Network Policies
Açıklaması
şöyle. Yani varsayılan davranışta herhangi bir kısıtlama yoktur. Her pod her pod ile ağ bağlantısı kurabilir
By default, Kubernetes allows communication from any pod to another pod within the same cluster. While this is ideal for service discovery, it provides zero network separation, allowing bad actors or compromised systems unlimited access to all resources. This becomes extremely problematic for teams using namespaces as the primary means of multi-tenancy inside Kubernetes.
To control the traffic flow between pods, namespaces, and external endpoints, use a CNI plugin that supports the NetworkPolicy API (e.g., Calico, Flannel, or cloud-specific CNI) for network isolation. Following the zero-trust model, the best practice is to implement a default deny-all policy to block all ingress and egress traffic unless it is specifically allowed by another policy.
Kullanım
podSelector ile kendi isim alanım içindeki belirtilen label'a sahip podları seçerim
namespaceSelector ile belirtilen isim alanını seçerim
ingress ve egress için policy belirtilir. ingress pod'a gelen bağlantı, egress ise poddan çıkan bağlantıdır
ingress altına from ile namespaceSelector ve podSelector ile seçim kuralları yazılır
egress altın to ile namespaceSelector ve podSelector ile seçim kuralları yazılır
Örnek
Şöyle
yaparız. Bunun ismi default deny çünkü her türlü trafiği engelliyor
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: my-ns
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
1. Ingress
Örnek
Elimizde şöyle bir network policy
olsun. Burada iki tane ingress network policy var. Birincisi her şeye izin veriyor. İkincisi sadece ismi
a olan isim alanından izin veriyor.
#networkpolicy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: namespace-a
spec:
podSelector: {}
policyTypes:
- Ingress
---
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: allow-namespace-a
namespace: namespace-a
spec:
podSelector:
matchLabels:
app: k8s-security-demo
ingress:
- from:
- namespaceSelector:
matchLabels:
team: a
Açıklaması şöyle
... we have created two network policies: one denies everything, the other allows access from within the namespace.
namespace-b'den bağlanamadığımızı ancak namespace-a'dan bağlanabildiğimizi görmek için şöyle
yaparız$ kubectl exec -n namespace-b -it testpod -- sh
$ curl k8s-security-demo.namespace-a
curl: (28) Failed to connect to k8s-security-demo.namespace-a port 80 after 129977 ms:
Operation timed out
namespace-a'dan bağlanabildiğimizi görmek için şöyle
yaparız$ kubectl exec -n namespace-a -it testpod -- sh
$ curl k8s-security-demo.namespace-a
Hello, world!/ $
2. Egress
Örnek
-> (80) Web Server -> (5000) App Server -> 3306 DB Server
Şöyle
yaparız. Web-Policy olarak web-server dışarıdan gelen her bağlantıyı kabul eder ve api-pod'un 5000 numaralı portuna gönderir.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: web-policy
spec:
podSelector:
matchLabels:
role: web
policyTypes:
- Egress
egress:
- to:
- podSelector:
matchLabels:
name: api-pod
- namespaceSelector:
matchLabels:
name: dev
ports:
- protocol: TCP
port: 5000
Örnek - To Belirtilmemiş
Bu yanlış çünkü
to kısmı
belirtilmemiş. Dolayısıyla 80 numaralı port olmak kaydıyla her türlü adrese erişim
verir.
# This is bad, because it allows connections to anything listening
# on port 80
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-cronjob-to-examplecom
namespace: my-ns
spec:
podSelector:
matchLabels:
app.kubernetes.io/component: cronjob
policyTypes:
- Egress
egress:
- ports:
- protocol: TCP
port: 80
3. Ingress ve Egress
Şöyle
yaparız. App Server, 5000 numaralı porta bağlantı kabul eder ve DB Server'ın 3306 numaralı portuna gönderir.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: api-policy
spec:
podSelector:
matchLabels:
role: api
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
name: web-pod
namespaceSelector:
matchLabels:
name: dev
ports:
- protocol: TCP
port: 5000
egress:
- to:
- podSelector:
matchLabels:
name: db-pod
- namespaceSelector:
matchLabels:
name: dev
ports:
- protocol: TCP
port: 3306
Şöyle
yaparız. DB Server, 3306 numaralı portuna sadece App Server'dan bağlantıyı kabul eder ve DB belirli bir
IP bloğuna gönderir.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: db-policy
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
name: api-pod
namespaceSelector:
matchLabels:
name: dev
- ipBlock:
cidr: 192.168.5.10/32
ports:
- protocol: TCP
port: 3306
egress:
- to:
- ipBlock:
cidr: 192.168.5.10/32
ports:
- protocol: TCP
port: 80