CNI Plugin #

Sebagai sistem orkestrasi kontainer terpopuler, Kubernetes memiliki filosofi desain yang sangat mengedepankan modularitas. Kubernetes menetapkan kontrak jaringan yang ketat (seperti Flat Network dan alokasi IP unik per Pod), namun Kubernetes API Server sendiri tidak memproses pembuatan perangkat jaringan virtual, tabel routing, atau aturan enkapsulasi paket. Tugas operasional tingkat rendah (low-level data path) tersebut didelegasikan sepenuhnya ke Container Network Interface (CNI) Plugin.

CNI adalah standar spesifikasi minimalis yang mendefinisikan bagaimana container runtime (seperti containerd atau CRI-O) berinteraksi dengan plugin jaringan pihak ketiga melalui berkas manifes konfigurasi JSON standar.

Pemilihan CNI plugin di awal pembuatan kluster adalah salah satu keputusan arsitektur paling kritis yang harus kita ambil. CNI yang kita pilih akan menentukan performa I/O jaringan kluster, ketersediaan fitur keamanan (firewall internal via NetworkPolicy), kapasitas enkripsi lalu lintas data antar-node, serta kemudahan observabilitas sistem.

Artikel ini akan membedah bagaimana CNI bekerja di bawah kap mesin, membandingkan CNI plugin terpopuler (Flannel, Calico, dan Cilium), serta menguraikan prosedur migrasi CNI pada kluster produksi.


Bagaimana CNI Bekerja: Daur Hidup Pembuatan Pod #

Ketika kita mendeploy Pod baru di kluster, Kubelet di node worker tidak langsung mengetahui cara memberikan IP ke Pod tersebut. Kubelet mengandalkan biner plugin CNI yang terpasang di host node worker untuk menyelesaikan tugas tersebut.

Secara fisik, file konfigurasi CNI disimpan di direktori host /etc/cni/net.d/, sedangkan biner eksekusinya disimpan di /opt/cni/bin/.

Mari kita perhatikan bagaimana alur koordinasi pembuatan jaringan Pod ini berlangsung melalui diagram berikut:

flowchart TD
    API["Kubernetes API Server"] -- "Instruksi Buat Pod" --> Kubelet["Kubelet (Node Worker)"]
    Kubelet -- "CRI Request (Create Sandbox)" --> CRI["Container Runtime (containerd)"]
    CRI -- "CNI ADD Command" --> CNI["CNI Plugin Binary (/opt/cni/bin/)"]
    
    subgraph CNIOperations["Operasi Internal CNI Plugin"]
        veth["1. Buat veth pair virtual"]
        IPAM["2. Ambil IP dari Pod CIDR (IPAM)"]
        netns["3. Masukkan eth0 ke Pod netns"]
        Route["4. Atur default gateway host"]
        Firewall["5. Terapkan NetworkPolicy rules"]
    end
    
    CNI --> CNIOperations
    CNIOperations -- "Return IP & MAC" --> CRI
    CRI --> Kubelet

1. Perintah ADD (Saat Pod Dibuat) #

Begitu Kubelet menerima instruksi dari API Server untuk menghidupkan Pod di node worker:

  1. Kubelet memanggil Container Runtime Interface (CRI, contoh: containerd) untuk membuat kontainer sandbox.
  2. containerd membaca direktori /etc/cni/net.d/ untuk mengetahui plugin CNI mana yang aktif, lalu mengeksekusi biner CNI tersebut dengan argumen perintah ADD.
  3. Biner CNI membuat sepasang kartu jaringan virtual (veth pair), memasukkan salah satu ujungnya (diberi nama eth0) ke dalam network namespace terisolasi milik Pod, dan mencolokkan ujung lainnya ke virtual bridge host (seperti cbr0 atau cni0).
  4. CNI berinteraksi dengan plugin IPAM (IP Address Management) untuk mengambil satu alamat IP kosong yang tersedia dari blok CIDR node worker tersebut, lalu menetapkannya ke interface eth0 Pod.
  5. CNI menuliskan aturan routing di tabel IP host node worker agar seluruh node tahu ke mana harus mengirimkan paket jika ingin menghubungi IP Pod baru tersebut.
  6. Terakhir, CNI menulis aturan iptables/eBPF untuk menerapkan pembatasan NetworkPolicy jika dikonfigurasi.

