Load Balancing & kube-proxy #
Setiap kali traffic menuju sebuah Service di Kubernetes, ada mekanisme di balik layar yang memutuskan Pod mana yang akan menerima request tersebut. Komponen yang bertanggung jawab adalah kube-proxy — sebuah agen yang berjalan di setiap node dan mengimplementasikan logika routing Service. Memahami cara kerjanya penting untuk mendiagnosis masalah performa dan memilih konfigurasi yang tepat untuk cluster besar.
Apa yang Dilakukan kube-proxy #
kube-proxy tidak memproses traffic secara langsung — ia tidak berada di jalur data. Tugasnya adalah mengatur aturan jaringan di setiap node yang membuat traffic otomatis di-forward ke Pod yang tepat.
Cara kube-proxy bekerja:
1. kube-proxy watch API Server untuk perubahan Service dan Endpoints
2. Saat Service "api" dibuat dengan ClusterIP 10.96.45.12
dan 3 Pod di belakangnya:
3. kube-proxy menulis aturan di setiap node:
"Traffic ke 10.96.45.12:80 → forward ke salah satu dari:
10.244.1.5:8080 (Pod A)
10.244.2.3:8080 (Pod B)
10.244.3.7:8080 (Pod C)"
4. Ketika Pod D ditambahkan atau Pod A dihapus,
kube-proxy memperbarui aturan di semua node secara otomatis
kube-proxy tidak pernah “melihat” paket data yang lewat — aturan yang ia tulis langsung di-eksekusi oleh kernel Linux.
Mode iptables (Default) #
Mode default kube-proxy menggunakan iptables — mekanisme filtering paket di kernel Linux. Setiap Service dan Endpoints menghasilkan serangkaian aturan iptables.
Contoh aturan iptables untuk Service "api":
KUBE-SERVICES chain:
-d 10.96.45.12/32 -p tcp --dport 80 → jump KUBE-SVC-API
KUBE-SVC-API chain (3 Pod, load balancing 1/3 probability):
probability 0.33 → jump KUBE-SEP-POD-A
probability 0.50 → jump KUBE-SEP-POD-B (0.5 dari 2/3 yang tersisa = 1/3)
no condition → jump KUBE-SEP-POD-C (fallthrough = 1/3)
KUBE-SEP-POD-A chain:
-j DNAT --to-destination 10.244.1.5:8080
Algoritma load balancing: random dengan probabilitas equal — setiap Pod mendapat peluang yang sama untuk menerima koneksi baru. Ini bukan round-robin murni, tapi secara statistik distribusinya seimbang dalam skala besar.
Keterbatasan mode iptables:
Masalah dengan banyak Service (ribuan):
Setiap request melewati SEMUA aturan iptables secara linear
1000 Service = evaluasi ribuan aturan per paket
10000 Service = puluhan ribu evaluasi → latensi naik signifikan
Update rules tidak atomik:
Saat Endpoints berubah, iptables harus di-flush dan ditulis ulang
→ brief period di mana aturan tidak konsisten
→ untuk cluster dengan update Endpoints sangat sering, ini bisa masalah
Mode IPVS #
IPVS (IP Virtual Server) adalah mode alternatif yang jauh lebih efisien untuk cluster besar. Ia menggunakan hash table untuk routing, bukan linear traversal.
Perbedaan kinerja:
Mode iptables:
100 Service → O(n) lookup → ~100 rule evaluations per paket
10000 Service → ~10000 evaluations per paket → latensi tinggi
Mode IPVS:
100 Service → O(1) hash lookup → konstan
10000 Service → O(1) hash lookup → tetap cepat
Update rules:
iptables: flush semua → tulis ulang → non-atomik
IPVS: update incremental → atomik → tidak ada downtime
IPVS juga mendukung lebih banyak algoritma load balancing:
Algoritma load balancing IPVS:
rr (round-robin) — bergantian merata
lc (least connection) — Pod dengan koneksi paling sedikit
dh (destination hash) — hash berdasarkan destination
sh (source hash) — hash berdasarkan source IP (session sticky)
sed (shortest expected delay)
nq (never queue)
Untuk mengaktifkan mode IPVS:
# ConfigMap kube-proxy (biasanya di kube-system)
apiVersion: v1
kind: ConfigMap
metadata:
name: kube-proxy
namespace: kube-system
data:
config.conf: |-
mode: "ipvs"
ipvs:
scheduler: "lc" # algoritma least connection
IPVS membutuhkan kernel moduleip_vs,ip_vs_rr, dll yang harus tersedia di node. Di cloud managed Kubernetes (GKE, EKS, AKS), ini biasanya sudah tersedia. Untuk cluster on-premise, pastikan node sudah menginstallipvsadmdan module tersebut di-load.
Session Affinity #
Secara default, kube-proxy mendistribusikan koneksi secara random. Untuk aplikasi yang membutuhkan sesi yang konsisten ke Pod yang sama (session stickiness), kamu bisa mengaktifkan session affinity:
apiVersion: v1
kind: Service
spec:
selector:
app: api
sessionAffinity: ClientIP # sticky berdasarkan IP client
sessionAffinityConfig:
clientIP:
timeoutSeconds: 3600 # session timeout: 1 jam
ports:
- port: 80
targetPort: 8080
Session affinity bekerja dengan cara: koneksi dari IP client yang sama selalu dikirim ke Pod yang sama, selama Pod tersebut masih tersedia dan dalam periode timeout.
Keterbatasan session affinity berbasis ClientIP:
Masalah:
→ Client di belakang NAT atau load balancer eksternal
terlihat punya IP yang sama → semua traffic ke satu Pod
→ Pod target mati → session break, koneksi ke Pod baru
Alternatif yang lebih baik untuk session:
→ Gunakan session store berbasis Redis/Memcached
(lebih reliabel, tidak bergantung pada IP affinity)
→ Desain aplikasi sebagai stateless (session di client via JWT)
External Traffic Policy #
Untuk Service tipe NodePort dan LoadBalancer, ada pengaturan tambahan yang mempengaruhi bagaimana traffic dari luar cluster diproses:
spec:
type: LoadBalancer
externalTrafficPolicy: Cluster # default
# atau:
externalTrafficPolicy: Local
externalTrafficPolicy: Cluster (default):
Traffic masuk ke Node-1 bisa di-forward ke Pod di Node-2
Pro: load balancing merata ke semua Pod
Con: SNAT terjadi → Pod kehilangan IP asli client
Tambahan network hop untuk traffic lintas node
externalTrafficPolicy: Local:
Traffic hanya di-forward ke Pod di node yang sama
Pro: Tidak ada SNAT → Pod bisa lihat IP asli client
Tidak ada network hop tambahan
Con: Load balancing tidak merata jika distribusi Pod tidak merata
Node tanpa Pod tidak bisa serve traffic
Untuk aplikasi yang butuh IP asli client (untuk geolocation, logging, rate limiting), gunakan Local.
Ringkasan #
- kube-proxy menulis aturan, tidak memproses traffic — ia tidak berada di jalur data; kernel Linux yang mengeksekusi aturan routing yang ditulis kube-proxy.
- Mode iptables default, IPVS untuk cluster besar — iptables tidak efisien untuk ribuan Service karena traversal linear; IPVS menggunakan hash table dengan lookup O(1).
- Load balancing random berbasis probabilitas — distribusi statistik merata di skala besar; bukan round-robin murni tapi hasilnya serupa.
- IPVS mendukung lebih banyak algoritma — round-robin, least connection, source hash untuk session affinity yang lebih fleksibel.
- Session affinity berbasis ClientIP punya keterbatasan — NAT dan load balancer eksternal bisa membuat semua client terlihat dari IP yang sama; lebih baik desain stateless atau gunakan external session store.
- externalTrafficPolicy: Local untuk IP asli client — mencegah SNAT sehingga Pod bisa melihat IP asli client; tapi distribusi traffic bisa tidak merata.