Episode ini memandu pembuatan CiliumNetworkPolicy pertama: struktur CNP, pemilihan target dengan label selector, serta rule ingress dan egress dengan port dan range. Kalian juga menerapkan policy dan mengujinya menggunakan hubble observe untuk memastikan allow-list bekerja sesuai harapan.

Konsep identity sudah kita kuasai di episode 5. Sekarang waktunya menerjemahkan konsep menjadi policy nyata. Episode 6 memperkenalkan CiliumNetworkPolicy (CNP) — CustomResource Kubernetes yang menjadi alat utama untuk menerapkan keamanan jaringan di Cilium.
Kita akan membedah struktur CNP, menulis rule ingress dan egress berbasis label selector dan port, lalu menerapkan serta mengujinya dengan hubble observe. Setelah episode ini, kalian akan bisa menulis policy allow-list untuk aplikasi sederhana — skill dasar yang dipakai hampir di semua episode security berikutnya.
CNP adalah resource Kubernetes yang scoped ke satu namespace. Bagian intinya terdiri dari tiga blok: endpointSelector untuk memilih pod yang dilindungi, lalu ingress dan egress untuk mendefinisikan traffic yang diizinkan masuk dan keluar. Struktur dasar yang perlu diingat:
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: allow-rule-contoh
spec:
endpointSelector:
matchLabels:
app: frontend
ingress:
- fromEndpoints:
- matchLabels:
app: backend
toPorts:
- ports:
- port: "8080"
protocol: TCPapiVersion: cilium.io/v2 menandai resource ini sebagai CNP. spec.endpointSelector memilih pod yang dilindungi policy; fromEndpoints di dalam ingress menentukan identity mana yang boleh menghubunginya.
Ketika sebuah CNP dengan blok ingress diterapkan, endpoint yang dipilih berubah ke mode default deny untuk ingress. Semua traffic masuk yang tidak cocok dengan rule akan di-drop. Mari kita tulis policy yang mengizinkan hanya pod dengan label app=backend untuk menghubungi port 8080 pada pod app=frontend:
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: allow-ingress
spec:
endpointSelector:
matchLabels:
app: frontend
ingress:
- fromEndpoints:
- matchLabels:
app: backend
toPorts:
- ports:
- port: "8080"
protocol: TCPPerhatikan bahwa fromEndpoints memakai label selector, bukan IP. Pod backend baru dengan label yang sama otomatis diizinkan, dan IP pod frontend yang berubah tidak memengaruhi rule sama sekali. Untuk menerapkan policy:
kubectl apply -f allow-ingress.yaml
kubectl get cnpkubectl apply -f allow-ingress.yaml menerapkan policy ke cluster, dan kubectl get cnp menampilkan daftar CNP beserta jumlah rule yang aktif.
Egress mengatur traffic yang keluar dari endpoint. Rule egress biasanya menargetkan pod lain, service DNS, atau internet dengan pembatasan port. Contoh policy yang mengizinkan pod app=frontend menghubungi database di namespace lain:
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: allow-egress-db
spec:
endpointSelector:
matchLabels:
app: frontend
egress:
- toEndpoints:
- matchLabels:
io.kubernetes.pod.namespace: database
matchLabels:
app: postgres
toPorts:
- ports:
- port: "5432"
protocol: TCPmatchLabels: app: postgres memilih pod database, dan kombinasi dengan io.kubernetes.pod.namespace: database membatasi scope ke namespace tertentu. Selama tidak ada policy egress lain yang lebih luas, setelah policy ini diterapkan, pod frontend hanya boleh keluar ke port 5432 database.
Setelah policy terpasang, saatnya memverifikasi. Aktifkan Hubble dulu jika belum (episode 7), lalu amati flow:
hubble observe --namespace default
hubble observe --verdict DROPPEDhubble observe --namespace default menampilkan flow di namespace default, termasuk verdict FORWARDED untuk traffic yang diizinkan. hubble observe --verdict DROPPED menampilkan traffic yang ditolak policy — ini cara tercepat memastikan allow-list bekerja: traffic selain yang terdefinisi harus muncul sebagai DROPPED.
Untuk simulasi cepat, buat dua pod dengan label berbeda lalu uji koneksi:
kubectl run frontend --image=nginx --labels=app=frontend
kubectl run backend --image=curlimages/curl --command -- sh -c "sleep 3600"
kubectl exec backend -- curl -s -o /dev/null -w "%{http_code}" http://frontendkubectl exec backend -- curl -s http://frontend akan berhasil (kode 200) karena backend diizinkan oleh policy. Coba jalankan dari pod dengan label lain, misalnya app=worker, dan request tersebut harus gagal atau timeout — itulah bukti default deny bekerja.
Tip
Jangan menulis policy dalam satu kali penerapan besar. Mulai dari rule kecil, terapkan, amati dengan Hubble, lalu perluas. Pola ini meminimalkan risiko memblokir traffic yang seharusnya diizinkan — kebiasaan yang akan berguna di episode 18 saat policy dikelola lewat GitOps.
Inti yang harus dibawa pulang:
kubectl apply dan kubectl get cnp untuk mengelola policy.hubble observe --verdict DROPPED untuk membuktikan allow-list bekerja.Di episode 7 selanjutnya kita akan menggali Hubble secara menyeluruh — mengaktifkan relay dan UI, membaca flow logs dengan hubble observe, melacak koneksi yang diizinkan, memverifikasi policy, dan menemukan traffic yang ter-drop. Observability inilah yang membuat semua eksperimen policy di episode ini bisa dianalisis dengan bukti, bukan tebakan.