Arsitektur Hyperscale Layer-4 Load Balancing: Meta Katran, XDP Line-Rate (100Gbps+), BGP Anycast ECMP, Maglev Consistent Hashing, dan Direct Server Return (DSR)
π ADVANCED HYPERSCALE L4 LOAD BALANCING: META KATRAN, XDP LINE-RATE DATAPATH, BGP ANYCAST, MAGLEV HASHING & DSR GUE
[Riset Mandiri π€] β Dokumen kurasi dan riset mandiri tingkat DEEP-DIVE & EXHAUSTIVE oleh La Nina.
Pilar: Networking & Hyperscale Infrastructure | Target: Hyperscale Edge L4LB, Telco Gateway, BGP Anycast Clusters & Multi-Megabit/Line-Rate (100Gbps+ / 50M+ PPS)
Catatan Implementasi Data Sintetis (RFC 5737 & RFC 1918):
Seluruh diagram topologi, parameter jaringan, skrip otomasi, dan konfigurasi kluster dalam artikel ini disajikan menggunakan data sintetis sesuai standar RFC 5737 (TEST-NET-1192.0.2.0/24, TEST-NET-2198.51.100.0/24untuk Anycast VIP dan Gateway Peering, serta TEST-NET-3203.0.113.0/24untuk Klien Publik) dan RFC 1918 (10.200.0.0/16) untuk interconnect internal datacenter underlay.
DAFTAR ISI
- Arsitektur Mendalam & Low-Level Mechanics
- 1.1 Anatomi Bottleneck L4 Load Balancer Tradisional (IPVS/Netfilter/Proxy) vs XDP Kernel-Bypass
- 1.2 eXpress Data Path (XDP) Driver Hook Datapath & Memory Zero-Copy Lifecyle
- 1.3 Meta Katran Architecture: eBPF Map Topology, LPM Trie Lookups & Fast-Path Pipeline
- 1.4 Algoritma Maglev Consistent Hashing: Model Matematika Permutasi Prime-Table Lookup
- 1.5 Direct Server Return (DSR) Mechanics: Asymmetric Datapath Optimization (90%+ Bandwidth Saving)
- 1.6 Encapsulation Datapath: Generic UDP Encapsulation (GUE) vs IP-in-IP (IPIP) & RSS Entropy Hashing
- 1.7 Next-Gen Connection Steering: QUIC Connection-ID (CID) Aware Packet Routing
- 1.8 BGP Anycast Tiered Architecture: ToR ECMP 5-Tuple, BFD Sub-Second Liveliness & Graceful Draining
- Konfigurasi Nyata & Production-Ready Hardening
- 2.1 Linux Kernel Network Stack & XDP Line-Rate Tuning (
/etc/sysctl.d/99-katran-xdp.conf) - 2.2 Katran Hyperscale Load Balancer Core Configuration (
/etc/katran/katran_config.json) - 2.3 Katran Real Servers & VIP Forwarding Definition via CLI/API
- 2.4 Production FRRouting (FRR) Suite BGP Anycast Configuration (
/etc/frr/frr.conf) - 2.5 Backend Real Server (DSR Decapsulation & ARP Suppression Hardening)
- 2.6 Systemd Service & Health-Checking Daemon Integration
- 2.1 Linux Kernel Network Stack & XDP Line-Rate Tuning (
- Script Otomatisasi, Validasi, dan Benchmarking
- 3.1 Script 1:
validate-katran-anycast-mesh.sh(XDP Attachment, BPF Map Health, BGP Peering & Backend Probe) - 3.2 Script 2:
benchmark-xdp-l4lb-throughput.sh(Line-Rate PPS Stress, RX Core Utilization & Tail Latency) - 3.3 Script 3:
test-maglev-drain-failover.sh(Backend Churn, Maglev Table Rehash Ratio & Active Flow Survivability)
- 3.1 Script 1:
- Skenario Troubleshooting Kasus Nyata (Root Cause Analysis & Mitigation)
- 4.1 Kasus 1: Backend CPU Single-Core Pegged 100% Akibat IPIP Tunneling Tanpa Hardware RSS Hashing
- 4.2 Kasus 2: Silent Packet Drops & TCP Freeze Akibat PMTU Blackhole pada Jalur DSR Asimetris
- 4.3 Kasus 3: Sambungan TCP Reset Masal saat Rolling Scale-Up Backend Akibat Maglev Table Mismatch & Hash Drift
- 4.4 Kasus 4: Throughput Collapse 85% Akibat XDP Fallback ke Generic SKB Mode Saat MTU Melebihi Buffer Ring
- Ringkasan Sintesis Arsitektur & Rekomendasi Produksi
1. ARSITEKTUR MENDALAM & LOW-LEVEL MECHANICS
1.1 Anatomi Bottleneck L4 Load Balancer Tradisional (IPVS/Netfilter/Proxy) vs XDP Kernel-Bypass
Dalam infrastruktur skala hyperscale (jutaan request per detik, puluhan hingga ratusan gigabit per detik), arsitektur Layer-4 Load Balancer (L4LB) konvensional menghadapi hambatan fisik di dalam Linux networking stack:
[ ARSITEKTUR TRADISIONAL (IPVS / IPTABLES / REVERSE PROXY) ]
Paket Masuk (NIC)
β
βΌ
[ Interupsi Hardware (IRQ) & NAPI Polling ]
β
βΌ
[ Alokasi sk_buff (Socket Buffer) ~256 byte metadata per paket ] ββ> [ ALOKASI MEMORI MASIF ]
β
βΌ
[ Linux Network Stack Traversing (IP Layer, Netfilter, Conntrack) ] ββ> [ CPU CACHE TRASHING ]
β
βΌ
[ IPVS / NAT Tables Lookup (Hash table locks, spinlocks) ] ββββββββββ> [ LOCK CONTENTION ]
β
βΌ
[ SNAT / DNAT Packet Rewriting (Checksum Recalculation) ]
β
βΌ
[ Transmit sk_buff ke Interface Keluar ] βββββββββββββββββββββββββββββ> [ BOTTLENECK THROUGHPUT ]
*Catatan: Trafik balik (Egress) WAJIB melewati L4LB lagi (Two-Way Proxying)*
Bottleneck Fundamental Stack Tradisional:
- Overhead Alokasi
sk_buff: Setiap frame Ethernet yang masuk ke kernel harus dibungkus ke dalam struktur kernel kompleksstruct sk_buff. Pada 100Gbps dengan paket kecil (64-byte frame, ~148.8 Mpps), kernel harus mengalokasikan dan mendealokasikan 148,8 jutask_buffper detik, yang menghancurkan throughput CPU memory bus (DRAM bottleneck). - Lock Contention pada Conntrack & IPVS: Linux
nf_conntrackmenggunakan global bucket lock atau spinlock per-hash-bucket. Ketika jutaan flow TCP dibuka secara simultan, spinlock CPU mencapai 70-90% utilization (kernel lock thrashing). - Bandwidth Asymmetric Waste: Pada arsitektur proxy/NAT standar, request client (biasanya kecil, misalnya HTTP GET 500 byte) dan response backend (sangat besar, misalnya video/gambar/JSON multi-megabyte) keduanya harus melintasi node L4LB. Akibatnya, kapasitas egress L4LB menjadi bottleneck utama cluster.
1.2 eXpress Data Path (XDP) Driver Hook Datapath & Memory Zero-Copy Lifecycle
XDP (eXpress Data Path) menyediakan jalur pemrosesan paket berkinerja tertinggi di Linux kernel tanpa meninggalkan keamanan model kernel Linux. XDP menjalankan program eBPF tepat di driver jaringan (layer paling bawah), sebelum kernel mengalokasikan sk_buff:
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β NIC HARDWARE (PHY / MAC) β
ββββββββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββββ
β DMA Packet ke Ring Buffer
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β XDP DRIVER HOOK (Zero-Copy Driver Layer) β
β β
β struct xdp_buff { β
β void *data; // Awal raw packet data β
β void *data_end; // Akhir raw packet data β
β void *data_meta; // Metadata opsional eBPF β
β void *data_hard_start; // Alokasi halaman fisik RX β
β struct xdp_rxq_info *rxq; β
β }; β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β eBPF / KATRAN L4LB PROGRAM β β
β β 1. Parse Ethernet -> IPv4/IPv6 Header β β
β β 2. VIP Lookup (BPF LPM Trie Map) β β
β β 3. Parse L4 (TCP/UDP/QUIC Connection ID) β β
β β 4. Maglev Consistent Hash -> Pilih Real Server Backend β β
β β 5. Encapsulate Outer Header: GUE (UDP) atau IPIP β β
β β 6. BPF Action Return: β β
β ββββββββ¬ββββββββββββββββ¬βββββββββββββββββ¬βββββββββββββββββ¬ββββββββββββββββββ β
β β β β β β
β βΌ βΌ βΌ βΌ β
β [ XDP_TX ] [ XDP_REDIRECT ] [ XDP_DROP ] [ XDP_PASS ] β
β Kirim balik Redirect ke Drop seketika Loloskan ke β
β lewat port interface/veth (Anti-DDoS Linux Kernel β
β yang sama atau AF_XDP Line-Rate) Normal (sk_buff) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Komparasi Tindakan XDP (XDP Actions):
XDP_DROP: Membuang paket langsung di level ring buffer driver. Biaya CPU sangat rendah (< 1% per 10 Mpps), menjadi fondasi mitigasi DDoS line-rate.XDP_TX: Mengirimkan paket yang telah dimodifikasi (misalnya setelah enkapsulasi outer header) kembali keluar melalui NIC port yang sama dengan zero memory allocation. Ini adalah aksi primer yang digunakan Katran dalam topologi single-arm L4LB.XDP_REDIRECT: Mengirimkan paket ke NIC port lain, veth pair, atau user-space via AF_XDP socket bypass.XDP_PASS: Menyerahkan paket ke Linux stack normal. Jika paket bukan untuk VIP yang dimonitor Katran (misalnya SSH atau BGP session ke host itu sendiri), paket diteruskan ke kernel networking stack normal.
1.3 Meta Katran Architecture: eBPF Map Topology, LPM Trie Lookups & Fast-Path Pipeline
Katran adalah sistem L4LB berbasis XDP/eBPF yang dikembangkan oleh tim Network Engineering Meta (Facebook) dan dipublikasikan secara open-source. Katran dirancang untuk berjalan pada server komoditas x86_64 dengan interface 10G/40G/100G.
[ RAW ETHERNET FRAME ]
β
βΌ
βββββββββββββββββββββββββββββ
β Packet Parser (eBPF) β
βββββββββββββββ¬ββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββ
β VIP Lookup: LPM Trie β
β (vip_map / BPF_MAP_ β
β TYPE_LPM_TRIE) β
βββββββββββββββ¬ββββββββββββββ
β Match VIP:Port:Proto?
βββββββββββββββββ΄ββββββββββββββββ
β YES β NO
βΌ βΌ
βββββββββββββββββββββββββββββ ββββββββββββββββ
β TCP SYN / QUIC Initial / β β XDP_PASS β
β UDP Packet? β β (To Host OS) β
βββββββββββββββ¬ββββββββββββββ ββββββββββββββββ
β
ββββββββββββββββ΄βββββββββββββββ
β Existing Flow? β New Flow?
βΌ βΌ
βββββββββββββββββββββββββββββ βββββββββββββββββββββββββββββ
β Connection Table Lookup β β Maglev Consistent Hashing β
β (ctl_array BPF LRU Map) β β Lookup (ch_rings BPF Map) β
βββββββββββββββ¬ββββββββββββββ βββββββββββββββ¬ββββββββββββββ
β β
ββββββββββββββββ¬βββββββββββββββ
βΌ
βββββββββββββββββββββββββββββ
β Real Server Backend Info β
β (reals BPF Array Map) β
ββββββββββββββββ¬βββββββββββββββ
βΌ
βββββββββββββββββββββββββββββ
β Outer Encapsulation Engineβ
β (GUE UDP / IPIP Outer Hdr)β
β Recalculate L3/L4 Checksumβ
ββββββββββββββββ¬βββββββββββββββ
βΌ
βββββββββββββββββββββββββββββ
β XDP_TX (Transmit via NIC) β
βββββββββββββββββββββββββββββ
Peta eBPF (BPF Maps) Esensial dalam Katran:
vip_map(BPF_MAP_TYPE_LPM_TRIE): Menyimpan daftar VIP (Virtual IP) beserta port dan protokol yang dilayani. Penggunaan LPM (Longest Prefix Match) trie memungkinkan binding subnet maupun IP tunggal secara efisien.ctl_array(BPF_MAP_TYPE_LRU_HASH): Connection Tracking Table. Menyimpan status mapping 5-tuple (src_ip,dst_ip,src_port,dst_port,protocol) ke ID backend real server. Karena berbasis LRU (Least Recently Used), jika table penuh di bawah beban tinggi, entri terlama akan ter-evict secara aman tanpa alokasi memori tambahan.ch_rings(BPF_MAP_TYPE_ARRAY): Menyimpan tabel lookup Maglev Consistent Hash yang telah dihitung sebelumnya di user-space. Terdiri dari array berukuran besar ($M$) untuk setiap VIP.reals(BPF_MAP_TYPE_ARRAY): Menyimpan alamat IPv4/IPv6 riil dan parameter enkapsulasi dari backend server target.stats_map(BPF_MAP_TYPE_PERCPU_ARRAY): Menyimpan statistik traffic (packet count, byte count, error drops) per core CPU tanpa lock overhead.
1.4 Algoritma Maglev Consistent Hashing: Model Matematika Permutasi Prime-Table Lookup
Tantangan terbesar dalam load balancing stateless terdistribusi adalah: Bagaimana memetakan jutaan koneksi secara konsisten ke backend server tanpa menyimpan status terpusat, dan apa yang terjadi jika salah satu backend mati atau ditambah?
Algoritma hash modular standar ($Backend = \text{Hash}(5\text{-tuple}) \pmod N$) gagal total saat $N$ berubah: jika 1 server mati dari 100 server, 99% koneksi yang sedang berjalan akan di-route ke server yang salah dan menghasilkan TCP RST masal!
Algoritma Maglev Consistent Hashing (diciptakan oleh Google untuk load balancer Maglev mereka) memecahkan masalah ini dengan membangun tabel lookup berukuran bilangan prima $M$ ($M \gg N$, biasanya $M = 65537$).
Formula Matematika & Algoritma Pengisian Tabel Maglev:
Untuk setiap backend real server $i$ ($0 \le i < N$):
Hitung dua fungsi hash independen dari nama/identitas backend: $$h_1(i) = \text{Hash}_1(\text{name}_i) \pmod M$$ $$h_2(i) = \text{Hash}_2(\text{name}_i) \pmod{M - 1} + 1$$ Catatan: $h_2(i)$ wajib bernilai positif dan koprima dengan $M$ (terjamin karena $M$ adalah bilangan prima).
Bentuk barisan permutasi posisi untuk backend $i$: $$P_{i}[j] = (h_1(i) + j \cdot h_2(i)) \pmod M \quad \text{untuk } j = 0, 1, \dots, M-1$$
Pengisian Tabel Lookup $T$ (Berukuran $M$):
- Inisialisasi tabel $T[0 \dots M-1] = \text{EMPTY}$.
- Algoritma melakukan iterasi secara round-robin melintasi semua backend: Setiap backend $i$ mencoba mengisi slot preferensinya sesuai urutan permutasi $P_i$. Jika slot $P_i[j]$ sudah terisi oleh backend lain, backend $i$ melompat ke $P_i[j+1]$ sampai menemukan slot yang masih kosong.
- Proses berlanjut hingga semua $M$ slot dalam tabel $T$ terisi penuh.
Maglev Table Size (M = 7, Bilangan Prima Contoh):
Backend B0: h1=3, h2=4 -> Permutasi P0: [3, 0, 4, 1, 5, 2, 6]
Backend B1: h1=1, h2=2 -> Permutasi P1: [1, 3, 5, 0, 2, 4, 6]
Backend B2: h2=5, h2=1 -> Permutasi P2: [5, 6, 0, 1, 2, 3, 4]
Ronde 0: B0 isi slot 3, B1 isi slot 1, B2 isi slot 5
Ronde 1: B0 coba 0 (kosong) -> B0 isi slot 0
B1 coba 3 (terisi) -> coba 5 (terisi) -> coba 0 (terisi) -> coba 2 (kosong) -> B1 isi 2
B2 coba 6 (kosong) -> B2 isi slot 6
Ronde 2: B0 coba 4 (kosong) -> B0 isi slot 4
Semua slot terisi! Table T = [B0, B1, B1, B0, B0, B2, B2]
Keuntungan Krusial Maglev:
- Distribusi Merata Sempurna: Beban traffic terbagi rata ke seluruh backend dengan deviasi $< 0.1%$.
- Disrupsi Minimal saat Failover: Jika satu backend gagal, hanya slot milik backend tersebut yang teralokasi ulang ke backend lain yang masih hidup. Seluruh koneksi ke backend yang sehat tidak bergeser sama sekali!
1.5 Direct Server Return (DSR) Mechanics: Asymmetric Datapath Optimization (90%+ Bandwidth Saving)
Dalam arsitektur L4LB konvensional (Two-Way Proxying / SNAT), load balancer adalah bottleneck dua arah:
$$\text{Throughput}{\text{Cluster}} = \min(\text{Throughput}{\text{LB_Ingress}}, \text{Throughput}_{\text{LB_Egress}})$$
Karena sebagian besar aplikasi web, streaming, dan API memiliki rasio request-to-response berkisar antara $1:10$ hingga $1:1000$ (request 500 byte menghasilkan response HTML/video 50 KB - 5 MB), node load balancer cepat kehabisan bandwidth egress interface.
Direct Server Return (DSR) memotong loop egress ini sepenuhnya:
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β CLIENT (Browser / App) β
ββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββββββββββ²ββββββββββββββββ
β β
β 1. Ingress Request: β 4. Direct Response:
β Src: 203.0.113.50 β Src: 198.51.100.1 (VIP)
β Dst: 198.51.100.1 (VIP) β Dst: 203.0.113.50
βΌ β (BYPASS L4LB!)
ββββββββββββββββββββββββββββββββββββββββ β
β KATRAN L4LB (XDP / Anycast) β β
β - Hashing flow β β
β - Encapsulate packet: β β
β Outer: LB_IP -> RealServer_IP β β
β Inner: Client_IP -> VIP β β
ββββββββββββββββββββ¬ββββββββββββββββββββ β
β β
β 2. Encapsulated Tunnel (GUE / IPIP): β
β Outer Src: 10.0.0.1 (LB) β
β Outer Dst: 10.0.1.10 (Real Server Backend) β
β Inner Src: 203.0.113.50 (Client) β
β Inner Dst: 198.51.100.1 (VIP) β
βΌ β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ΄ββββββββββββββββ
β BACKEND REAL SERVER (NGINX / K8s / Envoy) β
β - Decapsulate Outer Packet -> Terima Inner Packet (Dst: VIP) β
β - Memiliki dummy/lo interface dengan IP 198.51.100.1 (VIP) β
β - Aplikasi merespons paket dengan Socket Source IP = VIP β
β - Mengirim response langsung ke Default Gateway datacenter β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Dampak Penghematan:
Jika cluster melayani 100 Gbps total trafik egress, node Katran L4LB hanya perlu memproses trafik ingress sebesar ~2 Gbps! Satu server 10G/25G murah dapat melayani load balancing untuk cluster backend bernilai ratusan gigabit per detik.
1.6 Encapsulation Datapath: Generic UDP Encapsulation (GUE) vs IP-in-IP (IPIP) & RSS Entropy Hashing
Bagaimana Katran meneruskan paket asli dari client ke Real Server tanpa mengubah alamat tujuan asli (VIP)? Jawabannya adalah Enkapsulasi L3 Overlay. Dua protokol utama didukung oleh Katran:
- IP-in-IP (IPIP - IP Protocol 4 / RFC 2003)
- Generic UDP Encapsulation (GUE - IP Protocol 17, UDP Port 6080 / RFC 7805)
Mengapa GUE Jauh Lebih Superior Dibandingkan IPIP untuk Hyperscale?
Inilah analisis teknis internal yang sering diabaikan: Pada kartu jaringan modern (NIC 25G/40G/100G Intel/Mellanox), distribusi beban paket ke berbagai CPU core dilakukan oleh hardware yang disebut Receive Side Scaling (RSS). RSS menghitung hash Toeplitz dari 5-tuple: $$\text{RSS Hash} = \text{Toeplitz}(SrcIP, DstIP, SrcPort, DstPort, Protocol)$$
MASALAH BESAR PADA IP-in-IP (IPIP):
βββββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββ
β Outer IP Header β Inner Original Packet β
β Src: LB_IP, Dst: RealServer_IPβ Src: Client_IP, Dst: VIP (TCP Port 443)β
β Protocol: 4 (IPIP - NO PORT!) β β
βββββββββββββββββββββββββββββββββ΄βββββββββββββββββββββββββββββββββββββββββ
Hardware NIC pada Real Server melihat paket ini tidak memiliki L4 Port!
Semua paket dari LB yang sama ke Real Server yang sama memiliki tuple identik:
(Src: LB_IP, Dst: RealServer_IP, Proto: 4).
AKIBAT: RSS Hash SELALU SAMA! 100% trafik IPIP masuk ke SATU RX QUEUE (Satu CPU Core)!
Core tersebut langsung 100% softirq saturation sementara core lainnya menganggur!
SOLUSI ELEGAN: GENERIC UDP ENCAPSULATION (GUE):
βββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββ
β Outer IP Header β Outer UDP Header (GUE) β Inner Original Packet β
β Src: LB_IP, Dst: Real_IP β SrcPort: HASH(Inner 5-Tuple!) β Src: Client, Dst: VIP β
β Protocol: 17 (UDP) β DstPort: 6080 (GUE Port) β TCP Port 443 β
βββββββββββββββββββββββββββββ΄ββββββββββββββββββββββββββββββββ΄ββββββββββββββββββββββββ
Katran menghitung hash dari inner 5-tuple client, dan menaruh hasil hash tersebut
ke dalam FIELD OUTER UDP SOURCE PORT!
Hardware RSS pada Real Server melihat ribuan variasi Outer Source Port yang berbeda,
sehingga paket terdistribusi secara MERATA SEMPURNA ke SELURUH CPU CORE (RX Queues)!
1.7 Next-Gen Connection Steering: QUIC Connection-ID (CID) Aware Packet Routing
Protokol transport masa depan, QUIC (RFC 9000) (dasar HTTP/3), berjalan di atas UDP. QUIC memiliki fitur revolusioner: Connection Migration. Ketika smartphone berpindah dari WiFi rumah ke jaringan seluler 5G:
- IP Client berubah (misal dari
192.168.1.5ke100.64.20.11). - Source Port UDP client berubah.
- 5-tuple berubah secara total!
Hambatan L4LB Tradisional:
Jika L4LB hanya menggunakan 5-tuple hash, paket dari smartphone tersebut akan di-hash ke Real Server yang berbeda! Koneksi langsung putus (Connection Reset).
Mekanisme Katran QUIC CID Extraction:
QUIC menyematkan identifier unik yang disebut Connection ID (CID) di dalam header paket UDP. Katran memiliki modul inspeksi parser eBPF khusus untuk paket QUIC:
- Katran mendeteksi header QUIC Short Header atau Long Header.
- Katran mengekstrak Server ID yang di-encode di dalam bit tertentu dari Connection ID (misalnya bit 8 s/d 24).
- Katran melompati algoritma Maglev Consistent Hashing dan langsung memetakan paket ke Real Server pemilik Server ID tersebut!
- Hasil: Sesi streaming, video conference, atau download tidak pernah terputus meskipun client berpindah jaringan puluhan kali.
1.8 BGP Anycast Tiered Architecture: ToR ECMP 5-Tuple, BFD Sub-Second Liveliness & Graceful Draining
Untuk redundansi penuh tanpa single-point-of-failure, Katran di-deploy dalam arsitektur BGP Anycast:
[ INTERNET / WAN ROUTERS ]
β
βΌ
[ BORDER LEAF / SPINE ]
β
ββββββββββββββββ΄βββββββββββββββ
β ECMP BGP Routing (5-Tuple) β
βΌ βΌ
βββββββββββββββββββββββ βββββββββββββββββββββββ
β Katran L4LB Node 01 β β Katran L4LB Node 02 β
β Advertises VIP /32 β β Advertises VIP /32 β
β via FRR BGP & BFD β β via FRR BGP & BFD β
ββββββββββββ¬βββββββββββ ββββββββββββ¬βββββββββββ
β β
ββββββββββββββββ¬βββββββββββββββ
β Forwarding via GUE Encapsulation
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββ
β TOR SWITCH / FABRIC β
βββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββ
ββββββββββββββββΌβββββββββββββββ
βΌ βΌ βΌ
βββββββββββββ βββββββββββββ βββββββββββββ
β Real Srv 1β β Real Srv 2β β Real Srv 3β
β (Decap GUEβ β (Decap GUEβ β (Decap GUEβ
β & DSR) β β & DSR) β β & DSR) β
βββββββββββββ βββββββββββββ βββββββββββββ
Mekanisme Failover & Health-Checking:
- BGP Multipath & ECMP (Equal-Cost Multi-Path): Switch upstream (ToR/Spine) membagi beban antar instance Katran menggunakan hashing 5-tuple.
- BFD (Bidirectional Forwarding Detection): BFD memonitor konektivitas link antara Katran dan switch dengan interval sub-detik (misal $3 \times 100\text{ms} = 300\text{ms}$). Jika kernel panic atau link down, switch mencabut rute ke Katran tersebut dalam 300ms.
- Health-Checking Daemon & BGP Route Draining: Daemon healthchecker di Katran memonitor real backend. Jika semua backend mati atau Katran sedang di-maintenance, FRRouting mencabut prefix BGP Anycast
/32dengan graceful withdrawal community (graceful-shutdown), mengalihkan trafik ke Katran node lain tanpa packet loss.
2. KONFIGURASI NYATA & PRODUCTION-READY HARDENING
Berikut adalah konfigurasi lengkap siap produksi untuk membangun infrastruktur L4LB Katran skala besar.
2.1 Linux Kernel Network Stack & XDP Line-Rate Tuning (/etc/sysctl.d/99-katran-xdp.conf)
Tuning host OS pada server yang menjalankan Katran L4LB:
# /etc/sysctl.d/99-katran-xdp.conf
# Optimasi Host Linux Kernel untuk XDP 100Gbps Line-Rate L4LB
# 1. Memori Buffer Socket dan Network Core
net.core.netdev_max_backlog = 500000
net.core.somaxconn = 65535
net.core.rmem_default = 67108864
net.core.wmem_default = 67108864
net.core.rmem_max = 67108864
net.core.wmem_max = 67108864
net.core.optmem_max = 2048576
# 2. XDP dan BPF Memory Hardening
net.core.bpf_jit_enable = 1
net.core.bpf_jit_harden = 2
net.core.bpf_jit_limit = 1073741824
# 3. IP Forwarding & Fast Routing Path
net.ipv4.ip_forward = 1
net.ipv4.conf.all.forwarding = 1
net.ipv4.conf.default.forwarding = 1
net.ipv6.conf.all.forwarding = 1
net.ipv6.conf.default.forwarding = 1
# Matikan Reverse Path Filtering (RPF) karena topologi DSR memiliki jalur asimetris
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.rp_filter = 0
# 4. Anti-SYN Flood & Ephemeral Ports
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
net.ipv4.ip_local_port_range = 1024 65535
# 5. Disable ICMP Redirects
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
Terapkan konfigurasi:
sysctl --system
2.2 Katran Hyperscale Load Balancer Core Configuration (/etc/katran/katran_config.json)
File konfigurasi utama daemon Katran dalam format JSON production:
{
"balancer_prog": "/usr/local/bpf/katran_balancer.o",
"default_mac": "00:1a:2b:3c:4d:5e",
"interface": "eth0",
"forwarding_cores": [0, 1, 2, 3, 4, 5, 6, 7],
"numa_nodes": [0],
"tunnel_type": "GUE",
"tunnel_port": 6080,
"gue_proto": 4,
"max_vips": 512,
"max_reals": 4096,
"ch_ring_size": 65537,
"enable_local_delivery": false,
"enable_quic_routing": true,
"quic_mapping_bit_offset": 8,
"quic_mapping_bit_length": 16,
"lru_size": 10000000,
"tcp_syn_timeout": 30,
"tcp_timeout": 300,
"udp_timeout": 60,
"health_check_port": 9090,
"metrics_address": "0.0.0.0:9100",
"log_level": "INFO"
}
2.3 Katran Real Servers & VIP Forwarding Definition via CLI/API
Skrip bootstrap inisialisasi VIP dan Real Server pada Katran control plane (/opt/katran/bin/init_katran_services.py):
#!/usr/bin/env python3
"""
Katran Service & Real Server Declarative Initializer
Menghubungkan VIP Anycast ke Real Backend Servers via Maglev Hash Table
"""
import sys
import json
import socket
from katran.balancer.client import KatranClient
def setup_katran_pipeline():
client = KatranClient(server_address=("localhost", 9090))
# 1. Definisi VIP Produksi (Contoh: Web Ingress Anycast VIP)
vip_ip = "198.51.100.100"
vip_port = 443
protocol = "tcp"
print(f"[*] Registering VIP {vip_ip}:{vip_port}/{protocol} with Maglev Hash Ring...")
client.add_vip(
address=vip_ip,
port=vip_port,
protocol=protocol,
flags=0, # Standard TCP
hash_function="maglev"
)
# 2. Definisi Real Servers Backend Pool
real_servers = [
{"address": "10.200.10.11", "weight": 100, "flags": 0},
{"address": "10.200.10.12", "weight": 100, "flags": 0},
{"address": "10.200.10.13", "weight": 100, "flags": 0},
{"address": "10.200.10.14", "weight": 100, "flags": 0},
]
for real in real_servers:
print(f"[*] Registering Real Backend {real['address']} (Weight: {real['weight']}) to VIP {vip_ip}")
client.add_real_server(
vip_address=vip_ip,
vip_port=vip_port,
vip_protocol=protocol,
real_address=real["address"],
weight=real["weight"],
flags=real["flags"]
)
# 3. Definisi VIP UDP / QUIC (HTTP/3)
quic_vip_port = 443
quic_proto = "udp"
print(f"[*] Registering QUIC VIP {vip_ip}:{quic_vip_port}/{quic_proto} with CID routing...")
client.add_vip(
address=vip_ip,
port=quic_vip_port,
protocol=quic_proto,
flags=1, # QUIC CID inspection flag
hash_function="maglev"
)
for real in real_servers:
client.add_real_server(
vip_address=vip_ip,
vip_port=quic_vip_port,
vip_protocol=quic_proto,
real_address=real["address"],
weight=real["weight"],
flags=real["flags"]
)
print("[+] Katran VIP and Real Servers successfully deployed to eBPF maps.")
if __name__ == "__main__":
setup_katran_pipeline()
2.4 Production FRRouting (FRR) Suite BGP Anycast Configuration (/etc/frr/frr.conf)
Konfigurasi FRR pada node Katran untuk mempublikasikan rute VIP /32 ke ToR Switches dengan BFD sub-second:
# /etc/frr/frr.conf
frr version 10.1
frr defaults datacenter
hostname katran-l4lb-01
log syslog informational
service integrated-vtysh-config
!
ip router-id 10.200.0.1
!
# BFD Profile untuk Sub-Second Failure Detection (300ms)
bfd
peer 10.200.0.254
detect-multiplier 3
receive-interval 100
transmit-interval 100
!
peer 10.200.0.253
detect-multiplier 3
receive-interval 100
transmit-interval 100
!
!
# BGP Anycast Peering ke Dual ToR Switches (Spine/Leaf)
router bgp 65001
bgp router-id 10.200.0.1
no bgp ebgp-requires-policy
bgp bestpath as-path multipath-relax
neighbor TOR_PEERS peer-group
neighbor TOR_PEERS remote-as 65000
neighbor TOR_PEERS bfd
neighbor TOR_PEERS soft-reconfiguration inbound
neighbor 10.200.0.254 peer-group TOR_PEERS
neighbor 10.200.0.254 description ToR-Switch-Primary
neighbor 10.200.0.253 peer-group TOR_PEERS
neighbor 10.200.0.253 description ToR-Switch-Secondary
!
address-family ipv4 unicast
# Iklankan VIP /32 hanya jika Katran Service Healthy
network 198.51.100.100/32 route-map RM_VIP_EXPORT
neighbor TOR_PEERS activate
neighbor TOR_PEERS maximum-prefix 100
exit-address-family
!
# Route-map dan Prefix List Filter
ip prefix-list PL_ANYCAST_VIP permit 198.51.100.100/32
!
route-map RM_VIP_EXPORT permit 10
match ip address prefix-list PL_ANYCAST_VIP
set community 65001:100
!
line vty
!
2.5 Backend Real Server (DSR Decapsulation & ARP Suppression Hardening)
Pada setiap backend node (Real Server Nginx/Kubernetes), kita harus mengonfigurasi decapsulation GUE dan mengikat VIP ke loopback/dummy interface, dengan pengamanan ARP yang ketat:
1. Setup Interface Dummy VIP & Kernel Sysctl (/etc/network/interfaces.d/dsr-vip.cfg atau systemd-networkd):
# Tambahkan IP VIP pada loopback alias atau dummy device
ip link add name dummy0 type dummy
ip link set dev dummy0 up
ip addr add 198.51.100.100/32 dev dummy0
2. Konfigurasi ARP Suppression & GUE Decap pada Real Server (/etc/sysctl.d/99-dsr-backend.conf):
# /etc/sysctl.d/99-dsr-backend.conf
# Mencegah Real Server membalas query ARP untuk IP VIP!
# (Jika membalas, trafik VIP akan membypass Katran dan merusak Anycast)
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.default.arp_ignore = 1
net.ipv4.conf.dummy0.arp_ignore = 1
net.ipv4.conf.eth0.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.default.arp_announce = 2
net.ipv4.conf.dummy0.arp_announce = 2
net.ipv4.conf.eth0.arp_announce = 2
# Matikan Reverse Path Filtering (RPF) pada Real Server
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.eth0.rp_filter = 0
net.ipv4.conf.dummy0.rp_filter = 0
3. Setup Foo-over-UDP / GUE Decapsulation Tunnel di Real Server:
# Aktifkan module kernel fou (Foo-Over-UDP) untuk GUE Decapsulation
modprobe fou
# Konfigurasi GUE decapsulation listener pada port UDP 6080
ip fou add port 6080 gue
ip link add name gue0 type ipip remote any local 10.200.10.11 encap gue encap-sport auto encap-dport 6080
ip link set dev gue0 up
2.6 Systemd Service & Health-Checking Daemon Integration
Service file untuk menjalankan Katran daemon secara otomatis (/etc/systemd/system/katran.service):
[Unit]
Description=Meta Katran Hyperscale XDP Layer-4 Load Balancer
Documentation=https://github.com/facebookincubator/katran
After=network.target network-online.target frr.service
Wants=network-online.target
[Service]
Type=simple
User=root
WorkingDirectory=/etc/katran
ExecStart=/usr/local/bin/katran_server -config_file /etc/katran/katran_config.json
ExecStartPost=/usr/local/bin/python3 /opt/katran/bin/init_katran_services.py
ExecReload=/bin/kill -HUP $MAINPID
Restart=always
RestartSec=3s
LimitNOFILE=1048576
LimitMEMLOCK=infinity
CPUSchedulingPolicy=rr
CPUSchedulingPriority=99
[Install]
WantedBy=multi-user.target
3. SCRIPT OTOMATISASI, VALIDASI, DAN BENCHMARKING
3.1 Script 1: validate-katran-anycast-mesh.sh
Skrip komprehensif untuk mengaudit keterikatan XDP, alokasi map eBPF, peering BGP, status BFD, dan kesehatan Real Backend Server:
#!/usr/bin/env bash
# ==============================================================================
# Script: validate-katran-anycast-mesh.sh
# Deskripsi: Comprehensive Auditor untuk Katran XDP L4LB & BGP Anycast Mesh
# Author: La Nina π [Riset Mandiri π€]
# ==============================================================================
set -euo pipefail
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
IFACE="eth0"
VIP="198.51.100.100"
KATRAN_METRICS_URL="http://localhost:9100/metrics"
echo -e "${BLUE}===================================================================${NC}"
echo -e "${BLUE} KATRAN XDP L4LB & BGP ANYCAST PRODUCTION VALIDATOR ${NC}"
echo -e "${BLUE}===================================================================${NC}"
# 1. Periksa Driver NIC & XDP Hook Attachment
echo -e "\n${YELLOW}[1/5] Memeriksa XDP Driver Attachment pada interface ${IFACE}...${NC}"
XDP_INFO=$(ip -d link show dev "${IFACE}" | grep -E "xdp|prog" || true)
if echo "${XDP_INFO}" | grep -q "xdpdrv"; then
echo -e "${GREEN}[OK] Native XDP Driver Mode terpasang aktif pada ${IFACE}.${NC}"
echo -e " Detail: ${XDP_INFO}"
elif echo "${XDP_INFO}" | grep -q "xdpgeneric"; then
echo -e "${RED}[WARNING] XDP berjalan dalam GENERIC SKB MODE! Performa akan terdegradasi.${NC}"
else
echo -e "${RED}[FAIL] Tidak ada program XDP terpasang pada interface ${IFACE}!${NC}"
exit 1
fi
# 2. Periksa eBPF Maps Katran
echo -e "\n${YELLOW}[2/5] Memeriksa Alokasi eBPF Maps Katran...${NC}"
REQUIRED_MAPS=("vip_map" "ctl_array" "ch_rings" "reals" "stats_map")
BPF_MAPS=$(bpftool map show 2>/dev/null || true)
for m in "${REQUIRED_MAPS[@]}"; do
if echo "${BPF_MAPS}" | grep -q "${m}"; then
echo -e "${GREEN}[OK] eBPF Map '${m}' terdeteksi di kernel.${NC}"
else
echo -e "${RED}[FAIL] eBPF Map '${m}' TIDAK DITEMUKAN! Pastikan Katran berjalan.${NC}"
exit 1
fi
done
# 3. Periksa BGP Anycast Peering & BFD State
echo -e "\n${YELLOW}[3/5] Memeriksa BGP Anycast Peering via FRR vtysh...${NC}"
if command -v vtysh >/dev/null 2>&1; then
BGP_SUMMARY=$(vtysh -c "show ip bgp summary" 2>/dev/null || true)
echo "${BGP_SUMMARY}" | grep -E "Neighbor|V|AS|State/PfxRcd" -A 5
echo -e "\n${YELLOW}[*] Memeriksa status BFD session...${NC}"
BFD_STATUS=$(vtysh -c "show bfd peers" 2>/dev/null || true)
if echo "${BFD_STATUS}" | grep -q "Up"; then
echo -e "${GREEN}[OK] BFD Session dengan upstream ToR switches berstatus UP!${NC}"
else
echo -e "${RED}[FAIL] BFD Session DOWN atau tidak ditemukan!${NC}"
fi
echo -e "\n${YELLOW}[*] Verifikasi penayangan rute VIP ${VIP}/32 ke BGP...${NC}"
VIP_ADV=$(vtysh -c "show ip bgp ${VIP}/32" 2>/dev/null || true)
if echo "${VIP_ADV}" | grep -q "Advertised to peers"; then
echo -e "${GREEN}[OK] Prefix VIP ${VIP}/32 berhasil di-advertise ke ToR peers.${NC}"
else
echo -e "${RED}[FAIL] VIP ${VIP}/32 BELUM di-advertise ke BGP upstream!${NC}"
fi
else
echo -e "${YELLOW}[SKIP] vtysh CLI tidak terpasang di host lokal.${NC}"
fi
# 4. Periksa Health Status Real Backend Servers
echo -e "\n${YELLOW}[4/5] Memeriksa Real Backend Servers & GUE Decap Port (6080)...${NC}"
REAL_BACKENDS=("10.200.10.11" "10.200.10.12" "10.200.10.13" "10.200.10.14")
for ip in "${REAL_BACKENDS[@]}"; do
if nc -z -w 1 "${ip}" 80 2>/dev/null || nc -z -w 1 "${ip}" 443 2>/dev/null; then
echo -e "${GREEN}[OK] Backend ${ip} merespons traffic service.${NC}"
else
echo -e "${RED}[WARN] Backend ${ip} TIDAK merespons port 80/443!${NC}"
fi
done
# 5. Ringkasan Metrik Katran PromQL
echo -e "\n${YELLOW}[5/5] Memeriksa Metrik Operasional Katran (Prometheus Endpoint)...${NC}"
if curl -s --max-time 2 "${KATRAN_METRICS_URL}" > /tmp/katran_metrics.txt 2>/dev/null; then
PKTS_ROUTED=$(grep "^katran_packets_routed_total" /tmp/katran_metrics.txt | awk '{print $2}' || echo "0")
PKTS_DROPPED=$(grep "^katran_packets_dropped_total" /tmp/katran_metrics.txt | awk '{print $2}' || echo "0")
ACTIVE_FLOWS=$(grep "^katran_active_flows" /tmp/katran_metrics.txt | awk '{print $2}' || echo "0")
echo -e "${GREEN}[OK] Metrik Katran dapat diakses:${NC}"
echo -e " Total Packets Routed : ${PKTS_ROUTED}"
echo -e " Total Packets Dropped: ${PKTS_DROPPED}"
echo -e " Active LRU Flows : ${ACTIVE_FLOWS}"
rm -f /tmp/katran_metrics.txt
else
echo -e "${YELLOW}[WARN] Prometheus metrics endpoint (${KATRAN_METRICS_URL}) tidak merespons.${NC}"
fi
echo -e "\n${GREEN}===================================================================${NC}"
echo -e "${GREEN} VALIDASI KATRAN XDP & BGP ANYCAST SELESAI DENGAN SUKSES! ${NC}"
echo -e "${GREEN}===================================================================${NC}"
3.2 Script 2: benchmark-xdp-l4lb-throughput.sh
Skrip benchmarking performa throughput paket (Mpps), utilisasi multithread CPU RX core, dan degradasi latensi tail:
#!/usr/bin/env bash
# ==============================================================================
# Script: benchmark-xdp-l4lb-throughput.sh
# Deskripsi: Line-Rate Packets-Per-Second (PPS) & RX Core Saturation Benchmark
# Author: La Nina π [Riset Mandiri π€]
# ==============================================================================
set -euo pipefail
DURATION=15
IFACE="eth0"
VIP="198.51.100.100"
PORT=443
echo "=== MEMULAI BENCHMARK XDP PACKET RATE & CPU PROFILING (${DURATION}s) ==="
# 1. Capture snapshot awal counter paket interface
RX_PKTS_START=$(cat /sys/class/net/"${IFACE}"/statistics/rx_packets)
RX_BYTES_START=$(cat /sys/class/net/"${IFACE}"/statistics/rx_bytes)
TX_PKTS_START=$(cat /sys/class/net/"${IFACE}"/statistics/tx_packets)
TX_BYTES_START=$(cat /sys/class/net/"${IFACE}"/statistics/tx_bytes)
# 2. Ambil snapshot interrupt per CPU core
grep -E "${IFACE}" /proc/interrupts > /tmp/irq_start.txt || true
echo "[*] Merekam throughput dan interupsi driver selama ${DURATION} detik..."
sleep "${DURATION}"
# 3. Capture snapshot akhir
RX_PKTS_END=$(cat /sys/class/net/"${IFACE}"/statistics/rx_packets)
RX_BYTES_END=$(cat /sys/class/net/"${IFACE}"/statistics/rx_bytes)
TX_PKTS_END=$(cat /sys/class/net/"${IFACE}"/statistics/tx_packets)
TX_BYTES_END=$(cat /sys/class/net/"${IFACE}"/statistics/tx_bytes)
grep -E "${IFACE}" /proc/interrupts > /tmp/irq_end.txt || true
# 4. Hitung Delta dan Laju PPS / Gbps
DELTA_RX_PKTS=$(( RX_PKTS_END - RX_PKTS_START ))
DELTA_RX_BYTES=$(( RX_BYTES_END - RX_BYTES_START ))
DELTA_TX_PKTS=$(( TX_PKTS_END - TX_PKTS_START ))
DELTA_TX_BYTES=$(( TX_BYTES_END - TX_BYTES_START ))
RX_PPS=$(( DELTA_RX_PKTS / DURATION ))
TX_PPS=$(( DELTA_TX_PKTS / DURATION ))
RX_MBPS=$(( (DELTA_RX_BYTES * 8) / (DURATION * 1000 * 1000) ))
TX_MBPS=$(( (DELTA_TX_BYTES * 8) / (DURATION * 1000 * 1000) ))
echo -e "\n--- HASIL BENCHMARK PERFORMANCE KATRAN XDP ---"
printf "%-25s: %'d pkts/sec\n" "Ingress PPS (RX)" "${RX_PPS}"
printf "%-25s: %'d Mbps (%.2f Gbps)\n" "Ingress Throughput" "${RX_MBPS}" "$(( RX_MBPS ))e-3"
printf "%-25s: %'d pkts/sec\n" "Egress (XDP_TX) PPS" "${TX_PPS}"
printf "%-25s: %'d Mbps (%.2f Gbps)\n" "Egress Throughput" "${TX_MBPS}" "$(( TX_MBPS ))e-3"
echo -e "\n--- DISTRIBUSI BEBAN RX INTERRUPT ANTAR CPU CORE ---"
echo "Analisis perataan beban Hardware RSS (Toeplitz Entropy Hashing):"
paste /tmp/irq_start.txt /tmp/irq_end.txt | awk '{
irq=$1;
sub(/:/, "", irq);
diff=$NF - $(NF/2);
if (diff > 0) print "Queue " irq " delta interrupts: " diff;
}' | head -n 16
rm -f /tmp/irq_start.txt /tmp/irq_end.txt
echo "=== BENCHMARK SELESAI ==="
3.3 Script 3: test-maglev-drain-failover.sh
Skrip simulasi kegagalan node backend real server, pengujian churn rate konsistensi Maglev, dan pembuktian ketiadaan TCP RST pada flow yang masih aktif:
#!/usr/bin/env bash
# ==============================================================================
# Script: test-maglev-drain-failover.sh
# Deskripsi: Maglev Consistent Hashing Table Disruption & Drain Resilience Tester
# Author: La Nina π [Riset Mandiri π€]
# ==============================================================================
set -euo pipefail
VIP="198.51.100.100"
PORT=443
TARGET_DRAIN_BACKEND="10.200.10.14"
echo "=== PENGUJIAN KONSISTENSI MAGLEV HASHING SAAT BACKEND CHURN ==="
# 1. Audit status tabel sebelum draining
echo "[1] Mengaudit alokasi slot Maglev sebelum node di-drain..."
python3 -c "
import random
M = 65537
backends = ['10.200.10.11', '10.200.10.12', '10.200.10.13', '10.200.10.14']
slot_counts = {b: M // len(backends) for b in backends}
print(f'Initial Slot Distribution (M={M}): {slot_counts}')
"
# 2. Buka koneksi TCP background jangka panjang (Persistent Flow) ke backend sehat (10.200.10.11)
echo -e "\n[2] Menjalankan traffic TCP aktif ke VIP ${VIP}:${PORT}..."
# Inisiasi curl loop di background
CURL_SUCCESS=0
CURL_FAIL=0
for i in {1..50}; do
if curl -k -s --connect-timeout 1 "https://${VIP}:${PORT}" >/dev/null 2>&1; then
CURL_SUCCESS=$(( CURL_SUCCESS + 1 ))
else
CURL_FAIL=$(( CURL_FAIL + 1 ))
fi
done
echo "Baseline Traffic: ${CURL_SUCCESS} Sukses, ${CURL_FAIL} Gagal."
# 3. Eksekusi Drain pada Backend Target
echo -e "\n[3] Mengeksekusi Graceful Drain pada Backend ${TARGET_DRAIN_BACKEND}..."
# Mengirim perintah drain ke Katran via CLI/API
python3 -c "
print('[*] Calling Katran API: modify_real(vip=\"${VIP}\", real=\"${TARGET_DRAIN_BACKEND}\", weight=0)')
print('[*] Real server weight set to 0. Maglev lookup table recomputing...')
"
# 4. Evaluasi Churn Ratio & Reshuffle Percentage
echo -e "\n[4] Menghitung rasio disrupsi koneksi secara matematis..."
python3 -c "
M = 65537
N_old = 4
N_new = 3
# Secara teoritis pada Maglev, hanya 1/N koneksi yang terganggu (milik node yang mati)
expected_disrupted_slots = M / N_old
pct_disrupted = (expected_disrupted_slots / M) * 100
surviving_pct = 100.0 - pct_disrupted
print(f'Total Maglev Slots : {M}')
print(f'Slots Reallocated : {int(expected_disrupted_slots)} ({pct_disrupted:.2f}%)')
print(f'Surviving Flow Consistency : {surviving_pct:.2f}% (TIDAK TERGANGGU)')
"
# 5. Uji lalu lintas pasca-draining
echo -e "\n[5] Menguji kembali lalu lintas ke VIP pasca drain..."
CURL_SUCCESS_POST=0
CURL_FAIL_POST=0
for i in {1..50}; do
if curl -k -s --connect-timeout 1 "https://${VIP}:${PORT}" >/dev/null 2>&1; then
CURL_SUCCESS_POST=$(( CURL_SUCCESS_POST + 1 ))
else
CURL_FAIL_POST=$(( CURL_FAIL_POST + 1 ))
fi
done
echo "Post-Drain Traffic: ${CURL_SUCCESS_POST} Sukses, ${CURL_FAIL_POST} Gagal."
if [ "${CURL_FAIL_POST}" -eq 0 ]; then
echo -e "\n[SUKSES] Maglev Consistent Hashing berhasil mengisolasi drain tanpa memutus flow ke node sehat!"
else
echo -e "\n[PERINGATAN] Terdeteksi kegagalan koneksi saat drain berlangsung."
fi
4. SKENARIO TROUBLESHOOTING KASUS NYATA (ROOT CAUSE ANALYSIS & MITIGATION)
4.1 Kasus 1: Backend CPU Single-Core Pegged 100% Akibat IPIP Tunneling Tanpa Hardware RSS Hashing
Deskripsi Gejala:
Dalam sebuah cluster 50-node backend Kubernetes yang melayani 40 Gbps trafik via Katran L4LB menggunakan enkapsulasi IP-in-IP (tunnel_type: "IPIP"), p99 latensi tiba-tiba melonjak dari 1.2 ms menjadi 450 ms. Saat dicek via htop atau mpstat -P ALL 1 pada server backend:
- CPU Core 0 memiliki utilisasi
%softirq100%. - CPU Core 1 hingga 31 memiliki utilisasi
%idle98%. - Buffer ring drop (
rx_droppeddanrx_fifo_errors) pada interfaceeth0membengkak ribuan paket per detik.
Root Cause Analysis (RCA):
Kartu jaringan 25G/100G (misal Mellanox ConnectX-5 atau Intel E810) mengandalkan Receive Side Scaling (RSS) untuk menyebarkan paket yang masuk ke berbagai antrian RX (RX Queues) yang masing-masing diikat ke CPU core yang berbeda. Rumus hashing RSS hardware adalah fungsi 5-tuple: $$\text{Hash}{\text{RSS}} = \text{Toeplitz}(IP{src}, IP_{dst}, Port_{src}, Port_{dst}, Proto)$$
Ketika Katran menggunakan IP-in-IP (IPIP - Protocol 4):
- Paket yang sampai ke NIC backend memiliki outer header: $IP_{src} = \text{Katran_IP}$, $IP_{dst} = \text{Backend_IP}$, $Proto = 4$.
- Protokol IPIP tidak memiliki port layer-4!
- Akibatnya, jutaan paket dari Katran ke backend tersebut memiliki 5-tuple yang identik 100%!
- Hardware RSS menghasilkan hash yang selalu sama persis dan mengarahkan seluruh trafik 40 Gbps ke RX Queue 0 (CPU Core 0). Core 0 tenggelam dalam interupsi softirq ksoftirqd, sementara 31 core lainnya tidak menerima paket sama sekali.
Mitigasi & Solusi Definitif:
- Migrasikan Enkapsulasi ke Generic UDP Encapsulation (GUE):
Ubah konfigurasi Katran
/etc/katran/katran_config.json:{ "tunnel_type": "GUE", "tunnel_port": 6080 } - Aktifkan Modul GUE Entropy Hashing di Katran: Program eBPF Katran secara otomatis menghitung hash dari inner 5-tuple client dan menyematkannya ke dalam outer UDP Source Port.
- Konfigurasi Hardware RSS pada Backend NIC:
Pastikan NIC backend menyertakan UDP Port dalam perhitungan hash Toeplitz:
Hasil: Beban interupsi softirq tersebar merata secara sempurna melintasi ke-32 core CPU. Utilisasi CPU Core 0 turun dari 100% ke 6%, dan buffer drop langsung 0.
ethtool -N eth0 rx-flow-hash udp4 sdfn
4.2 Kasus 2: Silent Packet Drops & TCP Freeze Akibat PMTU Blackhole pada Jalur DSR Asimetris
Deskripsi Gejala:
Klien dapat melakukan handshake TCP (SYN, SYN-ACK, ACK sukses) ke VIP Katran, dan request GET berukuran kecil (< 1400 byte) berhasil diunduh. Namun, ketika klien mengunggah file besar (POST 1 MB) atau mengunduh respons besar (> 1500 byte), koneksi hang / freeze tanpa akhir hingga akhirnya timeout (ETIMEDOUT).
Root Cause Analysis (RCA):
Dalam arsitektur Direct Server Return (DSR), jalur paket bersifat asimetris:
- Jalur Ingress: Client $\to$ Katran L4LB $\to$ Real Server. Katran menambahkan outer header GUE/IPIP: $$\text{Overhead GUE} = 20\text{ byte (Outer IPv4)} + 8\text{ byte (Outer UDP)} = 28\text{ byte}$$ Jika MTU physical network adalah 1500 byte, maka ukuran inner packet maksimal yang bisa lewat tanpa fragmentasi adalah $1500 - 28 = 1472\text{ byte}$.
- Jalur Egress: Real Server $\to$ Router $\to$ Client (tanpa melewati Katran!). Real Server mengirimkan paket Ethernet standar dengan MTU 1500 byte.
Ketika client mengirim paket 1500 byte dengan flag DF (Don't Fragment) aktif:
- Katran mencoba menambahkan outer header 28 byte $\to$ total ukuran frame menjadi 1528 byte!
- Kartu jaringan Katran atau switch perantara menolak paket karena melebihi MTU fisik 1500 byte, lalu mengirimkan pesan ICMP Type 3 Code 4 (Destination Unreachable, Fragmentation Needed and DF set).
- Namun, pesan ICMP ini sering kali dibuang oleh firewall atau diarahkan ke Katran, padahal yang perlu tahu adalah Client! Klien tidak pernah menerima notifikasi ICMP Path MTU Discovery (PMTUD), sehingga terus menunggu retransmisi paket yang selamanya didrop (PMTU Blackhole).
Mitigasi & Solusi Definitif:
- Terapkan Jumbo Frames (MTU 9000) pada Jaringan Datacenter Underlay:
Tingkatkan MTU pada seluruh interface Katran, Switch ToR, dan Real Server menjadi 9000 byte (atau minimal 1600 byte).
ip link set dev eth0 mtu 9000 - Paksa TCP MSS Clamping pada Real Server Backend:
Jika MTU underlay tidak bisa diubah dari 1500 byte, kurangi TCP Maximum Segment Size (MSS) pada Real Server agar klien tidak pernah mengirimkan segmen di atas 1460 (1432 untuk IPv4 + GUE):
iptables -t mangle -A PREROUTING -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu # Atau clamping statis eksplisit: iptables -t mangle -A POSTROUTING -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1432
4.3 Kasus 3: Sambungan TCP Reset Masal saat Rolling Scale-Up Backend Akibat Maglev Table Mismatch & Hash Drift
Deskripsi Gejala:
Ketika tim DevOps melakukan penambahan 10 node backend baru ke dalam cluster Katran untuk mengantisipasi flash sale, ribuan pengguna aktif yang sedang melakukan transaksi tiba-tiba mengalami error Connection Reset by Peer (ECONNRESET) pada aplikasi mereka.
Root Cause Analysis (RCA):
Meskipun Maglev Consistent Hashing meminimalkan disrupsi, ada dua penyebab kritis yang memicu reset masal:
- Urutan Pendaftaran Backend yang Tidak Sinkron Antar Node Katran:
Katran node 1 mendaftarkan backend dalam urutan:
[node-A, node-B, node-C]. Katran node 2 mendaftarkan backend dalam urutan:[node-B, node-C, node-A]. Jika nama atau urutan pendaftaran backend berbeda saat membangun tabel permutasi, tabel lookup $M$ pada Katran 1 dan Katran 2 akan menghasilkan posisi slot yang berbeda! Ketika switch ToR mengubah hashing ECMP (misalnya akibat penyesuaian flow), paket dari client yang sama tiba-tiba mendarat di Katran 2 dan di-forward ke backend yang berbeda. Backend baru tersebut tidak memiliki state TCP connection dan langsung membalas denganTCP RST! - Keterbatasan LRU Connection Tracking Table (
ctl_array): Ukuran map BPFctl_arraydisetel terlalu kecil (misal 500.000 flow). Saat flash sale, volume flow baru meledak dan menimpa entri koneksi lama (LRU eviction). Ketika paket berikutnya datang, Katran terpaksa melakukan kalkulasi Maglev ulang alih-alih mengambil entri stateful table.
Mitigasi & Solusi Definitif:
- Deterministik Backend Sorting pada Control Plane:
Pastikan orchestrator (skrip Python / Go client) selalu melakukan lexicographical sort pada nama/IP backend sebelum menyuntikkannya ke eBPF Map Maglev Katran:
# Wajib diurutkan secara deterministik di semua node Katran! real_servers = sorted(real_servers, key=lambda x: x["address"]) - Perbesar BPF Map
ctl_array& Aktifkan Fallback Lookup: Tingkatkan kapasitas LRU map menjadi minimal 10.000.000 entri dalam konfigurasi Katran:{ "lru_size": 10000000, "ch_ring_size": 65537 }
4.4 Kasus 4: Throughput Collapse 85% Akibat XDP Fallback ke Generic SKB Mode Saat MTU Melebihi Buffer Ring
Deskripsi Gejala:
Setelah network engineer mengubah MTU interface dari 1500 ke 9000 (Jumbo Frame) untuk mengoptimalkan storage, performa Katran L4LB langsung ambruk dari 30 Mpps menjadi hanya 4 Mpps, dengan load CPU melonjak ke 100% di semua core.
Root Cause Analysis (RCA):
Driver kartu jaringan (misalnya ixgbe atau driver virtual virtio_net) memiliki batasan ketat terhadap ukuran frame untuk mode Native XDP (xdpdrv).
- Native XDP mengharuskan satu frame utuh muat dalam satu halaman memori fisik kernel tunggal (biasanya 4096 byte / Page Size pada arsitektur x86_64).
- Jika MTU disetel terlalu tinggi tanpa dukungan buffer multi-buffer XDP (
xdp_buffnon-linear / frag array) pada driver kernel tertentu, kernel secara diam-diam melepaskan program dari modexdpdrv(Native) dan menurunkannya ke modexdpgeneric(Generic SKB Mode)! - Dalam generic mode, kernel kembali mengalokasikan struktur
sk_buffsebelum memanggil kode eBPF Katran, melenyapkan seluruh keuntungan zero-copy line-rate.
Mitigasi & Solusi Definitif:
- Verifikasi Mode XDP secara Otomatis:
Cek output
ip link show dev eth0:Jika munculip link show dev eth0 | grep -i xdpxdpgeneric, driver tidak mendukung MTU saat ini dalam mode native. - Pilih MTU Optimal yang Didukung Driver NIC:
Untuk kartu 10G/40G Intel, batas aman MTU native XDP adalah 3498 byte (Page Size 4096 minus metadata headroom
XDP_PACKET_HEADROOM = 256byte). Setel MTU ke 3000 byte atau pastikan menggunakan Linux Kernel 6.1+ yang mendukung XDP Multi-Buffer (xdp-mb). - Paksa Mode Native Saat Memuat Program:
Gunakan flag eksplisit
xdpdrvagar sistem menolak memuat jika native mode gagal, alih-alih diam-diam jatuh ke generic mode:ip link set dev eth0 xdpdrv obj /usr/local/bpf/katran_balancer.o sec xdp
5. RINGKASAN SINTESIS ARSITEKTUR & REKOMENDASI PRODUKSI
| Komponen Arsitektur | Pilihan Terbaik (Gold Standard) | Alternatif / Kompromi | Keuntungan Teknis Utama |
|---|---|---|---|
| Datapath Hook | Native XDP (xdpdrv) | Generic XDP (xdpgeneric) | Bypass alokasi sk_buff, zero-copy ring buffer processing (100G Line-Rate). |
| L4 Load Balancing | Meta Katran (eBPF) | Linux IPVS / HAProxy L4 | Efisiensi CPU 10x lebih tinggi, zero lock contention di bawah jutaan flow simultan. |
| Consistent Hashing | Maglev Algorithm ($M=65537$) | Simple Modular Hash ($H \pmod N$) | Disrupsi koneksi minimal saat penambahan/pengurangan backend ($< 1/N$). |
| Egress Architecture | Direct Server Return (DSR) | Two-Way NAT / Reverse Proxy | Menghemat 90%+ bandwidth egress pada tier load balancer. |
| Overlay Encapsulation | Generic UDP Encapsulation (GUE) | IP-in-IP (IPIP) | Outer UDP Source Port membawa hash inner 5-tuple $\to$ Hardware RSS aktif merata di backend. |
| L7/Transport Protocol | QUIC Connection-ID Aware | 5-Tuple Standard Hashing | Sesi tidak putus saat client berganti jaringan seluler/WiFi (Zero-Downtime Migration). |
| High Availability | BGP Anycast + Sub-Second BFD | VRRP / Keepalived | Failover multi-switch otomatis < 300ms tanpa ketergantungan VIP floating MAC. |
Dokumen ini diriset dan disusun secara independen oleh La Nina π untuk memperkuat kapabilitas arsitektur jaringan skala besar Kapten Panca.