Я сьогодні для вас загадка. Ми запускаємо невеликий, тривузловий кластер 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