Files
drhider/PROBLEM-AND-SOLUTION.md
T
2026-07-14 19:19:12 +04:00

5.2 KiB
Raw Blame History

Проблема загрузки файлов: диагностика и решение

Дата: 2026-07-14


Суть проблемы

При передаче данных через HTTP POST из внешней сети на managed-сервисы кластера (Flask и другие) периодически возникала константная задержка 51 секунда. Проблема проявлялась на любом объёме данных — даже на 100 КБ. Внутри кластера (pod → ingress pod напрямую) передача работала мгновенно. Задержка возникала исключительно при прохождении трафика снаружи через VIP (kube-vip), который распределяет запросы по всем нодам кластера.


Причина

Несоответствие MTU: канал между серверами — 1450 байт, а каждый Geneve-туннель добавляет к пакету 50 байт. При дефолтном MTU пода в 1500 байт любой cross-node-переход через туннель создаёт пакет размером 1550 байт, который не помещается в канал и дропается. Ядро ждёт повторной передачи — отсюда и 51-секундная пауза.

В зависимости от того, на каких нодах окажутся поды, запрос проходит через 0, 1 или 2 Geneve-туннеля:

Путь Туннелей Размер пакета Проходит?
Клиент → нода с ingress → drhider на той же ноде 0 1500 б
Клиент → нода с ingress → drhider на другой ноде 1 1500 + 50 = 1550 б
Клиент → нода без ingress → ingress → drhider 2 1500 + 50 + 50 = 1600 б

Снижение MTU пода до 1400 байт устраняет проблему: 1400 + 50 = 1450, что точно вписывается в канал на каждом переходе.


Архитектура кластера

Кластер iot-naeel: 4 ноды (3 worker + 1 control-plane), Cilium с Geneve-энкапсуляцией, kube-vip.

Ноды:      6f74n  |  bhbvs  |  v8zq4  |  control-plane
Ingress:   2 пода (Штурвал, всегда на разных нодах)
Drhider:   1 под  (размещается на случайной worker-ноде)
VIP:       185.247.187.151 → kube-vip анонсирует на все 4 ноды через ARP

Маршрут запроса: браузер → VIP (случайная нода) → kube-proxy → ingress-под → kube-proxy → drhider-под. Каждый переход между нодами — Geneve-туннель (+50 байт).

Примеры возможных размещений:

Ситуация Drhider Ingress Туннелей ingress→drhider
A 6f74n 6f74n + bhbvs 50% без туннеля, 50% через
B bhbvs 6f74n + v8zq4 100% через туннель
C v8zq4 bhbvs + v8zq4 50% без туннеля, 50% через

Если клиент попадает на ноду без ingress-пода, kube-proxy добавляет ещё один Geneve-переход.


Тестирование (curl с ВМ, 30 запросов, 63 КБ)

Цель: подтвердить, что только MTU 1400 работает стабильно при любом размещении подов.

MTU пода Размещение drhider / ingress Результат
1400 bhbvs / bhbvs + v8zq4 30/30
1400 6f74n / 6f74n + bhbvs 30/30
1450 6f74n / 6f74n + bhbvs 30/30 (50% без туннеля — повезло)
1500 6f74n / 6f74n + bhbvs 30/30 (50% без туннеля — повезло)
1500 v8zq4 / v8zq4 + ctrl 23/30
1500 bhbvs / 6f74n + bhbvs 0/30

При MTU 1500 и drhider на bhbvs с ingress на 6f74n+bhbvs — все запросы идут через Geneve, результат 0/30.

Вывод: MTU 1500 работает только случайно (когда поды оказываются на одной ноде). MTU 1400 — единственно надёжное решение.


Текущая конфигурация (2026-07-14)

Параметр По умолчанию Текущее Причина изменения
Cilium mtu 1500 1400 1400 + 50 (Geneve) = 1450 = underlay
proxy-body-size (ingress) 8m 1024m Поддержка загрузки файлов до 1 ГБ
HTTP/2 включён включён
externalTrafficPolicy Cluster Cluster
Реплик ingress 2 2

Код v0.0.22: XHR-таймаут 30 с, cache-busting, обработка SSE GeneratorExit.