2. Perintah DEL (Saat Pod Dihapus) #

Ketika Pod dimatikan, containerd memanggil biner CNI dengan perintah DEL. CNI akan menghapus interface virtual yang telah dibuat, melepaskan alamat IP kembali ke pool IPAM agar bisa digunakan oleh Pod lain di masa mendatang, serta membersihkan seluruh aturan routing dan firewall terkait di host node worker.


Analisis Mendalam CNI Plugin Terpopuler #

Setiap CNI plugin dirancang dengan filosofi, arsitektur, dan use case yang berbeda. Mari kita bedah tiga raksasa CNI yang paling banyak digunakan di industri saat ini:

1. Flannel: Simpel dan Minimalis #

Flannel adalah salah satu CNI tertua dan paling sederhana yang dikembangkan oleh CoreOS. Filosofi Flannel sangat sederhana: berikan jaringan datar (flat network) antar node worker secepat dan semudah mungkin.

Arsitektur Flannel (Enkapsulasi VXLAN Default):
  [Pod A (10.244.1.5)] ──> [cbr0 Bridge] ──> [flannel.1 Tunnel] ──> Enkapsulasi UDP ──> Kartu Jaringan Fisik
  • Mekanisme Routing: Secara default, Flannel membungkus paket asli Pod ke dalam paket UDP menggunakan teknologi VXLAN (overlay network). Flannel juga mendukung mode host-gw (host gateway) yang mengirimkan paket secara langsung tanpa enkapsulasi, namun mode ini mewajibkan seluruh node worker berada di dalam satu subnet Layer 2 yang sama.
  • Keamanan (NetworkPolicy): Flannel tidak mendukung NetworkPolicy sama sekali. Flannel tidak memiliki kode untuk menyaring paket data. Jika kita menggunakan Flannel, semua Pod di kluster bebas menghubungi Pod lain tanpa batas.
  • Use Case Terbaik: Kluster pengembangan lokal (seperti Kind, Minikube, atau k3s), kluster kecil non-produksi yang tidak membutuhkan isolasi keamanan jaringan, atau node worker yang memiliki spesifikasi hardware sangat terbatas.

2. Calico: Standar Industri Produksi #

Calico (oleh Tigera) adalah CNI yang paling banyak diadopsi untuk kluster produksi skala enterprise. Calico dirancang dengan fokus pada keamanan tingkat tinggi dan performa routing maksimal.

Arsitektur Calico (BGP Direct Routing - Zero Enkapsulasi):
  [Pod A (10.244.1.5)] ──> [Host Route Table] ──> [Router Fisik (BGP Route Iklan)] ──> Node Worker Tujuan
  • Mekanisme Routing: Keunggulan utama Calico adalah kemampuannya melakukan routing langsung tanpa enkapsulasi menggunakan protokol BGP (Border Gateway Protocol). Calico menjalankan daemon BIRD di setiap node worker untuk mengiklankan rute CIDR Pod secara dinamis ke router fisik data center. Jika infrastruktur tidak mendukung BGP, Calico dapat dikonfigurasi menggunakan overlay IP-in-IP atau VXLAN.
  • Keamanan (NetworkPolicy): Calico memiliki modul keamanan yang sangat kuat. Ia mendukung spesifikasi standar NetworkPolicy Kubernetes secara penuh dan menyediakan objek tambahan Calico NetworkPolicy yang mendukung fitur enterprise (seperti GlobalNetworkPolicy, policy ordering, dan integrasi IP set).
  • Use Case Terbaik: Kluster produksi skala besar, environment on-premise bare-metal dengan integrasi router jaringan fisik, kluster multi-tenant yang membutuhkan isolasi firewall mikro-segmentasi yang ketat.

