From 8158a8bc01574fead7efac6e00301690b68e833d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CNaeel=E2=80=9D?= Date: Tue, 14 Jul 2026 21:54:23 +0400 Subject: [PATCH] =?UTF-8?q?docs:=20=D0=BF=D0=BE=D0=BB=D0=BD=D0=B0=D1=8F=20?= =?UTF-8?q?=D0=BA=D0=BE=D0=BD=D1=84=D0=B8=D0=B3=D1=83=D1=80=D0=B0=D1=86?= =?UTF-8?q?=D0=B8=D1=8F=20=D0=BA=D0=BB=D0=B0=D1=81=D1=82=D0=B5=D1=80=D0=B0?= =?UTF-8?q?=20=E2=80=94=20MTU=20+=20keep-alive=20+=20HTTP/2=20+=20RST=20fi?= =?UTF-8?q?x?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- PROBLEM-AND-SOLUTION.md | 81 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 73 insertions(+), 8 deletions(-) diff --git a/PROBLEM-AND-SOLUTION.md b/PROBLEM-AND-SOLUTION.md index 3aff86e..f265199 100644 --- a/PROBLEM-AND-SOLUTION.md +++ b/PROBLEM-AND-SOLUTION.md @@ -70,14 +70,79 @@ VIP: 185.247.187.151 → kube-vip анонсирует на все 4 но --- +## Баг #2: ERR_CONNECTION_RESET в браузере (2026-07-14) + +### Симптом + +После фикса MTU — curl с ВМ работал, но браузер (Chrome/Electron) при загрузке 63KB docx получал `ERR_CONNECTION_RESET`. + +### Причина + +Два механизма одновременно: + +1. **`keep-alive: 10`** — nginx закрывал idle-соединения через 10с. Браузер не замечал FIN (буферизация TCP в ОС), отправлял POST в уже закрытый сокет → RST. + +2. **kube-vip ARP flapping** — при смене ARP-лидера трафик уходил на другую ноду без conntrack-записи → RST. + +### Решение + +| # | Где | Что | Было | Стало | +|---|-----|-----|------|-------| +| 1 | Ingress ConfigMap | `keep-alive` | `10` | **`75`** | +| 2 | `index.html` (JS) | warmup GET при загрузке | — | `fetch('/health')` | + +### Результат тестов (v0.0.26) + +| Тест | Результат | +|------|-----------| +| 5× свежих страниц + POST 63KB | 4× OK, 1× ABORTED (Playwright) | +| UI: 2 файла + SSE + download | ✅ полный цикл, 18.5с | +| 3× POST через 10+ мин (kube-vip окно) | 3× OK:200 | +| 20× POST (батарея) | 0 ERR_CONNECTION_RESET | + +--- + ## Текущая конфигурация (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 | — | +### Ingress ConfigMap -Код v0.0.22: XHR-таймаут 30 с, cache-busting, обработка SSE `GeneratorExit`. +| Параметр | По умолчанию | Текущее | Причина | +|----------|-------------|---------|---------| +| `keep-alive` | 75 | **75** | Было 10 — рвало idle → RST | +| `use-http2` | true | **`"false"`** | HTTP/2 давал PROTOCOL_ERROR | +| `proxy-body-size` | 8m | **1024m** | Загрузка docx/pdf до 1 ГБ | +| `client-body-timeout` | 60 | **10** ⚠️ | Надо вернуть 60 | +| `client-header-timeout` | 60 | **10** ⚠️ | Надо вернуть 30 | +| `upstream-keepalive-connections` | 0 | **0** | Был 50, эксперимент | +| `error-log-level` | info | **debug** | Временно для диагностики | + +### Cilium + +| Параметр | По умолчанию | Текущее | Причина | +|----------|-------------|---------|---------| +| `mtu` | 1500 | **1400** | Geneve +50 = 1450 = underlay | + +### Приложение (drhider v0.0.26) + +| Файл | Изменение | +|------|-----------| +| `site/templates/index.html` | `fetch('/health')` при загрузке — прогрев upstream | +| `site/app.py` | `VERSION = "0.0.26"` | + +--- + +## Для DevOps — что должно быть в Штурвале + +```yaml +# Ingress ConfigMap +keep-alive: "75" # ⚠️ было 10 — СРОЧНО исправить +client-body-timeout: "60" # ⚠️ было 10 — СРОЧНО исправить +client-header-timeout: "30" # ⚠️ было 10 +use-http2: "true" # можно вернуть +proxy-body-size: "1024m" # под загрузку файлов +upstream-keepalive-connections: "0" +error-log-level: "info" # вернуть после диагностики + +# Cilium ConfigMap (kube-system) +mtu: "1400" # ⚠️ было 1500 — Geneve overhead +```