Di episode ini kita akan coba bahas Kubernetes NetworkPolicy untuk fine-grained network traffic control. Kita akan mempelajari bagaimana implement network segmentation, zero-trust networking, dan best practice untuk secure Pod communication.

Catatan
Untuk kalian yang ingin membaca episode sebelumnya, bisa click thumbnail episode 35 di bawah ini
Di episode sebelumnya, kita menjelajahi Affinity dan Anti-Affinity, yang mengontrol penempatan Pod di seluruh node. Sekarang kita akan mendalami NetworkPolicy, yang mengontrol lalu lintas jaringan antara Pod dan jaringan eksternal.
Catatan: Disini saya akan menggunakan Kubernetes Cluster yang di install melalui K3s.
Secara default, Kubernetes memungkinkan semua lalu lintas antara Pod (model jaringan datar). NetworkPolicy memungkinkan Anda menerapkan segmentasi jaringan dan jaringan zero-trust. Pikirkan NetworkPolicy seperti aturan firewall untuk cluster Anda - tanpanya, semua Pod dapat saling berbicara. Dengannya, Anda dapat membatasi komunikasi hanya ke apa yang diperlukan.
NetworkPolicy adalah resource Kubernetes yang mendefinisikan bagaimana Pod berkomunikasi satu sama lain dan dengan jaringan eksternal. Ini beroperasi pada Layer 3 (IP) dan Layer 4 (TCP/UDP) dari model OSI. Ini tidak memeriksa protokol tingkat aplikasi atau konten.
Secara default, Kubernetes tidak memiliki pembatasan jaringan:
Ini nyaman untuk pengembangan tetapi berbahaya untuk produksi. NetworkPolicy mengubah perilaku ini.
NetworkPolicy terdiri dari:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-web
spec:
podSelector:
matchLabels:
app: web
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: client
ports:
- protocol: TCP
port: 80Kebijakan Ingress mengontrol lalu lintas masuk ke Pod.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all-ingress
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- {}Aturan ingress kosong memungkinkan semua lalu lintas.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-from-frontend
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080Ini memungkinkan lalu lintas ke Pod app=backend hanya dari Pod app=frontend pada port 8080.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-from-monitoring
namespace: production
spec:
podSelector:
matchLabels:
app: web
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: monitoring
ports:
- protocol: TCP
port: 9090Ini memungkinkan lalu lintas dari Pod apa pun di namespace monitoring.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-from-external
spec:
podSelector:
matchLabels:
app: api
policyTypes:
- Ingress
ingress:
- from:
- ipBlock:
cidr: 203.0.113.0/24
except:
- 203.0.113.5/32
ports:
- protocol: TCP
port: 443Ini memungkinkan lalu lintas dari blok CIDR 203.0.113.0/24 kecuali 203.0.113.5.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: multi-ingress
spec:
podSelector:
matchLabels:
app: database
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: backend
ports:
- protocol: TCP
port: 5432
- from:
- podSelector:
matchLabels:
app: migration
ports:
- protocol: TCP
port: 5432
- from:
- namespaceSelector:
matchLabels:
name: monitoring
ports:
- protocol: TCP
port: 9090Beberapa aturan digabungkan dengan logika OR - lalu lintas yang cocok dengan aturan apa pun diizinkan.
Kebijakan Egress mengontrol lalu lintas keluar dari Pod.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all-egress
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- {}apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-to-database
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Egress
egress:
- to:
- podSelector:
matchLabels:
app: database
ports:
- protocol: TCP
port: 5432Ini memungkinkan Pod app=backend mengirim lalu lintas hanya ke Pod app=database pada port 5432.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns
spec:
podSelector:
matchLabels:
app: web
policyTypes:
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
name: kube-system
ports:
- protocol: UDP
port: 53Ini memungkinkan kueri DNS ke namespace kube-system.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-external
spec:
podSelector:
matchLabels:
app: web
policyTypes:
- Egress
egress:
- to:
- ipBlock:
cidr: 0.0.0.0/0
except:
- 169.254.169.254/32 # Blokir layanan metadata AWS
ports:
- protocol: TCP
port: 443Ini memungkinkan lalu lintas HTTPS eksternal tetapi memblokir layanan metadata AWS.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: backend-policy
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
egress:
- to:
- podSelector:
matchLabels:
app: database
ports:
- protocol: TCP
port: 5432
- to:
- namespaceSelector:
matchLabels:
name: kube-system
ports:
- protocol: UDP
port: 53Pola umum adalah menolak semua lalu lintas secara default, kemudian memungkinkan lalu lintas tertentu.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-ingress
spec:
podSelector: {}
policyTypes:
- IngressDaftar ingress kosong menolak semua lalu lintas.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-egress
spec:
podSelector: {}
policyTypes:
- EgressapiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress# Frontend dapat menerima lalu lintas dari eksternal
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-ingress
spec:
podSelector:
matchLabels:
tier: frontend
policyTypes:
- Ingress
ingress:
- from:
- ipBlock:
cidr: 0.0.0.0/0
ports:
- protocol: TCP
port: 80
- protocol: TCP
port: 443
---
# Frontend hanya dapat berbicara dengan backend
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: frontend-to-backend
spec:
podSelector:
matchLabels:
tier: frontend
policyTypes:
- Egress
egress:
- to:
- podSelector:
matchLabels:
tier: backend
ports:
- protocol: TCP
port: 8080
- to:
- namespaceSelector:
matchLabels:
name: kube-system
ports:
- protocol: UDP
port: 53
---
# Backend dapat menerima dari frontend dan berbicara dengan database
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: backend-policy
spec:
podSelector:
matchLabels:
tier: backend
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
tier: frontend
ports:
- protocol: TCP
port: 8080
egress:
- to:
- podSelector:
matchLabels:
tier: database
ports:
- protocol: TCP
port: 5432
- to:
- namespaceSelector:
matchLabels:
name: kube-system
ports:
- protocol: UDP
port: 53
---
# Database hanya dapat menerima dari backend
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: database-policy
spec:
podSelector:
matchLabels:
tier: database
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
tier: backend
ports:
- protocol: TCP
port: 5432apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-monitoring
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: monitoring
ports:
- protocol: TCP
port: 9090Ini memungkinkan Prometheus di namespace monitoring untuk mengikis metrik dari semua Pod.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-cross-namespace
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- podSelector: {}
namespaceSelector:
matchLabels:
name: productionIni memungkinkan lalu lintas hanya dalam namespace production.
Memilih Pod berdasarkan label:
podSelector:
matchLabels:
app: webMemilih Pod di namespace tertentu:
namespaceSelector:
matchLabels:
name: productionMemilih berdasarkan CIDR IP:
ipBlock:
cidr: 10.0.0.0/8
except:
- 10.1.0.0/16from:
- podSelector:
matchLabels:
app: web
namespaceSelector:
matchLabels:
name: productionIni berarti: Pod dengan label app=web di namespace production.
1. Tidak Ada Penyaringan Layer 7 (Aplikasi)
NetworkPolicy bekerja pada Layer 3/4. Ini tidak dapat memfilter berdasarkan jalur HTTP atau metode.
2. Tidak Ada Egress ke Pod di Cluster Lain
NetworkPolicy hanya bekerja dalam cluster.
3. Memerlukan Dukungan Plugin Jaringan
Tidak semua plugin jaringan mendukung NetworkPolicy. Flannel tidak, tetapi Calico, Weave, dan Cilium melakukannya.
4. Tidak Ada Logging Bawaan
NetworkPolicy tidak mencatat lalu lintas yang ditolak secara default.
5. Overhead Kinerja
Kebijakan kompleks dapat mempengaruhi kinerja jaringan.
Problem: Pod tidak dapat menyelesaikan DNS.
# JANGAN LAKUKAN INI - Pod tidak dapat menyelesaikan DNS
egress:
- to:
- podSelector:
matchLabels:
app: database
ports:
- protocol: TCP
port: 5432Solusi: Selalu izinkan DNS:
egress:
- to:
- podSelector:
matchLabels:
app: database
ports:
- protocol: TCP
port: 5432
- to:
- namespaceSelector:
matchLabels:
name: kube-system
ports:
- protocol: UDP
port: 53Problem: Pod tidak dapat mengakses API Kubernetes.
# JANGAN LAKUKAN INI - Pod tidak dapat mengakses API Kubernetes
egress:
- to:
- podSelector:
matchLabels:
app: databaseSolusi: Izinkan akses server API.
Problem: Merusak lalu lintas yang sah.
# JANGAN LAKUKAN INI - Merusak lalu lintas yang sah
ingress:
- from:
- podSelector:
matchLabels:
app: specific-appSolusi: Uji kebijakan sebelum menerapkan ke produksi.
Problem: DNS tidak akan berfungsi.
# JANGAN LAKUKAN INI - DNS tidak akan berfungsi
egress:
- to:
- ipBlock:
cidr: 10.0.0.0/8Solusi: Secara eksplisit izinkan kube-dns:
egress:
- to:
- namespaceSelector:
matchLabels:
name: kube-system
ports:
- protocol: UDP
port: 53Problem: Pemilih namespace tidak akan berfungsi.
# Ini tidak akan berfungsi jika namespace tidak diberi label
namespaceSelector:
matchLabels:
name: productionSolusi: Beri label namespace:
kubectl label namespace production name=production# Pertama, tolak semua
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
# Kemudian, izinkan lalu lintas tertentu
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-web
spec:
podSelector:
matchLabels:
app: web
policyTypes:
- Ingress
ingress:
- from:
- ipBlock:
cidr: 0.0.0.0/0
ports:
- protocol: TCP
port: 80apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: namespace-isolation
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- podSelector: {}
namespaceSelector:
matchLabels:
name: productionBeri label Pod, namespace, dan node secara konsisten:
kubectl label pod web-1 app=web tier=frontend
kubectl label namespace production name=productionTambahkan komentar yang menjelaskan tujuan kebijakan:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: backend-policy
annotations:
description: "Izinkan komunikasi frontend ke backend pada port 8080"
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080Uji kebijakan di staging sebelum produksi:
# Terapkan kebijakan
kubectl apply -f network-policy.yaml
# Uji konektivitas
kubectl exec -it pod-1 -- curl http://pod-2:8080
# Periksa kebijakan
kubectl get networkpolicy
kubectl describe networkpolicy policy-nameAlat seperti Cilium dan Calico menyediakan UI untuk manajemen kebijakan.
Gunakan alat pemantauan jaringan untuk melacak lalu lintas yang ditolak:
# Calico menyediakan log kebijakan
kubectl logs -n calico-system -l k8s-app=calico-nodekubectl get networkpolicy
kubectl get networkpolicy -n productionkubectl describe networkpolicy allow-webkubectl get networkpolicy allow-web -o yaml# Uji apakah Pod dapat menjangkau Pod lain
kubectl exec -it pod-1 -- curl http://pod-2:8080
# Uji DNS
kubectl exec -it pod-1 -- nslookup kubernetes.defaultTidak semua plugin jaringan mendukung NetworkPolicy:
| Plugin | Dukungan NetworkPolicy |
|---|---|
| Flannel | Tidak |
| Calico | Ya |
| Weave | Ya |
| Cilium | Ya |
| AWS VPC CNI | Terbatas |
| Azure CNI | Ya |
Periksa dokumentasi plugin jaringan Anda untuk dukungan.
Pada episode 36 ini, kita telah membahas NetworkPolicy di Kubernetes secara mendalam. Kita sudah belajar bagaimana implement network segmentation dan zero-trust networking dengan mengontrol lalu lintas antara Pod dan jaringan eksternal.
Key takeaway:
NetworkPolicy sangat penting untuk mengamankan cluster Kubernetes. Dengan memulai dengan kebijakan tolak-semua dan secara eksplisit memungkinkan lalu lintas yang diperlukan, Anda dapat membangun cluster yang aman dan tangguh.
Catatan
Untuk kalian yang ingin melanjutkan ke episode selanjutnya, bisa click thumbnail episode 37 di bawah ini