3. Cilium: Pelopor eBPF Generasi Terbaru #

Cilium adalah CNI modern revolusioner yang memanfaatkan teknologi kernel Linux terbaru yang bernama eBPF (extended Berkeley Packet Filter). eBPF memungkinkan kita menjalankan program sandbox yang aman langsung di dalam kernel Linux secara dinamis tanpa perlu mengubah kode sumber kernel atau memuat modul kernel baru.

Arsitektur Cilium (eBPF Data Path - Bypass iptables & kube-proxy):
  [Pod A] ──> [eBPF Program di Kernel Space (Routing & Policy)] ──> [eBPF Bypass] ──> Kartu Jaringan Fisik
  • Mekanisme Routing: Cilium menggunakan eBPF untuk melakukan penyaringan dan routing paket langsung di tingkat kernel socket. Cilium dapat menggantikan komponen kube-proxy secara penuh (kube-proxy replacement). Dengan eBPF, Cilium melompati tumpukan aturan iptables yang panjang dan lambat, mengalihkan paket secara instan menggunakan tabel pencarian internal kernel yang sangat cepat.
  • Keamanan (NetworkPolicy): Cilium mendukung whitelisting hingga Layer 7 (aplikasi). Kita dapat menuliskan NetworkPolicy untuk membatasi kueri API (misalnya: Pod frontend hanya boleh melakukan kueri HTTP GET ke path /public, dan diblokir jika melakukan POST ke /admin).
  • Observabilitas (Hubble): Cilium terintegrasi dengan Hubble, sebuah sistem observabilitas jaringan yang luar biasa. Hubble menyediakan visualisasi grafis real-time mengenai lalu lintas data kluster, menampilkan peta interaktif koneksi antar-Pod, serta mencatat log paket data yang ditolak beserta alasannya.
  • Use Case Terbaik: Kluster skala besar modern (ratusan hingga ribuan node), aplikasi yang sensitif terhadap latensi jaringan, kebutuhan audit keamanan siber yang ketat, dan kluster yang ingin berjalan tanpa overhead iptables.

Tabel Perbandingan Teknis CNI #

Berikut adalah tabel evaluasi komprehensif untuk membantu kita memilih CNI yang tepat:

Fitur / Parameter Flannel Calico Cilium
Dukungan NetworkPolicy ✗ Tidak mendukung ✓ Mendukung penuh ✓✓ Mendukung Layer 3-7
Teknologi Data Path iptables / Bridge iptables / IP sets eBPF (Bypass iptables)
Kecepatan Routing Cukup (Overlay) Sangat Cepat (BGP mode) Terbaik (eBPF bypass)
Bypass kube-proxy ✗ Tidak bisa ✗ Tidak bisa ✓ Bisa (Strict replacement)
Enkripsi Jaringan ✗ Tidak didukung ✓ WireGuard / IPsec ✓ WireGuard / IPsec
Observabilitas Alur Data Sangat Dasar Menengah Luar Biasa (Hubble UI)
Prasyarat Kernel Host Kernel standar Kernel standar Kernel Modern (>= 4.19)
Tingkat Kompleksitas Sangat Rendah Menengah Tinggi

Prosedur Migrasi CNI pada Kluster Aktif #

[!CAUTION] Mengganti CNI plugin pada kluster produksi yang sedang berjalan (live CNI migration) adalah operasi berisiko tinggi (high-risk operation) yang memicu gangguan koneksi (downtime). Hal ini terjadi karena tidak ada metode hot-swap CNI. Ketika CNI lama dimatikan dan CNI baru dihidupkan, Pod lama yang berjalan dengan konfigurasi routing CNI lama akan kehilangan rute komunikasi ke Pod baru.

