CoreOS: tcpdump загадково вирішує проблему з мережею (надмірна кількість використаних сокетів)


14

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

Оновлення

Цю проблему було вирішено виправленням драйвера ядра Linux . Дивіться відповідь нижче.

Симптоми

В основному, мережа між ураженою машиною та іншими двома вузлами гине. Усі в одній віртуальній мережі та в одній підмережі і можуть звичайно спілкуватися з іншими. До пошкодженого вузла все ще можна дістатися з інших підмереж (я можу в нього запуститись) та з іншої виглядаючої віртуальної мережі. Машина також має (дуже плямке) підключення до Інтернету, але більшість запитів просто вичерпується.

Ми помітили, що на ураженому вузлі кількість "використаних розеток" /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

Крім цього машина здається прекрасною. Жодних підозрілих процесів не працює, використання процесора мінімальне, і є достатня кількість наявної пам'яті.

Пінінг "недоступного" VM в тій самій підмережі призводить до декількох EAGAINвідповідей recvmsgта переходу до ENOBUFSповернення з sendmsg. тут виводиться страйк-пінг

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

Аналіз

Ми намагалися вимкнути все, що можна придумати на сервері, першим підозрюваним є еластичний пошук. Але відключення еластичного контейнера не звільняє використані розетки. Те ж саме для всіх процесів, пов'язаних з CoreOS (оновлення-двигун, слюсар, ...) або навіть усього часу виконання Docker або специфічних для Azure матеріалів. Начебто нічого не допомогло.

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

Додаткові висновки

  • Ми переконалися, що робота tcpdumpз -p/--no-promiscuous-modeпрапором не очищає лічильник використаних розеток і повертає апарат у придатний стан.
  • При запуску ifconfig eth0 txqueuelen 1001скидає лічильник використовуваних сокетів, але з'єднання не відновлюється.
  • Встановлення режиму розмитнення вручну за допомогою ip link set eth0 promisc onтакож не відновлює з'єднання.
    • net.ipv4.xfrm4_gc_thresh встановлено на 32768, і збільшення його трохи не вирішує проблему.

використовувані розетки

Ми контактували з Azure, які так само збентежені, як і ми. Я розумію, що це, мабуть, не проблема, а лише симптом. Але це єдина відчутна річ, яку я знайшов поки що. Я сподіваюся, що, розуміючи симптом, я можу наблизитися до першопричини. Мережеві інтерфейси на Azure запускаються з цим мережевим драйвером .

Можливо, винна CoreOS / Kernel?

З точки зору часової шкали, проблеми почалися в 2019-03-11, тому день CoreOS автоматично оновився до останньої версії. Відповідно до приміток до випуску , це оновлення містило оновлення ядра з 4.15.23 до 4.19.25 . Я все ще переживаю журнали змін, щоб побачити, чи може щось там виникнути. Поки я лише виявив, що за останні місяці гіпервертер мережевого драйвера отримав досить багато оновлень , не всі з яких є частиною 4.19.25. Патчсет, який CoreOS застосував до 4.19.25, не такий вражаючий , але патч, який представляє підроблений модуль nf_conntrack_ipv4, новий.

Оновлення: Можливий пов'язаний патч вхідного ядра?

Довідка!

Поки що у нас є такі питання:

  • Що може призвести до того, що цей показник "використаних розеток" зростає? Я прочитав джерела ядра для цієї метрики, і, здається, це просто лічильник, не маючи посилання на те, якими саме є розетки або що їх створило.

  • Чому рівне число становить приблизно 4,5 к? Яка межа спричиняла б це?

  • Чи щось суттєво змінилося між ядром 4.14.96 та 4.19.25?

  • Чому setsockopt()виклик у libpcap скидає стан?

Пов'язана помилка CoreOS: https://github.com/coreos/bugs/isissue/2572


Відкриті розетки є наслідком проблеми, а не кореневою проблемою IMHO. Я мав цю поведінку в системі Linux з пристроями macvlan (з власними Mac-адресами) на мостовому пристрої. Встановлення мосту в перспективу змусило пристрої macvlan працювати. Я не знаю коріосу чи лазуриту. Проблема полягає в тому, що нижній шар не знає про адреси mac на верхніх рівнях.
AndreasM

