Files
drhider/PROBLEM-AND-SOLUTION.md
T

5.0 KiB
Raw Blame History

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

Дата: 2026-07-16
Версия приложения: v0.0.29
Кластер: iot-naeel (4 ноды, Cilium Geneve, kube-vip, Штурвал)


Проблема 1: 51-секундная задержка (MTU)

Суть

При передаче POST из внешней сети — пауза 51с на любом объёме данных. Внутри кластера — мгновенно.

Причина

Underlay MTU = 1450. Cilium Geneve добавляет 50 байт. Дефолтный MTU пода = 1500.
Cross-node пакет = 1500+50 = 1550 → фрагментация → дроп → ядро ждёт повторной передачи 51с.

Решение

cilium-configmtu: 1400. 1400+50 = 1450 = underlay.
Задокументировано 2026-07-13, применено 2026-07-14.


Проблема 2: ERR_CONNECTION_RESET после фикса MTU

Суть

curl с ВМ работает. Браузер — ERR_CONNECTION_RESET или ⏳ 100%.
После rollout restart ingress — работает 5-10 минут, потом снова RST.

Ложные следы (опровергнуты)

Гипотеза Почему неверна
kube-vip ARP flapping kube-vip.io/vipHost: control-plane — VIP жёстко на одной ноде
hostPort на 2 из 4 нод Трафик только на control-plane, не на все 4
upstream keepalive stale upstream-keepalive-connections: 0 не помог
conntrack ETPolicy Cluster не при чём — трафик на одну ноду
MTU Решено в проблеме 1
HTTP/2 ERR_HTTP2_PROTOCOL_ERROR → отключили → ERR_CONNECTION_RESET — симптом тот же

Истинная причина

keep-alive: 10 — Штурвал ставил nginx keep-alive: 10 (вместо дефолта 75).
Сценарий:

  1. Браузер грузит страницу — TCP открыт
  2. Пользователь выбирает файлы (>10с) — nginx закрывает idle соединение
  3. Браузер не замечает FIN (буферизация ОС)
  4. POST 63KB летит в закрытый сокет → TCP RST

Решение (применено в платформе Штурвала 2026-07-15)

Через ShturvalServiceConfig (не kubectl — ArgoCD откатывает):

controller:
  config:
    keep-alive: "75"
    proxy-body-size: "1024m"
    client-body-timeout: "60"
    client-header-timeout: "30"
  hostPort:
    enabled: true
  replicaCount: 2
  service:
    type: LoadBalancer

Также в коде — fetch('/health') при загрузке страницы (прогрев upstream).

Результаты тестов (v0.0.29, 2026-07-15)

Тест Результат
10× POST 63KB (свежие страницы) 10/10 OK:200
UI: 5 файлов + SSE + ZIP + CSV полный цикл
5× POST через 75с (keep-alive окно) 5/5 OK:200
5MB PDF через curl 200 OK, 0.62с
ИТОГО 25/25 успешно, 0 RST

Итоговая конфигурация кластера

Ingress (через платформу Штурвала, несбрасываемо ArgoCD)

Параметр Дефолт nginx Было (Штурвал) Сейчас
keep-alive 75 10 75
proxy-body-size 8m 8m 1024m
client-body-timeout 60 10 60
client-header-timeout 60 10 30
use-http2 true true false
upstream-keepalive-connections 0 50 0
error-log-level info info debug (вернуть info)

Cilium (через kubectl, не сбрасывается)

Параметр Дефолт Сейчас
mtu 1500 1400

Приложение (drhider v0.0.29)

# site/app.py
VERSION = "0.0.29"
app.config["MAX_CONTENT_LENGTH"] = 200 * 1024 * 1024  # 200 MB
// site/templates/index.html — warmup при загрузке
window.addEventListener('load', () => {
  sf = []; fi.value = ''; rr();
  fetch('/health').catch(() => {});  // прогрев upstream
});

Документация

Файл Что
docs/ARCHITECTURE.md Архитектура + требования к Flask
docs/MIGRATION-GUIDE.md Инструкция переноса UI на Flask
History/2026-07-14-browser-rst-debug.md Полная история диагностики RST
History/2026-07-15-rst-root-cause.md Финальный диагноз
History/2026-07-15-cluster-dump.md Дамп кластера
STATE-2026-07-15.md Состояние проекта на 2026-07-15