Jika terpaksa harus melakukan migrasi CNI (misalnya bermigrasi dari Flannel ke Cilium):

  1. Rencanakan Jendela Pemeliharaan (Maintenance Window): Pastikan aplikasi client luar telah dialihkan ke kluster backup atau gunakan halaman maintenance selama proses berlangsung.
  2. Drain Node Secara Bertahap: Kosongkan satu per satu node worker menggunakan perintah kubectl drain agar seluruh Pod dipindahkan ke node lain.
  3. Bersihkan Konfigurasi CNI Lama di Host: Di setiap node worker yang telah kosong:
    • Hapus objek DaemonSet CNI lama dari API Server.
    • Hapus berkas konfigurasi CNI di direktori host /etc/cni/net.d/.
    • Hapus biner CNI di /opt/cni/bin/.
    • Jalankan perintah restart containerd / docker engine di host node.
  4. Terapkan CNI Plugin Baru: Deploy manifes CNI baru (atau gunakan Helm) ke kluster.
  5. Uncordon Node: Aktifkan kembali node worker menggunakan kubectl uncordon.
  6. Ulangi untuk Seluruh Node: Lakukan proses ini secara bergantian untuk seluruh node worker hingga seluruh kluster menggunakan CNI baru secara seragam.

Anti-Pattern vs Solusi dalam Penerapan CNI #

Mari kita pelajari beberapa kesalahan arsitektur (anti-pattern) yang sering terjadi saat mengonfigurasi CNI beserta cara mengatasinya.

Anti-Pattern 1: Mengabaikan Keamanan Jaringan Akibat Memilih CNI Flannel #

Kita mendeploy kluster multi-tenant produksi menggunakan CNI Flannel karena proses instalasinya yang paling mudah. Kemudian, kita menuliskan puluhan manifes NetworkPolicy yang rumit untuk memisahkan lalu lintas antar tim developer.

Konsekuensi Buruk #

Kubernetes API Server akan menerima dan menyimpan manifes NetworkPolicy kita tanpa mengeluarkan pesan error. Namun, karena CNI Flannel tidak mendukung pemfilteran paket, seluruh aturan NetworkPolicy tersebut diabaikan secara diam-diam. Developer mengira database mereka aman terisolasi, padahal sebenarnya seluruh Pod di kluster tetap bebas mengakses port database tersebut tanpa batasan.

Kode Solusi (Menggunakan CNI yang Menegakkan NetworkPolicy) #

Kita harus menginstal CNI Calico atau Cilium agar seluruh manifest NetworkPolicy yang kita tulis dieksekusi secara nyata di tingkat kernel host node worker.

# SOLUSI: Contoh potongan instalasi Cilium via Helm yang menjamin penegakan NetworkPolicy
# helm install cilium cilium/cilium \
#   --namespace kube-system \
#   --set networkPolicy.enabled=true \
#   --set networkPolicy.http=true # Mengaktifkan eBPF Layer 7 HTTP filtering

Anti-Pattern 2: Menggunakan BGP Mode Calico di Cloud VPC Tanpa Enkapsulasi Fallback #

Kita mengonfigurasi CNI Calico dengan mode routing langsung (BGP direct routing) pada kluster EKS di AWS. Kita mematikan fitur enkapsulasi IP-in-IP untuk mengejar performa transfer data maksimal.

Kode Manifest Salah (BGP Tanpa Enkapsulasi di Cloud VPC) #

# JANGAN LAKUKAN INI DI CLOUD PROVIDER: Paket rentan dibuang
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
  name: default-ipv4-ippool
spec:
  cidr: 10.244.0.0/16
  ipipMode: Never # JANGAN: Router AWS VPC membuang paket IP Pod lintas subnet!
  natOutgoing: true

Konsekuensi Buruk #

Router jaringan internal cloud (seperti AWS VPC) menerapkan aturan keamanan ketat bernama Source/Destination Check. Router cloud akan membuang (drop) setiap paket data yang melintasi batas subnet yang memiliki alamat IP pengirim yang tidak terdaftar secara resmi pada tabel routing kartu jaringan virtual EC2. Akibatnya, Pod di Node worker A tidak akan bisa menghubungi Pod di Node worker B yang berada di subnet AWS yang berbeda.