Дякую за Ваш коментар! Я розумію, що велика кількість використовуваних розеток не є першопричиною, я просто чіпляюся за одну відчутну річ, яку я можу визначити як ненормальну в машині.
Стефан Кляйн

Привіт, Стефане. Якісь новини? повідомте, будь ласка, повідомте 1) чи включена WOL? 2) чи вирішує sysctl -w net.ipv4.route.flush = 1? 3) що таке кеш-арп при не працюючому стані? в робочому стані?
Массімо

Відповіді:


4

Перш за все, дякую за дуже добре написане запитання!

Оскільки рівень деталізації, який ви описали, дуже високий, і ви вже на рівні gdb, я вважаю, що моя відповідь вам не принесе користі. У будь-якому випадку, ось що:

  • Імовірно, ви вже пробували щось подібне ss -aeі lsof -n?
  • Чи dmesgповертається щось цікаве, коли це відбувається?
  • Чи використовуєте iptables на сервері?
  • Якщо ви встановите режим безладу, використовуючи інший спосіб, ніж tcpdump (скажімо, ip link set [interface] promisc on), чи це також виправить проблему?
  • Ви перевіряли наявність підозрілих процесів, файлів чи інших дивних дій? Тільки думаючи, що, можливо, якийсь непроханий неприємний процес ховається у тіні, ховаючись, і замовчує, коли встановлюється розбещений режим?
  • Якщо ви залишите tcpdump запущений фон, повернеться ця проблема?

Я сподіваюся, що це допомагає.


1
Дякую за вашу відповідь! Я дійсно зібрав результат деяких команд, на які ви посилаєтесь. Зараз вони також пов'язані у запитанні ( gist.github.com/privatwolke/e7e2e7eb0272787765f5d3726f37107c ). Дивна річ у тому, що отримують набагато менше розеток, про які повідомляється ss, lsofі netstatніж від "розеток, які використовуються" в /proc/net/sockstat. Тільки загальна кількість (яка, здається, щойно прочитана з цього файлу), однакова. iptablesзапускається, але не має спеціальних правил (див. суть), я не намагався самостійно встановлювати режим розмитості або безперервно запускати tcpdump. Зробимо це наступного разу.
Стефан Кляйн

Я додав вихід ss -aepiдо своєї вихідної колекції: gist.github.com/privatwolke/… - На жаль, dmesg не повертає абсолютно нічого, коли це відбувається. Фактично, останній запис перед інцидентом - 5 днів.
Стефан Кляйн


Я перевірив, що ip link set eth0 promisc onпоодинці не повертається машина до зручного стану.
Стефан Кляйн

Здрастуйте, чи переглядали ви ще це питання на цьому веб-сайті? serverfault.com/questions/614453/… Мабуть, це означає, що ви, можливо, вичерпуєте кеш xfrm4 dest. Ви можете збільшити його за допомогою цього параметра ядра: xfrm4_gc_thresh - INTEGER The threshold at which we will start garbage collecting for IPv4 destination cache entries. At twice this value the system will refuse new allocations. Наскільки я можу сказати, він пов'язаний з IPsec, який, здається, не працює і тут.
Педро Перес

0

Це було викликано помилкою в драйвері hv_netsvc в ядрі Linux. Ми могли вирішити це за допомогою розробника Microsoft, і нам вдалося застосувати виправлення вище за течією.

Я цитую тут повідомлення про фіксацію, оскільки воно досить добре підсумовує проблему:

Коли буфер дзвінка майже заповнений через повідомлення про завершення RX, пакет TX може досягти "низького водяного знака" і призвести до зупинки черги. Якщо завершення TX надійшло раніше, ніж зупинка черги, пробудження може бути пропущено.

Цей патч переміщує чек останнього пакета, що очікує, щоб охопити як EAGAIN, так і випадки успіху, тому черга буде надійно прокинута при необхідності.

Для подальшої посилання комісія, яка це виправляє, https://github.com/torvalds/linux/commit/6d9cfab853ca60b2f77b5e4c40443216988cba1f .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.