Files
IoT/doc/thinking/nubes-devops-report-2026-08-16.md
T

144 lines
9.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Отчёт для DevOps Nubes — сетевые проблемы платформы
**Кластер:** iot-naeel
**Дата:** 2026-08-16
**Статус:** предварительный, все факты подтверждены тестами и дампами.
Готовы предоставить скрипты воспроизведения и провести совместные тесты.
---
## Часть 1. Что не работает (наблюдения и доказательства)
### 1.1 Внешние WebSocket-соединения закрываются ~через 150 секунд
**Симптом.** WebSocket-соединения из внешних сетей (wss, TLS) закрываются
в районе 150 секунд после установления. Для клиентов это выглядит как
разрыв без видимой причины (close 1006/1005) с необходимостью
переподключения.
**Доказательства.**
- 5 из 5 внешних станций (разные сети) — разрыв ~150 с, стабильно.
- Чистый VPS (Vultr) — 1 из 1, тот же разрыв ~150 с.
- Внутри кластера (под → сервис) — 600 с без единого разрыва.
- Машина за тем же шлюзом, но вне платформы — 300 с чисто.
- Контрольные wss-соединения к внешним ресурсам (nginx, echo-серверы)
с тех же станций — чисто.
**Вывод.** Обрывает именно edge-шлюз платформы (или балансировщик перед
ним), по таймеру. Похоже на фиксированный лимит времени жизни
соединения (idle/lifetime timeout) на проксирующем слое.
**Влияние.** Любой долгоживущий протокол поверх WebSocket (например,
MQTT) вынужден переподключаться каждые ~150 с. Наши клиенты это
переживают (автопереподключение), но это лишний трафик и окна потерь.
### 1.2 Зависание внешних соединений ~на 51 секунду при объёмном трафике (MTU)
**Симптом.** Из внешней сети операции с телом/ответом крупнее ~1,4 КБ
периодически «зависают» ровно на ~51 секунду, после чего либо
завершаются, либо обрываются. Внутри кластера те же операции проходят
мгновенно.
**Доказательства (три независимых контура).**
- Контур A (HTTP-сервис за платформой): POST снаружи — пауза ~51 с на
любом объёме данных выше порога; изнутри — мгновенно. При
внешнемTrafficPolicy: Cluster большие файлы (>5 МБ) дают TCP-stall
ровно на 51 с.
- Контур B (очередь с AWS-совместимым API): тела >~1,4 КБ виснут ~51 с
(классическая экспонента TCP-ретрансмитов).
- Контур C (REST API): HTTP-ответы крупнее ~15 КБ приходят частично и
виснут (в тесте получено 15 672 байта — далее стоп); маленькие ответы
(до ~15 КБ) проходят стабильно.
**Диагностика (наша гипотеза, подтверждённая измерениями).**
- Underlay MTU = 1450.
- Оверлей (Cilium Geneve) добавляет ~50 байт инкапсуляции.
- MTU контейнеров остаётся дефолтным 1500.
- Кросс-нодовый пакет полного размера = 1500 + 50 = 1550 > 1450 →
фрагментация невозможна (DF) → пакет дропается → ядро ждёт
ретрансмиссии по экспоненте → суммарная пауза ~51 с.
- На внешнем пути наблюдается MSS 1448 при MTU 1400 — т.е. ICMP
«fragmentation needed» до клиентов, вероятно, не доходит (PMTUD
сломан на каком-то из хопов).
**Влияние.** Любой объёмный запрос/ответ снаружи рискует зависнуть на
~51 с; клиенты с таймаутами 30 с получают «таймаут», хотя сервис
ответил мгновенно.
### 1.3 Периодические таймауты внешних запросов на малых объёмах (~5,5%)
**Симптом.** Даже запросы размером ~512 байт снаружи в ~5,5% случаев не
получают ответ 30+ секунд; характерный паттерн — зависание на 31–33 с.
**Доказательства.**
- Внутри кластера: 24 977 запросов подряд — 0 сбоев (порт-форвард).
- Снаружи: периодические зависания подтверждены tcpdump-ом (запрос
уходит, ответ не возвращается в течение 30+ с).
- Маловероятно, что это наша прикладная логика: те же операции изнутри
кластера стабильны.
**Гипотеза.** Связь с пунктом 1.2 (потеря крупных сегментов при
переговорах TLS/подтверждениях) или лимиты conntrack/сессий на
балансировщике.
---
## Часть 2. Как это исправить (наши предложения)
### 2.1 К пункту 1.1 (wss ~150 с)
1. Найти слой, который закрывает соединения: проверить настройки
idle/lifetime timeout на edge-шлюзе и балансировщике перед кластером
(nginx: `proxy_read_timeout`, `proxy_send_timeout`; LB: idle timeout).
2. Для wss-трафика выставить таймауты ≥ 600 с (или «без таймаута»).
3. Включить WebSocket ping/pong на прокси-слое (keepalive-фреймы каждые
30–60 с), чтобы соединение не считалось простаивающим.
4. После изменения — прогнать наш контрольный тест (wss-клиент держит
соединение 10 минут; критерий — 0 разрывов).
### 2.2 К пункту 1.2 (MTU / 51 с)
Варианты, в порядке предпочтения:
1. **Включить MSS-clamping на внешнем пути** (на шлюзе/на узлах):
`iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN \
-j TCPMSS --clamp-mss-to-pmtu` (или фиксированный MSS под MTU
внешнего интерфейса). Это дешёвое и надёжное решение: клиент не будет
слать сегменты крупнее, чем проходит путь.
2. **Привести MTU контейнеров к underlay**: MTU подов 1450 50
(инкапсуляция) = 1400. Тогда кросс-нодовые пакеты перестанут
превышать underlay, и дропы исчезнут в принципе.
3. **Проверить, что ICMP «fragmentation needed» не режется** на всём
внешнем пути (firewall/LB) — восстановление PMTUD решит проблему
для больших ответов.
4. Отключить запрет фрагментации на edge для исходящих сегментов (менее
желательно).
Критерий приёмки: POST/GET с телами 1 КБ…1 МБ снаружи проходят без
пауз >2 с (наш тест: 100 запросов разных размеров, 0 зависаний).
### 2.3 К пункту 1.3 (таймауты малых тел)
1. Сначала применить 2.2 — вероятно, это тот же корень.
2. Если проблема останется: проверить лимиты conntrack на шлюзе
(`nf_conntrack_max`, `table-full` в логах) и пул/лимиты соединений
балансировщика.
3. Критерий: 10 000 запросов по 512 байт снаружи — 0 таймаутов.
---
## Что мы уже сделали со своей стороны (обходы)
- Клиенты переподключаются автоматически (переживают пункт 1.1).
- Внутренние взаимодействия ходят по внутренним DNS, минуя внешний
шлюз (таймауты 1.3 нас не блокируют).
- Чтение больших списков разбито на страницы небольшого размера
(обход пункта 1.2).
## Что нужно от вас
1. Подтверждение/опровержение по каждому пункту.
2. Если нужны воспроизведения — дайте окно и среду, прогоним тесты
совместно (скрипты готовы).
3. Оценка сроков по пунктам 2.1–2.3.