docs: исправлен PROBLEM-AND-SOLUTION.md — mtu 1400 а не 1450, убран раздел Опуса, обновлены результаты
Deploy drhider / validate (push) Waiting to run
Deploy drhider / validate (push) Waiting to run
This commit is contained in:
+22
-105
@@ -67,15 +67,11 @@ flowchart LR
|
|||||||
Выставить корректный MTU в Cilium:
|
Выставить корректный MTU в Cilium:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
kubectl edit configmap -n kube-system cilium-config
|
kubectl patch configmap -n kube-system cilium-config --type merge -p '{"data":{"mtu":"1400"}}'
|
||||||
# mtu: 1450
|
|
||||||
|
|
||||||
kubectl rollout restart ds/cilium -n kube-system
|
kubectl rollout restart ds/cilium -n kube-system
|
||||||
kubectl rollout restart deploy -n ingress shturval-ingress-controller-controller
|
kubectl delete pods -n ingress --all --force --grace-period=0
|
||||||
|
kubectl delete pods -n <drhider-ns> --all --force --grace-period=0
|
||||||
# Вернуть Cluster
|
|
||||||
kubectl patch svc -n ingress shturval-ingress-controller-controller \
|
|
||||||
-p '{"spec":{"externalTrafficPolicy":"Cluster"}}'
|
|
||||||
```
|
```
|
||||||
|
|
||||||
После этого:
|
После этого:
|
||||||
@@ -84,114 +80,35 @@ kubectl patch svc -n ingress shturval-ingress-controller-controller \
|
|||||||
- `Local` не нужен
|
- `Local` не нужен
|
||||||
- Ручной scale не нужен
|
- Ручной scale не нужен
|
||||||
|
|
||||||
### Почему 1450
|
### Почему 1400
|
||||||
|
|
||||||
Физический интерфейс ноды (`eth0`) показывает MTU **1500** — стандартное значение, выставленное провайдером. Однако между физическими серверами провайдер добавляет собственную инкапсуляцию (VXLAN/GRE, ~50 байт overhead), поэтому реальный path MTU = **1450**.
|
Underlay между нодами — **1450** (измерен `ping -M do`).
|
||||||
|
В этой версии Cilium (`routing-mode: tunnel`, `tunnel-protocol: geneve`) значение `mtu` задаёт pod MTU напрямую. Geneve-заголовок (+50 байт) добавляется поверх.
|
||||||
|
|
||||||
```
|
```
|
||||||
Ваша VM Сеть провайдера Другая VM
|
Pod MTU 1400 → пакет 1400 + Geneve 50 = 1450 = underlay 1450 → проходит
|
||||||
eth0: 1500 ──── [VXLAN/GRE +50 overhead] ──── eth0: 1500
|
Pod MTU 1450 → пакет 1450 + Geneve 50 = 1500 > underlay 1450 → дроп
|
||||||
реальный path MTU = 1450
|
|
||||||
```
|
```
|
||||||
|
|
||||||
| Параметр | Значение | Почему |
|
| Параметр | Значение |
|
||||||
|---------|----------|--------|
|
|---------|----------|
|
||||||
| `eth0` (видит VM) | 1500 | Провайдер выставил интерфейс |
|
| Underlay между нодами | 1450 |
|
||||||
| Реальный path MTU | **1450** | Провайдер добавляет инкапсуляцию |
|
| `cilium-config mtu:` | **1400** |
|
||||||
| `cilium-config mtu:` | **1450** | Сообщить Cilium реальный path |
|
| Pod MTU | 1400 |
|
||||||
| Pod/tunnel MTU | 1400 | Cilium вычитает 50 на Geneve |
|
| Пакет через Geneve | 1400 + 50 = 1450 |
|
||||||
|
|
||||||
Подтверждено: фикс устранил stall, загрузка файлов идёт без задержки.
|
> В некоторых версиях Cilium `mtu` означает underlay (Cilium сам вычитает 50). В нашей — задаёт pod MTU напрямую. Проверено 2026-07-14: `mtu: 1450` → pod 1450 (не работает через Geneve), `mtu: 1400` → pod 1400 (работает).
|
||||||
|
|
||||||
### Почему это безопасно
|
|
||||||
|
|
||||||
- Понижение MTU консервативно: меньше пакет → меньше проблем
|
|
||||||
- Влияет на весь кластер одинаково (не ломает отдельные сервисы)
|
|
||||||
- Стандартная практика для туннельных CNI (Geneve, VXLAN, GRE)
|
|
||||||
- Не трогает логику Штурвала
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Полный анализ Опуса 4.8
|
## Результаты (кластер `iot-naeel`, 2026-07-14)
|
||||||
|
|
||||||
### Главное уточнение
|
| Метрика | До (MTU 1450) | После (MTU 1400 + Connection: close) |
|
||||||
|
|---------|---------------|--------------------------------------|
|
||||||
`mtu` в cilium-config — это MTU **underlay-сети** (физической сети между нодами), а НЕ туннеля. Cilium сам вычитает 50 байт на Geneve:
|
| Upload из браузера | ERR_CONNECTION_RESET | <0.2s |
|
||||||
|
| 5 файлов подряд | первый сбой | все <0.1s |
|
||||||
```
|
| F5 при обработке | мёртвые соединения | чисто |
|
||||||
mtu: 1450 → tunnel/pod MTU = 1450 − 50 = 1400
|
| Edge 7× подряд | на 5-й сбой | стабильно |
|
||||||
```
|
|
||||||
|
|
||||||
По умолчанию Cilium автодетектит underlay 1500 → туннель 1450. Если stall всё равно происходит — значит реальный underlay < 1500. Поэтому нужно измерять, не гадать.
|
|
||||||
|
|
||||||
### Подводные камни
|
|
||||||
|
|
||||||
- **ConfigMap сам не применяется.** Нужен `kubectl rollout restart ds/cilium -n kube-system` — без этого агенты продолжат работать со старым MTU.
|
|
||||||
- **Существующие TCP-соединения не поменяют MSS** — эффект только на новые соединения после рестарта.
|
|
||||||
- **Нужен рестарт подов приложения** (ingress, drhider) — veth-интерфейс пода получает MTU при создании. Для транзитного (ingress) трафика обновления маршрутов ноды обычно достаточно на новых соединениях, но для чистоты — пересоздать.
|
|
||||||
- Пересоздавать туннели вручную не нужно — рестарт агента переинициализирует `cilium_geneve` device.
|
|
||||||
- **Установленный вручную `externalTrafficPolicy: Local`** надо вернуть на `Cluster` через `kubectl patch` (ставился не через Helm, сам не откатится).
|
|
||||||
|
|
||||||
### Риски для других сервисов
|
|
||||||
|
|
||||||
`mtu` — параметр всего кластера, влияет на ВСЕ поды и ВСЕ ноды. **Понижение MTU безопасно** (меньше = консервативнее). Максимум — небольшой рост числа пакетов / микроскопическая потеря throughput. Функционально ничего не ломает.
|
|
||||||
|
|
||||||
Риск в момент раскатки: `rollout restart ds/cilium` перезапускает агенты по нодам. eBPF-датаплейн переживает рестарт (трафик идёт), но возможны короткие блипы. Лучше делать в окно.
|
|
||||||
|
|
||||||
Настоящий риск — только если поставить **слишком высокий** MTU (проблема останется) или **слишком низкий без нужды** (лишний оверхед). Поэтому критически важен замер.
|
|
||||||
|
|
||||||
### iptables как альтернатива
|
|
||||||
|
|
||||||
**Не равноценен и с Cilium может не сработать.** Cilium с eBPF-датаплейном / kube-proxy replacement обходит netfilter `FORWARD` для трафика подов. Правило в `mangle/FORWARD` может просто не видеть нужные пакеты.
|
|
||||||
|
|
||||||
`--clamp-mss-to-pmtu` берёт MSS из PMTU исходящего маршрута. Если MTU маршрута неверен — клампинг будет неправильным. Надёжнее явный `--set-mss 1400`.
|
|
||||||
|
|
||||||
На какую ноду: kube-vip раздаёт VIP на **все 4 ноды** → правило нужно на всех (DaemonSet/node-level).
|
|
||||||
|
|
||||||
Вывод: iptables — костыль-fallback, который с Cilium может оказаться нерабочим. **Правильный путь — `cilium-config`**, потому что Cilium ставит `advmss` на маршрутах (тот же MSS clamping, но нативно в eBPF-датаплейне).
|
|
||||||
|
|
||||||
### Верификация после изменения
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Проверить что Cilium применил MTU
|
|
||||||
kubectl -n kube-system exec ds/cilium -- cilium-dbg status | grep -i mtu
|
|
||||||
ip link show | grep -E 'cilium|geneve' # MTU tunnel-девайса
|
|
||||||
ip route show | grep -E 'advmss|mtu' # advmss на cilium-маршрутах
|
|
||||||
|
|
||||||
# Проверить MSS в SYN-пакетах
|
|
||||||
tcpdump -ni any 'tcp[tcpflags] & tcp-syn != 0' -vv | grep mss
|
|
||||||
```
|
|
||||||
|
|
||||||
Функционально: файл >5 MB через drhider — без паузы 51с. F5 без ERR_TIMED_OUT.
|
|
||||||
|
|
||||||
### Более грамотная альтернатива на будущее
|
|
||||||
|
|
||||||
Cilium **DSR + `kubeProxyReplacement`** позволяет поду отвечать клиенту напрямую, минуя обратный путь через ingress и Geneve-туннель. Это устраняет ответную часть задержки, но не решает корневую проблему (stall возникает на входящем пути, клиент → pod). Для быстрого фикса — избыточно.
|
|
||||||
|
|
||||||
### Итоговый вердикт
|
|
||||||
|
|
||||||
Путь правильный (фикс корня, а не симптома). Конечное состояние `Cluster + корректный MTU + replicaCount: 2` — чистое и согласованное: убирает разом и ручной scale, и Local-костыль.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Результаты (тестовый кластер `iot-naeel`, 2026-07-13)
|
|
||||||
|
|
||||||
Изменение применено на личном кластере где отсутствуют активные production-сервисы.
|
|
||||||
|
|
||||||
**До:** `externalTrafficPolicy: Local`, 4 реплики ingress, `ERR_TIMED_OUT` при сбросе реплик, TCP-stall 51с.
|
|
||||||
|
|
||||||
**После:** `externalTrafficPolicy: Cluster`, 2 реплики ingress, MTU 1450.
|
|
||||||
|
|
||||||
| Метрика | До | После |
|
|
||||||
|---------|-----|-------|
|
|
||||||
| F5 (5 запросов) | 50% ERR_TIMED_OUT | 5/5 OK, <250ms |
|
|
||||||
| Upload 63 KB | пауза 51с | 0.2-0.3s |
|
|
||||||
| Upload 6×63 KB | нестабильно | все <0.25s |
|
|
||||||
| Process 6 файлов | ~90s (со stall) | 32.8s |
|
|
||||||
| Download ZIP | медленно | 0.23s |
|
|
||||||
| Download CSV | медленно | 0.12s |
|
|
||||||
|
|
||||||
Все костыли (`Local`, ручной scale) убраны. Кластер работает на заводских настройках Штурвала + одна цифра в конфиге Cilium.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user