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

6.6 KiB
Raw Blame History

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)

# Было (ручные правки 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 — мёртв

# 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

# В шаблоне пода ingress (Helm template)
hostPort: 80
hostPort: 443

Включён в ревизиях 8 и 9. hostPort = порт слушается ТОЛЬКО на нодах где стоит под.

podAffinity на drhider — временный костыль

{
  "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 — не участвует

vip_arp: true          # ARP включён
vip_leaderelection: false  # нет CP election
svc_election: true     # должен быть — но lease мёртв

Даемоны не логгируют VIP 185.247.187.151. Трафик распределяет облако, не kube-vip.


Решение

Единственное полное решение: ingress-под на каждой ноде куда приходит трафик.

Вариант 1 (рекомендуемый): увеличить replicas

# Helm values
shturval-ingress-controller:
  replicaCount: 4

Или выяснить у DevOps сколько нод в LB-пуле Штурвала и поставить replicaCount = число нод.

Вариант 2 (если балансировка на все worker'ы): DaemonSet

# Helm values
shturval-ingress-controller:
  kind: DaemonSet

Что делать сейчас (ручной воркараунд)

1. Починить ConfigMap (срочно)

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 (временный фикс)

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)