前面介紹 Service 時提過,Pod 可以透過 Service 與其他 Pod 進行連線。但如果希望限制哪些 Pod 可以互相連線,就需要額外設定網路存取規則。
Kubernetes 提供 NetworkPolicy,可以用來控制 Pod 的網路流量,例如限制哪些 Pod 可以連線進來,或限制 Pod 可以連線到哪些地方。
NetworkPolicy 主要可以控制兩種流量:
這裡的 Ingress 指的是「進入 Pod 的流量方向」,和前面 DAY14 介紹的 Kubernetes Ingress 資源並不是同一個東西。
NetworkPolicy 會透過 Label Selector 選擇要套用規則的 Pod。
例如:
podSelector:
matchLabels:
app: backend
代表這個 NetworkPolicy 會套用到具有:
app=backend
Label 的 Pod。
如果 Namespace 中有:
frontend
backend
database
三種 Pod,就可以利用 NetworkPolicy 設定:
frontend → backend 允許
database → backend 拒絕
讓 backend 只接受指定 Pod 的連線。
先建立兩個 Pod:
apiVersion: v1
kind: Pod
metadata:
name: nginx-demo
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
---
apiVersion: v1
kind: Pod
metadata:
name: client-demo
labels:
app: client
spec:
containers:
- name: client
image: busybox:1.36
command: ["sleep", "3600"]
再替 nginx 建立 Service:
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
套用之後,可以從 client-demo 測試連線:
kubectl exec client-demo -- wget -qO- http://nginx-service
正常情況下應該可以取得 nginx 的網頁內容。
接著建立 NetworkPolicy:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: nginx-policy
spec:
podSelector:
matchLabels:
app: nginx
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
access: allowed
這個 NetworkPolicy 會選擇app=nginx的 Pod。
並且只允許具有access=allowed Label 的 Pod 對它建立 Ingress 連線。
目前 client-demo 的 Label 是:
app=client
並沒有:
access=allowed
因此它不符合 NetworkPolicy 中設定的條件。
可以再次測試:
kubectl exec client-demo -- wget -T 3 -qO- http://nginx-service
如果目前使用的 Kubernetes 網路環境有支援 NetworkPolicy,這次連線就會被阻擋。
接著替 client-demo 加上access=allowedLabel
kubectl label pod client-demo access=allowed
可以查看 Label:
kubectl get pods --show-labels
這時 client-demo 就具有:
app=client
access=allowed
再次執行:
kubectl exec client-demo -- wget -T 3 -qO- http://nginx-service
因為現在符合 NetworkPolicy 的條件,因此就可以連線到 nginx。
整個關係可以簡單理解成:
client-demo
access=allowed
│
│ 允許
▼
nginx-demo
app=nginx
NetworkPolicy 選擇 app=nginx 的 Pod,再決定哪些來源可以連線到它。
除了控制進入 Pod 的流量,也可以使用 Egress 控制 Pod 主動向外建立的連線。
例如:
policyTypes:
- Egress
代表這個 NetworkPolicy 要管理 Pod 的 Egress 流量。
因此可以簡單理解:
Ingress
Client ──────→ Pod
Egress
Pod ──────→ Other Pod / Network
實際設定 Egress 時,還需要考慮 DNS 等必要流量,因此這裡先了解它的用途即可。
NetworkPolicy 本身只是 Kubernetes 中用來描述網路規則的資源,實際限制流量還需要底層的網路元件支援 NetworkPolicy。
因此建立 NetworkPolicy 後,如果發現 Pod 之間的流量完全沒有受到限制,不一定代表 YAML 寫錯,也可能是目前使用的網路環境沒有實際執行這些規則。
在 Minikube 中進行實作前,也應先確認目前使用的網路環境是否支援 NetworkPolicy。
NetworkPolicy 可以限制 Pod 之間的網路流量,主要分成:
Ingress → 控制哪些流量可以進入 Pod
Egress → 控制 Pod 可以向外送出哪些流量
NetworkPolicy 會透過 podSelector 選擇需要套用規則的 Pod,再設定允許的流量來源或目的地。
因此除了前面介紹過的 Service、Ingress 等網路資源之外,NetworkPolicy 可以進一步限制 Pod 之間的連線,避免所有 Pod 都可以任意互相存取。