VXLAN Náhodné Straty Paketov: Pasca Checksum Offload
Packet drops sme hnali par dni, kym sme nenasli VXLAN checksum offload. “gRPC je nestabilné medzi nodmi ale lokálne funguje perfektne.” Tri dni sme obviňovali aplikáciu, kým sme zistili, že špecifické nody ticho poškodzujú VXLAN pakety kvôli bugu v checksum offload NIC drivera.
Prostredie: Kubernetes 1.28, Calico VXLAN mode, Intel X710 NIC (špecifická verzia firmware)
Problém
Symptómy Vyzerajúce Ako Problém Aplikácie
Časová os typického incidentu:
08:00 Deploy novej verzie služby
08:05 Začínajú náhodné gRPC timeouty
08:10 Zlyhávajú len cross-node volania (~5% error rate)
08:15 Reštart podov - dočasne pomáha
08:30 Chyby sa vracajú, iné pody postihnuté
09:00 Obviňujeme "nestabilitu siete"
Čo robilo tento problém šialeným:
- Rovnaký pod-to-pod funguje lokálne - volania v rámci nodu nikdy nezlyhali
- Len špecifické zdrojové nody - nie všetky nody mali problém
- Intermitentný vzor - nie každý paket, zhruba 1-5%
- Žiadne chyby v aplikačných logoch - len timeouty
Skrytá Korupcia
# Capture na prijímajúcom node ukázal zlé checksums
tcpdump -i eth0 -vvv udp port 4789 2>&1 | grep -i checksum
# Výstup:
# UDP, length 1234: [bad udp cksum 0x1a2b -> 0x3c4d!]
# UDP, length 567: [bad udp cksum 0x5e6f -> 0x7890!]
# Ale odosielateľ si myslel že je všetko OK!
# Pretože hardware mal počítať checksum...
Analýza Príčiny
Ako Checksum Offload Rozbíja VXLAN
Normálny tok paketu:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Aplikácia │────▶│ Kernel │────▶│ NIC │
│ (gRPC) │ │ (VXLAN) │ │ (TX Offload)│
└─────────────┘ └─────────────┘ └─────────────┘
│ │
Outer UDP header Má počítať
checksum = 0x0000 checksum tu
(placeholder) │
▼
BUG: NIC nezručí
VXLAN správne
Čo sa stane s bugom:
1. Kernel vytvorí VXLAN-enkapsulovaný paket
2. Kernel nastaví outer UDP checksum = 0 (nech NIC počíta)
3. Kernel zapne tx-udp_tnl-csum-segmentation
4. NIC vypočíta checksum ZLE pre enkapsulované pakety
5. Prijímajúci kernel vidí zlý checksum → dropne paket
6. Aplikácia vidí timeout, nevie prečo
Identifikácia Postihnutých Nodov
#!/bin/bash
# check-offload-settings.sh
echo "=== Kontrola TX Offload Nastavení ==="
for node in $(kubectl get nodes -o name | cut -d/ -f2); do
echo -e "\n--- Node: $node ---"
# Skontroluj offload nastavenia
kubectl debug node/$node -it --image=nicolaka/netshoot -- \
ethtool -k eth0 2>/dev/null | grep -E "(tx-udp_tnl|tx-checksum)"
done
# Hľadaj:
# tx-udp_tnl-csum-segmentation: on <-- potenciálny problém
# tx-udp_tnl-segmentation: on
Korelácia s Verziou NIC Drivera
# Nájdi ktoré nody majú problematický driver
kubectl get nodes -o json | jq -r '.items[] | .metadata.name' | while read node; do
echo "=== $node ==="
kubectl debug node/$node -it --image=busybox -- \
cat /sys/class/net/eth0/device/driver/module/version 2>/dev/null
kubectl debug node/$node -it --image=busybox -- \
ethtool -i eth0 2>/dev/null | grep -E "(driver|version|firmware)"
done
# Príklad problematického výstupu:
# driver: i40e
# version: 2.14.13
# firmware-version: 8.30 0x8000af86 <-- táto špecifická kombinácia je buggy
Riešenie
Okamžitá Mitigácia
# Vypni problematický offload na postihnutých nodoch
# Spusti na každom postihnutom node:
ethtool -K eth0 tx-udp_tnl-csum-segmentation off
ethtool -K eth0 tx-udp_tnl-segmentation off
# Over
ethtool -k eth0 | grep tx-udp_tnl
# tx-udp_tnl-segmentation: off
# tx-udp_tnl-csum-segmentation: off
Perzistentný Fix cez DaemonSet
# nic-offload-fix.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: nic-offload-fix
namespace: kube-system
spec:
selector:
matchLabels:
app: nic-offload-fix
template:
metadata:
labels:
app: nic-offload-fix
spec:
hostNetwork: true
hostPID: true
nodeSelector:
# Spusti len na nodoch so známym buggy NIC
node.kubernetes.io/nic-type: "i40e"
initContainers:
- name: disable-offload
image: alpine
securityContext:
privileged: true
command:
- /bin/sh
- -c
- |
apk add --no-cache ethtool
# Nájdi primárne rozhranie
IFACE=$(ip route | grep default | awk '{print $5}')
echo "Vypínam tx-udp_tnl offloady na $IFACE"
ethtool -K $IFACE tx-udp_tnl-csum-segmentation off || true
ethtool -K $IFACE tx-udp_tnl-segmentation off || true
echo "Hotovo. Aktuálne nastavenia:"
ethtool -k $IFACE | grep tx-udp_tnl
containers:
- name: pause
image: gcr.io/google_containers/pause:3.2
tolerations:
- operator: Exists
Dlhodobé Riešenie: Firmware Update
# Skontroluj či firmware update opravuje problém
# Intel poskytuje NVM update tool pre X710
# Stiahni z Intel support
wget https://downloadmirror.intel.com/.../700Series_NVMUpdatePackage_v8_40_Linux.tar.gz
# Aplikuj update (vyžaduje maintenance window)
tar xzf 700Series_NVMUpdatePackage_v8_40_Linux.tar.gz
cd 700Series/Linux_x64
./nvmupdate64e -u -l -o update.log
# Rebootni node
# Znova zapni offloady a testuj
ethtool -K eth0 tx-udp_tnl-csum-segmentation on
Detekcia a Monitoring
Prometheus Metriky pre Zlé Checksums
# Poznámka: Vyžaduje node_exporter s textfile collectorom
# Vytvor skript ktorý beží periodicky
# /etc/node_exporter/scripts/nic_checksum_errors.sh
#!/bin/bash
IFACE="eth0"
RX_ERRORS=$(ethtool -S $IFACE 2>/dev/null | grep rx_csum_offload_errors | awk '{print $2}')
echo "# HELP nic_rx_csum_errors NIC RX checksum errors"
echo "# TYPE nic_rx_csum_errors counter"
echo "nic_rx_csum_errors{interface=\"$IFACE\"} ${RX_ERRORS:-0}"
Alert Pravidlá
groups:
- name: network-offload
rules:
- alert: NICChecksumErrors
expr: |
rate(nic_rx_csum_errors[5m]) > 0
for: 5m
labels:
severity: warning
annotations:
summary: "NIC {{ $labels.instance }} vykazuje checksum chyby"
description: "Môže indikovať TX offload bug na odosielacích nodoch"
- alert: CrossNodeGRPCFailures
expr: |
(
sum by (source_node, dest_node) (
rate(grpc_client_handled_total{grpc_code!="OK"}[5m])
)
/
sum by (source_node, dest_node) (
rate(grpc_client_handled_total[5m])
)
) > 0.01
for: 5m
labels:
severity: warning
annotations:
summary: "Cross-node gRPC chyby medzi {{ $labels.source_node }} a {{ $labels.dest_node }}"
Debugging Playbook
#!/bin/bash
# vxlan-debug.sh - Spusti keď podozrievaš tento problém
echo "=== Krok 1: Identifikuj zlyhávajúce cesty ==="
# Z zlyhávajúceho podu, trasuj kam pakety idú
kubectl exec -it $POD -- traceroute -n $DEST_POD_IP
echo "=== Krok 2: Capture na cieľovom node ==="
# Na node kde beží cieľový pod
tcpdump -i any -nn udp port 4789 -c 100 -w /tmp/vxlan.pcap
echo "=== Krok 3: Analyzuj checksums ==="
tcpdump -r /tmp/vxlan.pcap -vvv 2>&1 | grep -c "bad.*cksum"
echo "=== Krok 4: Skontroluj offload zdrojového nodu ==="
# Na zdrojovom node
ethtool -k eth0 | grep -E "(tx-udp_tnl|segmentation)"
echo "=== Krok 5: Testuj s vypnutým offloadom ==="
ethtool -K eth0 tx-udp_tnl-csum-segmentation off
# Zopakuj zlyhávajúce requesty
# Ak fungujú, našiel si problém
Checklist
## VXLAN Packet Drop Diagnostika
### Symptómy
- [ ] Cross-node traffic intermitentne zlyháva
- [ ] Lokálny (same-node) traffic funguje
- [ ] Špecifické zdrojové nody sú horšie
- [ ] Žiadne aplikačné chyby, len timeouty
### Diagnostika
- [ ] Zachyť pakety na prijímacej strane
- [ ] Skontroluj "bad udp cksum" v tcpdump
- [ ] Identifikuj NIC driver/firmware na zlých nodoch
- [ ] Porovnaj ethtool offload nastavenia
### Fix
- [ ] Vypni tx-udp_tnl-csum-segmentation
- [ ] Deployni DaemonSet pre perzistenciu
- [ ] Naplánuj firmware update
- [ ] Pridaj monitoring pre checksum chyby
Záver
Tento failure mode je obzvlášť zákerný pretože:
- Vyzerá ako nestabilita aplikácie - timeouty, flakiness
- Postihuje len cross-node traffic - overlay enkapsulace to spúšťa
- Špecifický pre NIC/driver kombinácie - nie každý node je postihnutý
- Tichá korupcia - žiadne chyby kým pakety nedorazí
Fix je jednoduchý (ethtool -K), ale nájsť root cause vyžaduje packet-level debugging ktorý väčšina tímov nerobí pre “intermitentné gRPC problémy.”
Súvisiace články
- Kubernetes DNS Caching - DNS problémy ovplyvňujúce cross-node traffic
- gRPC Load Balancing v Kubernetes - gRPC connection management
Súvisiace články
PMTU Blackholes: Keď Iba Veľké Odpovede Visia
Malé API odpovede fungujú, veľké visia navždy. Príčina: ICMP 'Fragmentation Needed' správy filtrované firewallmi, rozbíjajú Path MTU Discovery v overlay sieťach.
kube-proxy Mikro-Výpadky: Problém xtables Lock Contencie
Náhodné 1-3 sekundové výpadky spojení počas deploymentov. CPU vyzerá v poriadku, pamäť stabilná. Skrytá príčina: iptables-restore drží xtables lock počas endpoint churnu.
Vyčerpanie Ephemeral Portov: Node Ktorý 'Pokazí'
Jeden Kubernetes node začne zlyhávať pripojenia k externým službám zatiaľ čo pody vyzerajú zdravé. Skrytá príčina: sidecar proxy vyčerpávajú ephemeral porty krátkodobými spojeniami.
Traffic Ide na Mŕtve Pody: Conntrack Zastaralé NAT Mapovanie
Deploy spôsobuje 503 presne 2 minúty. Problém: conntrack drží NAT mapovanie na staré pod IP aj po tom čo Kubernetes odstráni endpointy.
Citujte tento článok
Ak na článok odkazujete, pridajte pôvodnú URL a uveďte autora.