在 Kubernetes 中,NetworkPolicy 是一種資源對象,用于定義 Pod 之間的網絡通信策略。它允許你控制哪些 Pod 可以相互通信,以及如何通信。通過使用 NetworkPolicy,可以實現更細粒度的網絡訪問控制,增強集群的安全性。
1.NetworkPolicy 的作用
NetworkPolicy 主要用于以下場景:
限制 Pod 之間的通信:指定哪些 Pod 可以相互通信,哪些不能通信。
控制入站和出站流量:定義哪些流量可以進入 Pod,哪些流量可以從 Pod 發出。
基于標簽的策略:通過 Pod 的標簽選擇器來定義策略,使得策略的管理更加靈活。
2.NetworkPolicy 的工作原理
NetworkPolicy 本身并不直接實現網絡策略,而是依賴于支持網絡策略的網絡插件(如 Calico、Cilium、Weave 等)。這些插件會根據 NetworkPolicy 的定義,動態地配置網絡規則,從而實現流量的控制。
3.NetworkPolicy 的基本配置
NetworkPolicy 的配置文件是一個 YAML 文件,定義了策略的規則。以下是一個簡單的例子:
apiVersion: networking.k8s.io/v1 # 指定API版本
kind: NetworkPolicy # 指定資源類型為 NetworkPolicy。
metadata: # 定義了策略的名稱和命名空間。name: allow-specific-podsnamespace: default
spec:podSelector: # 定義了哪些 Pod 受此策略影響。在這個例子中,所有帶有 role: frontend 標簽的 Pod 會受到此策略的限制。matchLabels:role: frontendpolicyTypes: # 定義了策略的類型,可以是 Ingress(入站流量)、Egress(出站流量)或兩者。- Ingress- Egressingress: # 定義了允許進入 Pod 的流量規則。在這個例子中,只有帶有 role: backend 標簽的 Pod 可以向帶有 role: frontend 標簽的 Pod 發送流量。- from:- podSelector:matchLabels:role: backendegress: # 定義了允許從 Pod 發出的流量規則。在這個例子中,帶有 role: frontend 標簽的 Pod 只能向帶有 role: backend 標簽的 Pod 發送流量。- to:- podSelector:matchLabels:role: backend
4.NetworkPolicy 的主要字段
podSelector:選擇受此策略影響的 Pod。如果沒有指定,則默認選擇命名空間中的所有 Pod。
policyTypes:定義策略的類型,可以是 Ingress、Egress 或兩者。
ingress:定義入站流量的規則。
from:定義允許流量的來源。
podSelector:基于 Pod 的標簽選擇器。
namespaceSelector:基于命名空間的標簽選擇器。
ipBlock:基于 IP 范圍。
egress:定義出站流量的規則。
to:定義允許流量的目的地。
podSelector:基于 Pod 的標簽選擇器。
namespaceSelector:基于命名空間的標簽選擇器。
ipBlock:基于 IP 范圍。
ports:定義允許的端口和協議。如果沒有指定,則默認允許所有端口。
5.示例 限制 Pod 之間的通信
假設我們有兩個服務:
frontend:運行前端應用,帶有標簽 role: frontend。
backend:運行后端應用,帶有標簽 role: backend。
我們希望:
frontend 只能從 backend 接收流量。
frontend 只能向 backend 發送流量。
創建 Pod
apiVersion: v1
kind: Pod
metadata:name: frontendlabels:role: frontend
spec:containers:- name: frontendimage: my-frontend-image
---
apiVersion: v1
kind: Pod
metadata:name: backendlabels:role: backend
spec:containers:- name: backendimage: my-backend-image
創建 NetworkPolicy
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:name: allow-specific-podsnamespace: default
spec:podSelector:matchLabels:role: frontendpolicyTypes:- Ingress- Egressingress:- from:- podSelector:matchLabels:role: backendegress:- to:- podSelector:matchLabels:role: backend
6.注意事項
默認策略:如果沒有定義任何 NetworkPolicy,則默認允許所有 Pod 之間的通信。
網絡插件支持:NetworkPolicy 的實現依賴于網絡插件。確保你的 Kubernetes 集群使用了支持 NetworkPolicy 的網絡插件(如 Calico、Cilium 等)。
命名空間隔離:NetworkPolicy 僅在定義它的命名空間內生效。如果需要跨命名空間的策略,需要使用 namespaceSelector。
7.示例:限制外部流量
假設我們希望限制外部流量只能訪問特定的 Pod,可以使用以下 NetworkPolicy:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:name: allow-external-trafficnamespace: default
spec:podSelector:matchLabels:role: frontendpolicyTypes:- Ingressingress:- from:- ipBlock:cidr: 192.168.0.0/16
在這個例子中,只有來自 192.168.0.0/16 網段的外部流量可以訪問帶有 role: frontend 標簽的 Pod。
8.示例:限制特定端口
假設我們希望限制 Pod 只能通過特定端口通信,可以使用以下 NetworkPolicy:
apiVersion: networking.k8s.io/v1 # 指定了 Kubernetes API 的版本
kind: NetworkPolicy # :指定了資源類型
metadata:name: allow-specific-ports # 定義了這個網絡策略的名稱namespace: default # 定義了這個網絡策略所在的命名空間
spec:podSelector: # 定義了哪些 Pod 受此策略影響matchLabels:role: frontendpolicyTypes: # :定義了策略的類型- Ingress- Egressingress: # 定義了入站流量的規則。- from: # 定義了允許流量的來源。- podSelector: # 指定了流量來源的 Pod。這里通過 matchLabels 指定了帶有 role: backend 標簽的 Pod。matchLabels:role: backendports: # 定義了允許的端口和協議。- protocol: TCP # 指定了協議類型,這里是 TCP。port: 80 # 指定了端口號,這里是 80。# 解釋:這個規則表示:只有帶有 role: backend 標簽的 Pod 可以通過 TCP 端口 80 向帶有 role: frontend 標簽的 Pod 發送流量。egress: # 定義了出站流量的規則。- to: # 定義了允許流量的目的地。- podSelector: # 指定了流量目的地的 Pod。這里通過 matchLabels 指定了帶有 role: backend 標簽的 Pod。matchLabels:role: backendports: # 定義了允許的端口和協議。- protocol: TCP # 指定了協議類型,這里是 TCP。port: 80 # 指定了端口號,這里是 80。
# 這個規則表示:帶有 role: frontend 標簽的 Pod 只能通過 TCP 端口 80 向帶有 role: backend 標簽的 Pod 發送流量。
在這個例子中,帶有 role: frontend 標簽的 Pod 只能通過 TCP 端口 80 與帶有 role: backend 標簽的 Pod 通信。
總結
NetworkPolicy 是 Kubernetes 中用于控制 Pod 之間網絡通信的強大工具。通過合理配置 NetworkPolicy,可以實現細粒度的網絡訪問控制,增強集群的安全性。