docs: MSS-CLAMPING-PLAN v2 — исправлено после валидации Opus (underlay MTU, замер, рестарт)
Deploy drhider / validate (push) Waiting to run
Deploy drhider / validate (push) Waiting to run
This commit is contained in:
+52
-27
@@ -1,7 +1,8 @@
|
||||
# Корневое решение: MSS clamping вместо externalTrafficPolicy: Local
|
||||
# Корневое решение: MSS clamping через Cilium
|
||||
|
||||
**Дата:** 2026-07-13
|
||||
**Статус:** План для девопса
|
||||
**Дата:** 2026-07-13 (обновлено после валидации Opus)
|
||||
**Статус:** План для девопса
|
||||
**Валидация:** [Opus response](../History/2026-07-13-opus-response-mss-clamping.md)
|
||||
|
||||
---
|
||||
|
||||
@@ -11,54 +12,78 @@
|
||||
|
||||
## Корень проблемы
|
||||
|
||||
Geneve-туннель добавляет ~50 байт к пакету → превышение MTU (1500) → ICMP Frag Needed блокируется → TCP stall 51 секунда при передаче больших файлов.
|
||||
Geneve-туннель добавляет ~50 байт → превышение underlay MTU → ICMP Frag Needed блокируется → TCP stall 51с.
|
||||
|
||||
## Решение: MSS clamping через Cilium
|
||||
## Решение
|
||||
|
||||
```yaml
|
||||
# ConfigMap cilium-config
|
||||
mtu: 1450
|
||||
Выставить корректный MTU в Cilium, чтобы пакеты с Geneve-заголовком всегда влазили.
|
||||
|
||||
**Важно:** `mtu` в cilium-config — это MTU **underlay-сети** (физической/VM-сети между нодами). Cilium сам вычитает 50 байт на Geneve:
|
||||
```
|
||||
mtu: X → туннель = X − 50 → поды = X − 50
|
||||
```
|
||||
|
||||
Cilium режет MSS (Maximum Segment Size) у TCP SYN-пакетов так, чтобы итоговый пакет с Geneve-заголовком всегда влазил в MTU.
|
||||
|
||||
**Эффект:** никаких stall, никаких cross-node проблем.
|
||||
|
||||
## Что сделать девопсу
|
||||
|
||||
### Шаг 1: MSS clamping
|
||||
### Шаг 0: Измерить реальный underlay MTU
|
||||
|
||||
```bash
|
||||
# С одной ноды на IP другой ноды (DF-бит, подбираем размер)
|
||||
ping -M do -s 1472 <ip_другой_ноды> # 1472+28=1500; если не проходит — уменьшать
|
||||
tracepath <ip_другой_ноды> # покажет pmtu на пути
|
||||
```
|
||||
|
||||
Если 1500 не проходит — уменьшать шагами по 50 (1450, 1400...) пока не пройдёт. Результат = значение для `mtu`.
|
||||
|
||||
### Шаг 1: Выставить MTU в Cilium
|
||||
|
||||
```bash
|
||||
kubectl edit configmap -n kube-system cilium-config
|
||||
# mtu: 1450
|
||||
# mtu: <измеренное значение>
|
||||
```
|
||||
|
||||
Или iptables (если Cilium не управляет MTU):
|
||||
### Шаг 2: Применить изменения
|
||||
|
||||
```bash
|
||||
iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
|
||||
# Перезапустить агенты Cilium (ConfigMap сам не применяется)
|
||||
kubectl rollout restart ds/cilium -n kube-system
|
||||
|
||||
# Пересоздать поды приложения (ingress, drhider — чтобы veth получили новый MTU)
|
||||
kubectl rollout restart deploy -n ingress shturval-ingress-controller-controller
|
||||
```
|
||||
|
||||
### Шаг 2: Вернуть Cluster policy
|
||||
### Шаг 3: Вернуть Cluster policy
|
||||
|
||||
```bash
|
||||
kubectl patch svc -n ingress shturval-ingress-controller-controller \
|
||||
-p '{"spec":{"externalTrafficPolicy":"Cluster"}}'
|
||||
```
|
||||
|
||||
### Шаг 3: Верификация
|
||||
### Шаг 4: Верификация
|
||||
|
||||
- Загрузить файл > 5 MB через drhider — должно быть без 51-сек паузы
|
||||
```bash
|
||||
# Проверить что Cilium применил MTU
|
||||
kubectl -n kube-system exec ds/cilium -- cilium-dbg status | grep -i mtu
|
||||
ip link show | grep -E 'cilium|geneve'
|
||||
|
||||
# Проверить MSS в SYN-пакетах
|
||||
tcpdump -ni any 'tcp[tcpflags] & tcp-syn != 0' -vv | grep mss
|
||||
```
|
||||
|
||||
Функционально:
|
||||
- Загрузить файл > 5 MB через drhider — без паузы 51с
|
||||
- F5 несколько раз — без ERR_TIMED_OUT
|
||||
- Проверить другие сервисы (Keycloak, etc.) — без регрессий
|
||||
- Проверить Keycloak и другие сервисы
|
||||
|
||||
## Почему это грамотно
|
||||
|
||||
- Стандартная практика для любого туннельного CNI
|
||||
- Решает корневую причину, не симптомы
|
||||
- Не трогает логику Штурвала
|
||||
- Не требует DaemonSet, 4 реплик, cron-скриптов
|
||||
- Работает для всего кластера, не только drhider
|
||||
- Решает корневую причину (PMTU blackhole), не симптомы
|
||||
- Не трогает логику Штурвала (ingress остаётся на 2 репликах)
|
||||
- Работает для всего кластера
|
||||
- Стандартная практика для туннельного CNI
|
||||
|
||||
## Если MSS clamping невозможен
|
||||
## Примечания
|
||||
|
||||
План Б: DaemonSet для ingress через Штурвал (`controller.kind: DaemonSet` в Helm values).
|
||||
- **iptables как fallback ненадёжен:** Cilium с eBPF может обходить netfilter FORWARD. Если нужно — правило на **всех 4 нодах**, но лучше через `cilium-config`.
|
||||
- **Понижение MTU безопасно** (меньше = консервативнее). Максимум — микро-потеря throughput.
|
||||
- **Не смешивать с проблемой реплик.** При `Cluster` 2 реплик достаточно — ручной scale не нужен.
|
||||
|
||||
Reference in New Issue
Block a user