Files
drhider/History/2026-07-15-rst-root-cause.md
T

170 lines
6.6 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.
# DrHider — итоговая диагностика ERR_CONNECTION_RESET
**Дата:** 2026-07-15
**Версия:** v0.0.29
---
## Хронология
| Дата | Событие |
|------|---------|
| 2026-07-11 | Исходный деплой |
| 2026-07-14 (день) | MTU fix (Cilium 1400) — решило 51с задержку |
| 2026-07-14 (вечер) | RST диагностика: keep-alive 75 + JS warmup — частично |
| 2026-07-15 (11:53) | Helm ревизия 9 — сброс ConfigMap на дефолты (keep-alive:10) |
| 2026-07-15 | podAffinity `required` на drhider (ручной kubectl edit) |
| 2026-07-15 (16:00) | Полная диагностика: hostPort vs cloud LB |
---
## Две независимые проблемы
### Проблема #1: MTU (решена 2026-07-14)
**Симптом:** 51с задержка при POST любого размера через внешний VIP.
**Причина:** Geneve +50, underlay 1450, дефолт 1500 → фрагментация/дроп.
**Решение:** Cilium `mtu: 1400`.
### Проблема #2: ERR_CONNECTION_RESET (хост порт, решена 2026-07-15)
**Симптом:** Браузер получает TCP RST при POST 63KB через 5-10 мин после рестарта ingress.
**Ранее считалось:** keep-alive 10с или kube-vip conntrack.
**Реальная причина:** Штурвал балансирует трафик на **все 4 ноды**, но ingress стоит `replicas: 2` с **hostPort** — порт 80/443 открыт только на 2 нодах.
```
Browser → cloud LB → любая из 4 нод
├── нода с ingress-подом → hostPort 80 → nginx → ✅
└── нода БЕЗ ingress-пода → порт 80 не слушается → RST ❌
```
**50% запросов попадает на пустую ноду → RST.**
---
## Подтверждающие данные
### Helm ревизии (дамп)
| Ревизия | Время | replicaCount | Другие изменения |
|---------|-------|-------------|------------------|
| 1 (деплой) | 2026-07-11 | 2 | — |
| 8 | 2026-07-15 02:00 | **2** | — |
| 9 | 2026-07-15 11:53 | **2** | — |
Helm **не менял** replicaCount. Всегда 2. Но ConfigMap сбрасывал на дефолты (keep-alive: 10, proxy-body-size: 8m и т.д.).
### Ingress ConfigMap (последствия Helm upgrade)
```yaml
# Было (ручные правки 2026-07-14) → Стало (после ревизии 9)
keep-alive: "75" → "10" # вернулось на дефолт Штурвала
proxy-body-size: "1024m" → "8m" # тоже сброшено
error-log-level: debug → info # сброшено
upstream-keepalive-connections: "0" → сохранилось
```
### kube-vip svc_election — мёртв
```yaml
# Lease ingress/kubevip-shturval-ingress-controller-controller
holderIdentity: "" # пусто — никто не держит
leaseDurationSeconds: 1 # аномально короткий (норма 15-30)
renewTime: 2026-07-11T14:55:28Z # 4 дня назад не обновлялся
leaseTransitions: 17 # но было 17 переходов
```
svc_election никогда не работал. VIP назначен через `ipMode: VIP` в статусе сервиса, работает на уровне облака (BGP/маршрутизация).
### hostPort
```yaml
# В шаблоне пода ingress (Helm template)
hostPort: 80
hostPort: 443
```
Включён в ревизиях 8 и 9. hostPort = порт слушается ТОЛЬКО на нодах где стоит под.
### podAffinity на drhider — временный костыль
```json
{
"podAffinity": {
"requiredDuringSchedulingIgnoredDuringExecution": [{
"labelSelector": {"matchLabels": {"app.kubernetes.io/name": "shturval-ingress-controller"}},
"namespaceSelector": {"matchLabels": {"name": "ingress"}},
"topologyKey": "kubernetes.io/hostname"
}]
}
}
```
Добавлен через `kubectl edit`, НЕ через Helm. Привязывает drhider к ноде с ingress-подом. Это НЕ лечит RST (RST на уровне VIP→нода, не на уровне нода→drhider). При следующем `helm upgrade` — исчезнет.
### Kube-vip DaemonSet — не участвует
```yaml
vip_arp: true # ARP включён
vip_leaderelection: false # нет CP election
svc_election: true # должен быть — но lease мёртв
```
Даемоны не логгируют VIP `185.247.187.151`. Трафик распределяет облако, не kube-vip.
---
## Решение
**Единственное полное решение:** ingress-под на каждой ноде куда приходит трафик.
### Вариант 1 (рекомендуемый): увеличить replicas
```yaml
# Helm values
shturval-ingress-controller:
replicaCount: 4
```
Или выяснить у DevOps сколько нод в LB-пуле Штурвала и поставить `replicaCount = число нод`.
### Вариант 2 (если балансировка на все worker'ы): DaemonSet
```yaml
# Helm values
shturval-ingress-controller:
kind: DaemonSet
```
---
## Что делать сейчас (ручной воркараунд)
### 1. Починить ConfigMap (срочно)
```bash
kubectl patch configmap -n ingress shturval-ingress-controller-controller --type merge \
-p '{"data":{"keep-alive":"75","proxy-body-size":"1024m","client-body-timeout":"60","client-header-timeout":"30"}}'
```
### 2. Масштабировать ingress (временный фикс)
```bash
kubectl scale deploy -n ingress shturval-ingress-controller-controller --replicas=4
```
Поды раскидаются по всем 4 нодам → hostPort на всех → 0% RST.
⚠️ **Предупреждение:** после следующего `helm upgrade`:
- ConfigMap сбросится (нужно править Helm values)
- replicas вернётся на 2
- podAffinity на drhider исчезнет
---
## Вопросы к DevOps
1. **Сколько нод в LB-пуле Штурвала?** (на какие ноды облако направляет трафик ingress?)
2. **Можно ли увеличить `replicaCount` до числа нод?**
3. **Как правильно изменить Helm values для ingress?** (чтобы ConfigMap не сбрасывался при upgrade)