У меня непростое поведение, которое я не могу объяснить. У меня запущена виртуальная машина Ubuntu 20.04
, docker
19.03.6and a
Rediscontainer. Hosted on a
Windows 2019` Машина Hyper-V.
Есть вторая виртуальная машина (та же сеть, но другой физический сервер) с W2k19 и redis-client
подключение к redis
пример.
Время от времени из-за неправильной конфигурации redis
перегружает машину Ubuntu, использует слишком много памяти и производит тысячи *connection timed out*
исключение в redis-client
.
Когда это происходит, все соединения между машинами перестают работать. Если я попытаюсь подключиться через ssh
с машины W2k19 на Ubuntu или используя telnet
с той же машины на любом порту я получаю *connection timed out*
.
Например, если что-то на машине Linux автоматически заблокировало IP-адрес машины w2k19. С любого другого компьютера я могу подключиться через ssh
, telnet
и так далее.
Ufw
выключенfail2ban
установленыiptables
настроен со всеми открытыми портамиНо мы все еще не можем подключиться. Мы воспроизвели поведение на другой машине, второй ВМ с W2k19
и то же самое redis-client
.
Мы выяснили, что для восстановления связи между этими машинами будет перезапуск ssh
на машине Ubuntu в сочетании с перезагрузкой W2k19
машина.
Только сингл sudo service sshd restart
недостаточно, и просто перезагрузка W2k19
машина маловата. Я не могу понять, что происходит, и мы не можем принять в качестве стандартной процедуры в этих случаях перезапуск ssh
обслуживание и перезагрузите машину.
Но так далеко мы не можем чтобы выяснить, какое правило / конфигурация блокирует соединения. Это как-то связано с ssh
сервис, вероятно, поскольку его перезапуск действительно способствует восстановлению соединений, но как?
И зачем перезапускать ssh
сервис (и перезагрузка W2k19
машина) фактически разблокирует соединение с redis
6379 порт?
!!! ОБНОВИТЬ !!! Я попробовал tcpdump на машине ubuntu и не увидел трафика от другой виртуальной машины. Я настроил сетевое зеркалирование для машины ubuntu и проанализировал трафик с помощью wirehark, трафика с другой виртуальной машины тоже. Я отключил брандмауэры везде (виртуальная машина ubuntu, клиентская виртуальная машина, хосты Hyper-v) во время анализа трафика.
Что-то блокирует трафик до того, как он достигнет виртуальной машины, но я не могу понять, что именно.
Время соединения истекло означает, что начальный TCP SYN не вызвал никакого ответа [в течение времени ожидания соединения]. Клиент не получил ни SYN / ACK, ни RST, ни ошибки ICMP - ничего.
Это может произойти по многим причинам. Давайте разберем их в общих чертах, по этапам рукопожатия TCP.
Неисправность 1: исходный SYN не был доставлен на сервер.
Неисправность 2: серверная машина получила SYN, но потребовалось слишком много времени, чтобы accept()
запрос на подключение.
Неисправность 3: ответ SYN / ACK не был доставлен на клиентский компьютер.
Неисправность 4: последний ACK и все его повторные отправки были потеряны. (Это может привести к другой ошибке, но я не уверен.)
Эта часть дает мне догадку:
... время от времени redis перегружает машину Ubuntu, используя слишком много памяти ...
Убийца Linux OOM - деликатная тема; если вы не настроите из него хрень - обычно он предпочитает просто повесить пользовательское пространство вместо того, чтобы что-либо убивать. (Не спрашивайте, почему; я все еще не знаю. Настроить это проще, чем понять основные причины, почему.)
Итак, позвольте мне предложить вам OOM тест: когда проблема воспроизводится, вы можете ping
серверная машина? Вы также можете ssh
внутрь? Вероятный результат: да для ping, нет для ssh - укажет на неисправность 2.
Это типично для OOM-машин: ядро все еще живо и счастливо и отвечает на эхо-запросы, как будто ничего не происходит. Но обратите внимание: в отличие от ping, для установления TCP требуется пользовательское пространство серверная программа (например, redis или sshd) для активного вызова accept()
о готовящемся открытии соединения. В состоянии OOM на это уходит много времени, так как программы ждут выполнения своих запросов на выделение памяти.
Результат теста OOM «Нет ping, no ssh» - означает, что это не неисправность 2; Я предполагаю, что какие-то мосты виртуализации пошли наперекосяк.
Запуск Redis в докере еще больше усложняет ситуацию. В Docker есть собственная логика учета памяти (см. --memory
и друзья). Это также должен поправить iptables
правила функционирования сети контейнеров.
Если это не помогает: опишите здесь более подробную информацию о настройке сети, включая виртуализированные сети. Я чувствую, что мне уже нужна диаграмма для правильного подсчета ваших виртуальных машин.