docs: исправлены ошибки (TCP backoff, DSR, ping) + ответ Опуса
Deploy drhider / validate (push) Waiting to run

This commit is contained in:
2026-07-13 21:45:44 +04:00
parent 5e4418f648
commit cd22fd62a6
2 changed files with 38 additions and 10 deletions
@@ -0,0 +1,35 @@
# Opus: проверка PROBLEM-AND-SOLUTION.md на ошибки
**Дата:** 2026-07-13
---
## Найденные ошибки
### 1. TCP backoff — неправильные числа
**Было:** `1с → 3с → 7с → 15с → 25с = 51с` — выдумано.
**Правильно:** начальный RTO = 200ms, удвоение:
```
0.2с → 0.4с → 0.8с → 1.6с → 3.2с → 6.4с → 12.8с → 25.6с = 51с
```
8 ретрансмитов от 200ms = ровно 51 секунда (Linux kernel default).
### 2. DSR — неверное объяснение причины stall
**Было:** «двойной инкапсуляции return-трафика (главная причина stall)».
**Правильно:** stall на **входящем** трафике (клиент → pod), а не на return. DSR оптимизирует обратный путь, но не решает проблему inbound MTU black-hole.
### 3. Ping измеряет pod MTU, не underlay
Утверждение что `ping -M do` доказывает underlay = 1450 — неточно. Ping из пода измеряет MTU пода (1450 = 1500 50 Cilium). Физический underlay = 1450 подтверждён эмпирически (фикс сработал), а не прямым замером.
## Что верно
- Geneve overhead 50 байт: outer IP(20) + UDP(8) + Geneve(8) + inner Eth(14) = 50 ✓
- `mtu: 1450` → pod MTU = 1400 ✓
- `rollout restart ds/cilium` обязателен ✓
- iptables может не работать с eBPF dataplane ✓
- Корень проблемы и решение верны ✓
+3 -10
View File
@@ -41,7 +41,7 @@ flowchart LR
- Реальный канал = **1450 байт** → пакет **1500 не влазит**
- Роутер пытается отправить ICMP «fragmentation needed», но ICMP заблокирован
- Отправитель не знает что пакет не дошёл, ждёт подтверждения
- TCP включает exponential backoff: **1с → 3с7с → 15с → 25с = 51 секунда**
- TCP включает exponential backoff от начального RTO 200ms: **0.2с → 0.4с → 0.8с → 1.6с → 3.2с6.4с → 12.8с → 25.6с = 51 секунда**
- Через 51 секунду соединение разрывается → `ERR_TIMED_OUT`
### Почему не всегда
@@ -86,14 +86,7 @@ kubectl patch svc -n ingress shturval-ingress-controller-controller \
### Почему 1450
Замер выполнен 2026-07-13:
```
ping -M do -s 1472 → Message too large (1500 не проходит)
ping -M do -s 1422 → ok (1450 проходит)
```
Underlay MTU = 1450 → Geneve-туннель = 1400 → поды = 1400.
Фактический underlay MTU определён через `ping -M do` с временного пода: пакет с флагом DF размером 1500 не проходит, 1450 проходит. Строго говоря, ping измеряет pod MTU (а не underlay напрямую), но эмпирическое подтверждение получено: фикс `mtu: 1450` устранил stall.
### Почему это безопасно
@@ -158,7 +151,7 @@ tcpdump -ni any 'tcp[tcpflags] & tcp-syn != 0' -vv | grep mss
### Более грамотная альтернатива на будущее
Cilium **DSR + `kubeProxyReplacement`** убирает cross-node SNAT на обратном пути целиком — двойной инкапсуляции return-трафика (главная причина stall) просто не возникает. Но это меняет всю сетевую конфигурацию, для быстрого фикса — избыточно.
Cilium **DSR + `kubeProxyReplacement`** позволяет поду отвечать клиенту напрямую, минуя обратный путь через ingress и Geneve-туннель. Это устраняет ответную часть задержки, но не решает корневую проблему (stall возникает на входящем пути, клиент → pod). Для быстрого фикса — избыточно.
### Итоговый вердикт