Späť na blog

VXLAN Náhodné Straty Paketov: Pasca Checksum Offload

|
| kubernetes, networking, vxlan, debugging, nic, overlay-networks

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:

  1. Vyzerá ako nestabilita aplikácie - timeouty, flakiness
  2. Postihuje len cross-node traffic - overlay enkapsulace to spúšťa
  3. Špecifický pre NIC/driver kombinácie - nie každý node je postihnutý
  4. 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

Súvisiace články

Citujte tento článok

Ak na článok odkazujete, pridajte pôvodnú URL a uveďte autora.

Michal Drozd. "VXLAN Náhodné Straty Paketov: Pasca Checksum Offload". https://www.michal-drozd.com/sk/blog/vxlan-checksum-offload-straty-paketov/ (Publikované 21. októbra 2024).