# 2026-07-10 — ИТОГ РАССЛЕДОВАНИЯ: почему режется загрузка ## Методология Тестирование от внутреннего к внешнему — послойная изоляция каждого компонента. ## Результаты тестов | # | Тест | Маршрут | Размер | Результат | |---|------|---------|--------|-----------| | 1 | Python внутри пода → Flask | pod → localhost:5000 | 100KB base64 (136KB POST) | ✅ 102400 байт, 4ms | | 2 | Python внутри пода → Ingress HTTPS | pod → 10.105.13.158:443 | 136KB POST | ✅ 102400 байт, 2ms | | 3 | Python снаружи → Ingress | интернет → 185.247.187.151:443 | 136KB POST | ❌ **СЛУЧАЙНО** | | 4 | 10×100KB снаружи | интернет → 185.247.187.151:443 | 136KB POST | ~50% OK, ~50% RemoteDisconnected | ## Бинарный поиск предела (снаружи) | Размер POST | Результат | |-------------|-----------| | 1-48 KB | ✅ всегда | | 50 KB | ❌ | | 52 KB | ✅ | | 55-80 KB | ❌ | | 100 KB | ✅ (иногда!) | **Твёрдого предела НЕТ.** Сбои случайные. ## Исключённые причины | Компонент | Статус | Доказательство | |-----------|--------|----------------| | Flask dev-сервер | ✅ OK | Тест #1 | | nginx ingress | ✅ OK | Тест #2 | | ModSecurity (128KB NoFilesLimit) | ✅ OK | Тест #2, DetectionOnly | | Gunicorn field_size | ❌ не используется | Shturval запускает `python app.py` | ## Где проблема ``` Клиент (интернет) │ ▼ ??? Edge-инфраструктура хостера (NUBES LLC, AS212136) ??? │ ← здесь рвётся TCP-соединение для POST > ~48KB ▼ 185.247.187.151:443 (hostPort на ноде) │ ▼ nginx ingress pod ─── ModSecurity ─── pythonk8s pod (Flask) ✅ всё работает ``` IP в логах ingress: `192.168.255.x` — приватный IP хостинг-провайдера. На ноде порт 443 слушает kube-vip/hostPort напрямую (без proxy_protocol). Внутри кластера всё идеально. Снаружи — случайные обрывы. ## Аналогичный опыт (contracts) `/home/naeel/nubes/contracts/History/`: - `connection-reset-analysis.md`: curl 100KB → HTTP 000 случайно (5 тестов: 2 OK, 3 обрыв) - `sonnet-upload-from-scratch.md`: "64KB — жёсткий предел платформы" (43 версии) - `session-08-upload-saga.md`: чанки 50KB — только первый доходит ## Ложные правки (эта сессия) - Dockerfile `--limit-request-field_size 0` — бесполезно (Gunicorn не используется) - Версия 1.0.4 → 1.0.5 — задеплоено, но проблемы не решает (причина вне кода) ## Компоненты инфраструктуры (найдены) - Shturval v2.12.1 - kube-vip (DaemonSet) — VIP для LoadBalancer, IP 185.247.187.151 - nginx ingress через hostPort (порты 80/443 прямо на ноде) - ModSecurity OWASP CRS 4.10.0, SecRuleEngine DetectionOnly - `SecRequestBodyNoFilesLimit 131072` (128KB) — НЕ причина (внутри кластера работает) ## РЕШЕНИЕ Contracts на этой же ВМ работает потому, что использует **родной nginx** с `proxy_request_buffering off`: ```nginx # /etc/nginx/sites-enabled/nginx-contracts.conf location /upload { proxy_pass http://127.0.0.1:8766; client_max_body_size 100m; proxy_request_buffering off; # ← вот почему работает } ``` Для loadtest добавлена аннотация в k8s ingress: ``` nginx.ingress.kubernetes.io/proxy-request-buffering: "off" ``` Конфиг применился (подтверждено в `/etc/nginx/nginx.conf` внутри ingress pod): ``` proxy_request_buffering off; ``` ## Причина Edge-инфраструктура хостера (NUBES LLC) рвёт TCP-соединения при буферизации больших POST-тел. `proxy_request_buffering off` стримит тело напрямую в бэкенд — edge не рвёт.