91 lines
3.7 KiB
Markdown
91 lines
3.7 KiB
Markdown
# Корневое решение: MSS clamping через Cilium
|
||
|
||
**Дата:** 2026-07-13 (обновлено после валидации Opus)
|
||
**Статус:** План для девопса
|
||
**Валидация:** [Opus response](../History/2026-07-13-opus-response-mss-clamping.md)
|
||
|
||
---
|
||
|
||
## Текущий костыль
|
||
|
||
`externalTrafficPolicy: Local` + `kubectl scale replicas=4` (сбрасывается Штурвалом каждые ~час).
|
||
|
||
## Корень проблемы
|
||
|
||
Geneve-туннель добавляет ~50 байт → превышение underlay MTU → ICMP Frag Needed блокируется → TCP stall 51с.
|
||
|
||
## Решение
|
||
|
||
Выставить корректный MTU в Cilium, чтобы пакеты с Geneve-заголовком всегда влазили.
|
||
|
||
**Важно:** `mtu` в cilium-config — это MTU **underlay-сети** (физической/VM-сети между нодами). Cilium сам вычитает 50 байт на Geneve:
|
||
```
|
||
mtu: X → туннель = X − 50 → поды = X − 50
|
||
```
|
||
|
||
## Что сделать девопсу
|
||
|
||
## Замер (выполнен 2026-07-13)
|
||
|
||
```bash
|
||
kubectl run mtu-test --rm -it --restart=Never --image=nicolaka/netshoot -- ping -c 2 -M do -s 1472 172.16.0.9
|
||
# → Message too large (1500 не проходит)
|
||
|
||
kubectl run mtu-test --rm -it --restart=Never --image=nicolaka/netshoot -- ping -c 2 -M do -s 1422 172.16.0.9
|
||
# → 1430 bytes from 172.16.0.9 (1450 проходит)
|
||
|
||
**Результат:** underlay MTU = **1450**, туннель = **1400**.
|
||
|
||
### Шаг 1: Выставить MTU в Cilium
|
||
|
||
```bash
|
||
kubectl edit configmap -n kube-system cilium-config
|
||
# mtu: <измеренное значение>
|
||
```
|
||
|
||
### Шаг 2: Применить изменения
|
||
|
||
```bash
|
||
# Перезапустить агенты Cilium (ConfigMap сам не применяется)
|
||
kubectl rollout restart ds/cilium -n kube-system
|
||
|
||
# Пересоздать поды приложения (ingress, drhider — чтобы veth получили новый MTU)
|
||
kubectl rollout restart deploy -n ingress shturval-ingress-controller-controller
|
||
```
|
||
|
||
### Шаг 3: Вернуть Cluster policy
|
||
|
||
```bash
|
||
kubectl patch svc -n ingress shturval-ingress-controller-controller \
|
||
-p '{"spec":{"externalTrafficPolicy":"Cluster"}}'
|
||
```
|
||
|
||
### Шаг 4: Верификация
|
||
|
||
```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 и другие сервисы
|
||
|
||
## Почему это грамотно
|
||
|
||
- Решает корневую причину (PMTU blackhole), не симптомы
|
||
- Не трогает логику Штурвала (ingress остаётся на 2 репликах)
|
||
- Работает для всего кластера
|
||
- Стандартная практика для туннельного CNI
|
||
|
||
## Примечания
|
||
|
||
- **iptables как fallback ненадёжен:** Cilium с eBPF может обходить netfilter FORWARD. Если нужно — правило на **всех 4 нодах**, но лучше через `cilium-config`.
|
||
- **Понижение MTU безопасно** (меньше = консервативнее). Максимум — микро-потеря throughput.
|
||
- **Не смешивать с проблемой реплик.** При `Cluster` 2 реплик достаточно — ручной scale не нужен.
|