Назад | Перейти на главную страницу

CoreOS: tcpdump таинственным образом решает проблему с сетью (чрезмерное количество используемых сокетов)

Сегодня у меня для тебя есть загадка. Мы запускаем небольшой трехузловой кластер Elasticsearch на базе CoreOS (2023.5.0 / Linux 4.19.25-coreos) в Azure. Elasticsearch запускается внутри контейнера докеров в режиме сети хоста. После почти полного отсутствия технического обслуживания в течение более года мы наблюдаем, как машины входят в очень интересное состояние.

Обновить

Эта проблема была решена путем исправления драйвера в Ядро Linux. См. Ответ ниже.

Симптомы

По сути, сеть между затронутой машиной и двумя другими узлами умирает. Все они находятся в одной виртуальной сети и одной подсети и обычно могут связываться друг с другом. Затронутый узел по-прежнему доступен из других подсетей (я могу подключиться к нему по ssh) и из другой одноранговой виртуальной сети. У машины также есть (очень нестабильное) подключение к Интернету, но большинство запросов просто истекает.

Мы заметили, что на затронутом узле количество "используемых сокетов", сообщаемое /proc/net/sockstat очень высока (~ 4,5 КБ вместо ~ 300 на исправном узле). Мониторинг показывает, что это число быстро растет с момента, когда узел становится недоступным.

Самое интересное, что мы не можем определить источник этих используемых сокетов:

# cat /proc/net/sockstat
sockets: used 4566
TCP: inuse 2 orphan 0 tw 2 alloc 98 mem 4
UDP: inuse 1 mem 0
UDPLITE: inuse 0
RAW: inuse 0
FRAG: inuse 0 memory 0

# cat /proc/net/sockstat6
TCP6: inuse 98
UDP6: inuse 1
UDPLITE6: inuse 0
RAW6: inuse 1
FRAG6: inuse 0 memory 0

В остальном машина выглядит нормально. Нет никаких запущенных подозрительных процессов, загрузка ЦП минимальна, а доступной памяти достаточно.

Проверка связи "недостижимой" виртуальной машины в той же подсети приводит к нескольким EAGAIN ответы на recvmsg а затем переходят к получению ENOBUFS назад от sendmsg. вывод strace ping здесь

Я собрал некоторые дополнительные результаты (до того, как были внесены какие-либо изменения в систему) и разместил их в следующем виде: https://gist.github.com/privatwolke/e7e2e7eb0272787765f5d3726f37107c

Анализ

Мы попытались отключить все, что мы могли придумать на сервере, при этом в первую очередь заподозрили elasticsearch. Но закрытие контейнера elasticsearch не освобождает используемые сокеты. То же самое для всех процессов, связанных с CoreOS (update-engine, locksmithd, ...), или даже для всей среды выполнения Docker или специфичных для Azure вещей. Казалось, ничего не помогает.

Но теперь все становится еще более странным: мы пытались бежать tcpdump на машине, чтобы посмотреть, что происходит. И вот: проблема разрешилась сама собой, связь восстановилась. Наша теория заключалась в том, что tcpdump выполняет своего рода системный вызов, который разрешает эту проблему. Мы запустили tcpdump с gdb и установили точки останова для всех системных вызовов. Пройдя через множество точек останова, мы наконец обнаружили, что процесс установки беспорядочного режима на захватывающем сокете (в частности, эта строка в libpcap) - это то, что сбрасывает счетчик использованных сокетов и возвращает нас в нормальное состояние.

Дополнительные выводы

Мы связывались с Azure, которые так же озадачены этим, как и мы. Я понимаю, что скорее всего это не проблема, а всего лишь симптом. Но это единственная осязаемая вещь, которую я пока нашел. Я надеюсь, что, поняв симптом, я смогу приблизиться к первопричине. Сетевые интерфейсы в Azure работают с этот сетевой драйвер.

Может быть виноват CoreOS / Kernel?

С точки зрения временной шкалы, проблемы начались 11 марта 2019 года, в день, когда CoreOS автоматически обновился до последней версии. Согласно примечаниям к выпуску, это обновление содержало обновление ядра от С 4.15.23 по 4.19.25. Я все еще просматриваю журналы изменений, чтобы увидеть, может ли там что-нибудь быть проблемой. Пока я только обнаружил, что сетевой драйвер Hyperv имеет получил довольно много обновлений за последние месяцы, не все из которых, похоже, являются частью 4.19.25. Набор патчей, который CoreOS применил к 4.19.25, не так уж и впечатляет, но патч, который вводит поддельный модуль nf_conntrack_ipv4, является новым.

Обновить: Возможный связанный входящий патч ядра?

Помогите!

Пока у нас есть следующие вопросы:

Связанная ошибка CoreOS: https://github.com/coreos/bugs/issues/2572

Прежде всего, спасибо за очень хорошо написанный вопрос!

Поскольку уровень детализации, который вы описали, очень высок, и вы уже находитесь на уровне GDB, я предполагаю, что мой ответ не будет вам очень полезен. В любом случае, вот попытка:

  • Предположительно вы уже пробовали что-то вроде ss -ae и lsof -n?
  • Делает dmesg вернуть что-нибудь интересное, когда это произойдет?
  • Вы используете iptables на сервере?
  • Если вы установили неразборчивый режим другим способом, кроме tcpdump (скажем, ip link set [interface] promisc on), это тоже решает проблему?
  • Проверяли ли вы какие-либо подозрительные процессы, файлы или другую странную активность? Просто подумать, что, может быть, в тени скрывается какой-то незваный неприятный процесс, который замолкает всякий раз, когда установлен беспорядочный режим?
  • Если оставить tcpdump работающим в фоновом режиме, эта проблема вернется?

Надеюсь, это поможет.

Это было вызвано ошибкой в ​​драйвере hv_netsvc в ядре Linux. Мы могли решить эту проблему с помощью разработчика Microsoft, и нам удалось применить исправление вверх по течению.

Я процитирую сообщение о фиксации здесь, поскольку оно довольно хорошо резюмирует проблему:

Когда кольцевой буфер почти заполнен из-за сообщений о завершении приема, пакет TX может достичь «нижнего водяного знака» и вызвать остановку очереди. Если завершение передачи наступает раньше, чем остановка очереди, пробуждение может быть пропущено.

Этот патч перемещает проверку последнего ожидающего пакета, чтобы охватить как EAGAIN, так и случаи успеха, поэтому при необходимости очередь будет надежно активирована.

Для справки в будущем, фиксация, исправляющая это, https://github.com/torvalds/linux/commit/6d9cfab853ca60b2f77b5e4c40443216988cba1f.