Kode Solusi (Menggunakan Mode Cross-Subnet / Hybrid) #

Kita harus menyalakan enkapsulasi IP-in-IP secara pintar menggunakan mode CrossSubnet. Paket data akan dikirim secara langsung tanpa enkapsulasi jika Pod berada di node worker dengan subnet VPC yang sama, dan otomatis dibungkus (encapsulated) hanya ketika paket harus melintasi batas subnet VPC cloud.

# SOLUSI: Aktifkan mode CrossSubnet untuk kelancaran routing cloud
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
  name: default-ipv4-ippool
spec:
  cidr: 10.244.0.0/16
  ipipMode: CrossSubnet # AMAN: Otomatis enkapsulasi hanya saat melintasi batas subnet cloud
  natOutgoing: true

Anti-Pattern 3: Menjalankan kube-proxy DaemonSet Bersamaan dengan Mode Strict Cilium eBPF #

Kita mendeploy CNI Cilium dengan konfigurasi bypass penuh kubeProxyReplacement=strict dengan tujuan menggantikan kube-proxy dengan eBPF, namun kita membiarkan DaemonSet kube-proxy bawaan kluster tetap berjalan aktif.

Konsekuensi Buruk #

Kedua komponen tersebut akan memperebutkan kontrol aturan jaringan di kernel host node worker. Kube-proxy akan terus-menerus menuliskan puluhan ribu baris iptables rules, sedangkan Cilium akan mencoba melompatinya menggunakan eBPF socket map. Hal ini memicu pemborosan memori kernel, tabrakan aturan perutean (route collision), dan degradasi performa I/O jaringan yang tidak menentu.

Kode Solusi (Hapus kube-proxy dan Setel Strict eBPF Replacement) #

Kita harus menghapus DaemonSet kube-proxy secara bersih dari kluster (atau mematikannya menggunakan node selector yang tidak cocok), kemudian menginstal Cilium dengan parameter penggantian penuh.

# SOLUSI: 1. Hapus DaemonSet kube-proxy dari kluster
kubectl delete daemonset kube-proxy -n kube-system

# 2. Instal Cilium dengan STRICT kube-proxy replacement
helm install cilium cilium/cilium \
  --namespace kube-system \
  --set kubeProxyReplacement=strict \
  --set k8sServiceHost=api.k8s.mycompany.com \
  --set k8sServicePort=6443
  • Dengan parameter kubeProxyReplacement=strict, Cilium akan mengambil alih seluruh fungsi load balancing Service ClusterIP dan NodePort langsung di dalam program eBPF kernel space tanpa menyentuh iptables.

Ringkasan #

  • Kubernetes mendelegasikan jaringan ke CNI: Kubelet memanggil biner CNI pada direktori /opt/cni/bin/ dengan perintah ADD dan DEL untuk mengonfigurasi network namespace Pod, IPAM, dan routing rules.
  • Flannel ditujukan untuk simplicity: Cepat dipasang, namun tidak memiliki dukungan untuk NetworkPolicy dan performanya menengah akibat overhead VXLAN.
  • Calico adalah CNI andalan produksi: Menyediakan performa tinggi via native routing BGP dan memiliki modul penegakan NetworkPolicy yang sangat kuat.
  • Cilium mempelopori eBPF data path: Bypass tumpukan iptables dan kube-proxy langsung di kernel space; mendukung Layer 7 HTTP filtering dan Hubble UI observability.
  • Gunakan CrossSubnet mode di cloud: Hindari penggunaan mode native routing murni tanpa enkapsulasi di cloud provider guna mencegah pembuangan paket akibat Source/Destination Check router cloud.
  • Migrasi CNI memicu downtime: Tidak ada hot-swap CNI; rencanakan proses drain node secara bertahap dan bersihkan sisa konfigurasi host secara manual selama maintenance window.

← Sebelumnya: Load Balancing & kube-proxy   Berikutnya: Service Mesh →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact