4.8 KiB
Варианты решения ingress replicas + TCP stall
Дата: 2026-07-13
Источники: Sonnet analysis, Opus analysis
Связано: KUBEVIP-EXTERNAL-TRAFFIC-POLICY.md
Ключевой вывод (оба согласны)
Проблемы две независимые, решать по отдельности:
- TCP stall 51с — PMTU Blackhole на Geneve-туннеле, а не свойство
Cluster-политики.Localлечит как побочный эффект (убирает cross-node). - Сброс реплик —
kubectl scaleобходит Helm, поэтому реконсиляция откатывает.
⚠️ Важно (Opus):
kubectl scaleвы обходите Helm, поэтому и сбрасывается. Любое итоговое решение должно быть в values чарта, а не черезkubectl.
Варианты
1. DaemonSet (рекомендуется)
Одно изменение в Helm values:
controller:
kind: DaemonSet
# replicaCount игнорируется
- ✅ Автоматически 1 под/ноду
- ✅ Helm не ломает
- ✅ Стандарт для bare-metal / kube-vip
- ✅ Не требует менять сетевую конфигурацию
2. Починить MTU (убрать stall в корне)
51с — это классический Path MTU Discovery Blackhole. Geneve: MTU 1500 → ~1450.
Диагностика:
ip link show | grep -E "cilium|genev"
iptables -t mangle -L FORWARD -n -v | grep TCPMSS
Исправление:
iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
Если stall устранён → можно вернуть externalTrafficPolicy: Cluster и replicaCount 2.
3. Cilium DSR (Direct Server Return)
Ответный трафик идёт напрямую от пода к клиенту, без cross-node SNAT.
# cilium-config (требует kube-proxy replacement = strict)
loadBalancer:
mode: dsr
kubeProxyReplacement: strict
- ❌ Долго, меняет всю сетевую конфигурацию
4. replicaCount: 4 + podAntiAffinity
Если Штурвал не даёт сменить kind на DaemonSet:
controller:
replicaCount: 4
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app.kubernetes.io/name: ingress-nginx
topologyKey: kubernetes.io/hostname
- ✅ Гарантирует 1 под/ноду
- ✅ Helm values зафиксированы, не сбрасывается
Рекомендуемый путь (Sonnet + Opus)
| Приоритет | Действие | Эффект |
|---|---|---|
| 🟢 Сразу | controller.kind: DaemonSet в Helm values |
Убирает костыль с репликами навсегда |
| 🟡 Параллельно | Диагностика MTU + MSS clamping | Устраняет stall в корне |
| 🔵 Потом | Если MTU починен — вернуть Cluster |
Можно уйти от Local и требования под/ноду |
Как передать девопсу (Opus)
Для чарта shturval-ingress-controller-2.12.1:
# Вариант A: DaemonSet
helm upgrade -n ingress shturval-ingress-controller <чарт> \
--set controller.kind=DaemonSet
# Вариант B: replicaCount + antiAffinity (если DaemonSet недоступен)
helm upgrade -n ingress shturval-ingress-controller <чарт> \
--set controller.replicaCount=4 \
--set controller.affinity.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[0].labelSelector.matchLabels.app\.kubernetes\.io/name=ingress-nginx \
--set controller.affinity.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[0].topologyKey=kubernetes.io/hostname
Либо через Штурвал UI — изменить replicaCount: 4 в настройках чарта.
Диагностика MTU (Opus)
# реальный MTU туннеля
ip link show | grep -E "cilium|genev"
# есть ли MSS clamping
iptables -t mangle -L FORWARD -n -v | grep MSS
Варианты фикса:
- MSS clamping:
iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu - Cilium DSR:
loadBalancer.mode: dsr+kubeProxyReplacement: strict - Выставить MTU в Cilium под физическую сеть (Geneve overhead ~50 байт)
Текущий статус
externalTrafficPolicy: Local — не сбрасывается.
replicas: 4 — ручной scale, периодически сбрасывается Helm на 2.