Linux ARP Cache Zastarané Záznamy: Blackhole Traffic Po Failoveri
Failover prebehol cisto a potom traffic zmizol v stale ARP cache. “Load balancer failover dokončený ale traffic stále ide na mŕtvy node.” Príčina: klient servery majú cachované ARP záznamy mapujúce virtuálnu IP na MAC adresu starého nodu, ignorujúc failover.
Prostredie: Linux servery, VRRP/keepalived/floating IPs, databázové failovery, migrácie load balancerov
Problém
Traffic Blackhole Po Failoveri
Časová os databázového failoveru:
T+0:00 Primary (10.0.1.10, MAC aa:bb:cc:11:22:33) je zdravý
App servery majú ARP: 10.0.1.10 → aa:bb:cc:11:22:33
T+0:30 Primary zlyháva, keepalived spustí failover
T+0:31 Secondary preberá VIP 10.0.1.10
Secondary MAC: aa:bb:cc:44:55:66
Secondary posiela gratuitous ARP
T+0:32 Niektoré app servery aktualizujú ARP cache ✓
T+0:33 Iné app servery stále majú starú cache:
10.0.1.10 → aa:bb:cc:11:22:33 (mŕtvy MAC!)
T+0:35 Traffic zo serverov so starou cache → blackhole
Pakety poslané na starý MAC, nikdy nedosiahnu nový primary
Connection timeouty, aplikačné chyby
T+5:00 ARP cache expiruje, refreshne sa
Konečne funguje správne
Prečo Gratuitous ARP Nie Vždy Funguje
Problémy propagácie gratuitous ARP:
┌─────────────────────────────────────────────────────────────┐
│ Secondary posiela: "10.0.1.10 je na aa:bb:cc:44:55:66" │
│ │
│ Toto je broadcast, ale... │
│ │
│ ✗ Switche nemusia floodovať na všetky porty │
│ ✗ Niektoré hosty ignorujú nevyžiadané ARP aktualizácie │
│ ✗ Linux gc_stale_time bráni okamžitej aktualizácii │
│ ✗ Sieťové firewally môžu dropnúť ARP broadcasts │
│ ✗ VLANy nemusia správne propagovať gratuitous ARP │
└─────────────────────────────────────────────────────────────┘
Správanie Linux ARP cache:
- gc_stale_time: 60s default - nerefreshne pred týmto
- base_reachable_time: 30s - považuje záznam za platný
- Aj s gratuitous ARP, môže preferovať existujúci "potvrdený" záznam
Príčina
Stavy Linux ARP Cache
Životný cyklus ARP záznamu:
INCOMPLETE → REACHABLE → STALE → DELAY → PROBE → FAILED
↑ │
└───────────────────────┘ (alebo refresh)
Popis stavov:
- REACHABLE: Nedávno potvrdený, používa sa priamo
- STALE: Nepotvrdený nedávno, ale stále používaný (!)
- DELAY: Chystá sa probing pre potvrdenie
- PROBE: Aktívne prebieha probing (unicast ARP)
- FAILED: Nedosiahnuteľný
Problém: STALE záznamy sa POUŽÍVAJÚ, nerefreshujú sa okamžite!
Predvolené Timeouty
# Skontroluj parametre ARP cache
sysctl net.ipv4.neigh.default.gc_stale_time
# 60 sekúnd - ako dlho pred garbage collection STALE
sysctl net.ipv4.neigh.default.base_reachable_time_ms
# 30000 ms - ako dlho je záznam REACHABLE
sysctl net.ipv4.neigh.default.gc_thresh3
# 1024 - max záznamov pred agresívnym GC
# Celkový čas kedy môže byť záznam stale ale používaný: gc_stale_time + probing
# Môže byť 60-120 sekúnd traffic na zlú destináciu!
Diagnostika
Skontroluj Stav ARP Cache
# Zobraz ARP cache so stavom
ip neigh show
# Výstup:
# 10.0.1.10 dev eth0 lladdr aa:bb:cc:11:22:33 STALE
# ^^^^^ Problém!
# Sleduj zmeny ARP cache
ip monitor neigh
# Skontroluj konkrétny záznam
ip neigh show 10.0.1.10
Over Cestu Traffic
# Skontroluj či pakety dosahujú správnu destináciu
tcpdump -i eth0 -n host 10.0.1.10
# Uvidíš traffic idúci na ZLÝ MAC:
# 12:00:01 IP app-server > 10.0.1.10: TCP...
# Frame dst: aa:bb:cc:11:22:33 (starý MAC, mŕtvy server!)
# Správne po refreshi:
# Frame dst: aa:bb:cc:44:55:66 (nový MAC, aktívny server)
Skontroluj Príjem Gratuitous ARP
# Na app serveri, sleduj gratuitous ARP
tcpdump -i eth0 -n arp
# Mal by si vidieť:
# 12:00:30 ARP, Reply 10.0.1.10 is-at aa:bb:cc:44:55:66
# Ale ak nevidíš, skontroluj:
# - Sieťovú cestu (VLANy, firewally)
# - Správanie floodinku switcha
# - Kernel ignorujúci nevyžiadané ARP
Riešenie
Možnosť 1: Zníž Timeouty ARP Cache
# Zníž čas kedy záznamy zostávajú STALE
sysctl -w net.ipv4.neigh.default.gc_stale_time=30
sysctl -w net.ipv4.neigh.eth0.gc_stale_time=30
# Zníž REACHABLE čas
sysctl -w net.ipv4.neigh.default.base_reachable_time_ms=15000
# Urob persistentné v /etc/sysctl.d/arp.conf:
net.ipv4.neigh.default.gc_stale_time = 30
net.ipv4.neigh.default.base_reachable_time_ms = 15000
Možnosť 2: Akceptuj Gratuitous ARP Aktualizácie
# Zapni prijímanie nevyžiadaných ARP aktualizácií
sysctl -w net.ipv4.conf.all.arp_accept=1
sysctl -w net.ipv4.conf.eth0.arp_accept=1
# Toto prinúti Linux aktualizovať cache na gratuitous ARP
# aj pre existujúce záznamy
# Persistentné:
net.ipv4.conf.all.arp_accept = 1
Možnosť 3: Flushni ARP Cache Pri Failoveri
#!/bin/bash
# failover_arp_flush.sh - Spusti na klient serveroch po failoveri
VIP="10.0.1.10"
# Zmaž konkrétny ARP záznam
ip neigh del $VIP dev eth0 2>/dev/null
# Alebo flushni a nechaj znova naučiť
ip neigh flush $VIP
# Over
ip neigh show $VIP
# Ansible playbook na flush ARP pri failoveri
---
- name: Flush stale ARP entries
hosts: app_servers
tasks:
- name: Delete VIP ARP entry
command: ip neigh del {{ vip }} dev eth0
ignore_errors: yes
- name: Force ARP refresh with ping
command: ping -c 1 {{ vip }}
ignore_errors: yes
Možnosť 4: Pošli Viac Gratuitous ARP
# V keepalived.conf - pošli viac gratuitous ARP
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
# Pošli gratuitous ARP viackrát
garp_master_delay 1
garp_master_repeat 5 # Pošli 5-krát
garp_master_refresh 30 # Opakuj každých 30s
garp_master_refresh_repeat 2
virtual_ipaddress {
10.0.1.10/24
}
}
Možnosť 5: Použi arping Pre Aktívny Refresh
#!/bin/bash
# active_arp_announce.sh - Spusti na novom primary po failoveri
VIP="10.0.1.10"
INTERFACE="eth0"
# Pošli flood gratuitous ARP
for i in {1..10}; do
arping -U -I $INTERFACE $VIP -c 1
arping -A -I $INTERFACE $VIP -c 1
sleep 0.1
done
# -U: Nevyžiadaná ARP reply (gratuitous)
# -A: Nevyžiadaný ARP request (niektoré systémy preferujú toto)
Monitoring
groups:
- name: arp-cache
rules:
- alert: ARPCacheStaleVIP
expr: |
time() - arp_entry_last_confirmed_seconds{ip=~"10.0.1.*"} > 120
for: 5m
labels:
severity: warning
annotations:
summary: "Zastaraný ARP záznam pre VIP {{ $labels.ip }}"
- alert: FailoverTrafficBlackhole
expr: |
rate(tcp_retransmits_total{dest=~"10.0.1.*"}[1m]) > 100
for: 2m
labels:
severity: critical
annotations:
summary: "Vysoké TCP retransmity na VIP - možný ARP problém"
Checklist
## Linux ARP Cache Failover
### Pred Failoverom
- [ ] Nakonfiguruj znížený gc_stale_time (30s namiesto 60s)
- [ ] Zapni arp_accept=1 na klient serveroch
- [ ] Nakonfiguruj keepalived pre viac gratuitous ARP
- [ ] Otestuj failover s tcpdump monitoringom
### Počas/Po Failoveri
- [ ] Over že gratuitous ARP bol poslaný z nového primary
- [ ] Skontroluj stav ARP cache na klient serveroch
- [ ] Flushni zastarané záznamy ak potrebné
- [ ] Monitoruj connection timeouty
### Ak Nastane Traffic Blackhole
- [ ] Identifikuj postihnuté servery: ip neigh show | grep STALE
- [ ] Flushni ARP cache: ip neigh flush <VIP>
- [ ] Pošli dodatočné gratuitous ARP z nového primary
- [ ] Skontroluj sieťovú cestu pre problémy propagácie ARP
Záver
Lekcia: Linux ARP cache je lepkavý - preferuje existujúce záznamy pred gratuitous ARP aktualizáciami. Nakonfiguruj agresívne cache timeouty a zapni arp_accept=1 pre rýchlejšiu reakciu na failover.
Kľúčové princípy:
- STALE záznamy sa stále používajú - traffic ide na starý MAC
- gc_stale_time=30 pre rýchlejšiu expiráciu cache
- arp_accept=1 pre prijímanie gratuitous ARP aktualizácií
- Pošli viac gratuitous ARP z nového primary
Súvisiace články
- Conntrack Stale NAT Mappings - Problémy so sieťovým stavom
- Gossip Ghost Nodes IP Reuse - Zastaraná sieťová identita
Súvisiace články
Kubernetes Ghost Connections: Zastarané Conntrack DNAT Záznamy
Service vracia zlé pod IP po škálovaní. Príčina: Linux conntrack drží DNAT záznamy dlhšie ako existujú pody, smeruje traffic na zmazané endpointy.
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.
Kubernetes conntrack Vyčerpanie: Tichý Zabijak Paketov
Náhodné DNS timeouty, dropped spojenia, služby timeout-ujú. Vaša nf_conntrack tabuľka je plná. Ukážem ako diagnostikovať, monitorovať a opraviť tento K8s networking problém.
TCP TIME_WAIT Vyčerpanie Portov: Keď Connection Pooling Nestačí
Služba sa nemôže pripojiť k databáze - 'cannot assign requested address'. Príčina: ephemeral porty vyčerpané tisíckami socketov v TIME_WAIT stave.
Citujte tento článok
Ak na článok odkazujete, pridajte pôvodnú URL a uveďte autora.