Kubernetes 預設會以一般網路運作,其中所有 Pod 都可以彼此自由通訊。 這種不受限制的連線對於開發人員來說相當方便,但隨著應用程式調整而造成重大安全性風險。 假設組織部署多個微服務,每個微服務都會處理敏感數據、客戶交易或後端作業。 沒有任何限制,任何遭入侵的 Pod 都可能會存取未經授權的數據或中斷服務。
為了解決這些安全性考慮, Kubernetes 中的網路 原則可讓系統管理員控制及限制工作負載之間的流量。 它們提供宣告式方法來強制執行流量規則,確保叢集內的安全和控制網路行為。
什麼是 Kubernetes 網路原則?
Kubernetes 中的網路原則是一組規則,可控制 Pod 如何彼此通訊,以及與外部服務通訊。 其可針對網路流量提供更細緻的控制,讓系統管理員能夠在命名空間層級強制執行安全性和分割。 藉由實作網路原則,您可以取得:
- 更強的安全性狀態:防止叢集內未經授權的橫向移動。
- 合規性和治理:藉由控制通訊路徑來強制執行法規需求。
- 減少爆破半徑:藉由限制其網路存取,限制遭入侵工作負載的影響。
一開始,網路原則的設計目的是在 OSI 模型的第 3 層 (IP) 和第 4 層 (TCP/UDP) 上運作,以基本控制 Pod 對 Pod 和外部通訊。 不過,Cilium 等進階網路原則引擎已將網路原則延伸至第 7 層(應用層),以更深入地控制新式雲端原生應用程式的應用程式流量。
網路原則是在命名空間層級定義,這表示每個原則都會套用至特定命名空間內的工作負載。 網路原則的主要元件包括:
- Pod 選取器:定義原則會根據標籤套用至哪些 Pod。
- 輸入規則:指定允許的連入連線。
- 輸出規則:指定允許的連出連線。
- 原則類型:定義原則是否適用於輸入(傳入)、輸出(傳出)或兩者。
建立有效網路原則的基礎
在 Kubernetes 中建置有效的網路原則不只是撰寫 YAML 設定,它需要深入瞭解您的應用程式架構、流量模式和安全性需求。 如果沒有清楚瞭解工作負載的通訊方式,強制執行安全策略可能會導致非預期的中斷或保護缺口。 下列各節將說明如何有系統地處理網路原則設計。
了解您的工作負載連線
實作網路原則之前,您需要了解工作負載如何彼此通訊以及與外部服務通訊。 此步驟可確保原則不會不小心封鎖重要流量,同時有效限制不必要的暴露。
運用可見度工具:除了應用程式小組所提供的網路要求之外,您還可以使用 Cilium Hubble 和 Retina,協助您分析 Pod 之間的流量,找出需要通訊的服務,並定義其輸入和輸出相依性。 例如,前端可能需要連線到後端 API,但不應該直接與資料庫交談。 識別哪些服務需要通訊並定義其輸入和輸出相依性。 例如,前端可能需要連線到後端 API,但不應該直接與資料庫交談。
網路原則中標籤的重要性: 傳統上,網路安全策略依賴靜態IP位址來定義流量規則。 這種方法在 Kubernetes 中是有問題的,因為 Pod 是暫時的,經常會以動態指派的 IP 位址建立和終結。 根據不斷變更的IP維護安全性規則需要持續更新,讓原則管理效率低下且容易發生錯誤。
標籤透過提供穩定的方式來將工作負載分組,以解決這項挑戰。 Kubernetes 網路原則並不依賴固定 IP,而是使用標籤來定義安全性規則,即使 Pod 在重新啟動或跨節點移動時,這些規則仍能保持一致性。 例如,原則可以允許標籤 app: frontend
和 app: backend
的 Pods 之間的通訊,確保不論 Pod IP 改變時,流量都會如預期般流動。 這個以標籤為基礎的方法對於在雲端原生環境中實現可調整且意圖導向的網路安全性至關重要。
定義完善的標籤策略可簡化原則管理、減少設定錯誤,以及增強叢集間的安全性強制執行。
- 定義微分割: 將工作負載組織到安全性區域(例如前端、後端、資料庫)有助於強制執行最低許可權原則。 例如,處理客戶交易的微服務應該與一般用途應用程式隔離。
Kubernetes 的分層安全性方法
完全依賴基本 Kubernetes 網路原則可能不足以滿足所有安全性需求。 分層方法可確保跨不同層級的網路通訊進行全面保護。
- (L3/L4) 原則:網路安全性的基礎,根據 IP、連接埠和通訊協定層級的 Pod 標籤和命名空間來控制流量。
- FQDN 型原則:限制輸出流量到特定的外部網域,確保工作負載只能連線到已核准的外部服務(例如:只允許存取 API 呼叫 microsoft.com )。
- 第 7 層原則:藉由根據 HTTP 方法、標頭和路徑篩選要求,引進對流量的精細控制。 這適用於保護 API 並強制執行應用層安全策略。
管理網路原則
誰應該管理網路原則? 這通常取決於組織的結構和安全性需求。 平衡良好的方法可讓安全性小組和應用程式開發人員有效地共同作業。
- 集中式安全性管理:安全性或網路小組應定義基準原則,以強制執行全域安全性需求,例如預設拒絕所有規則或合規性導向的限制。
- 具有護欄的開發人員自主性:應用程式小組應該能夠在其命名空間內定義服務特定的網路原則,同時啟用安全性,同時維持靈活度。
- 原則生命週期管理:定期檢閱和更新原則可確保安全性與不斷演進的應用程式架構保持一致。 可檢視性工具可協助偵測原則設定錯誤和遺漏規則。
範例:使用網路原則保護多層式 Web 應用程式
步驟 1:瞭解工作負載連線能力
- 可見度工具:使用 Cilium Hubble 觀察 Pod 的通訊方式。
連線對應圖
來源 目的地 協定 港口 前端 後端 TCP 8080 後端 資料庫 TCP 5432 後端 外部付款閘道 TCP 443
步驟 2:為強制執行政策套用標籤
藉由正確標記工作負載,即使 Pod IP 變更,原則仍可保持穩定。
app: frontend
:適用於 UI Pod。app: backend
:適用於 API Pod。app: database
:適用於 DB Pod。
步驟 3:實作應用層級網路原則
在此範例中,我們使用兩層網路原則:L3/L4 基本原則來控制微服務與完整域名 (FQDN) 原則之間的流量,以使用外部付款網關控制輸出流量。
允許前端與後端通訊 | 允許後端存取資料庫 | 允許後端連線到外部付款 API |
---|---|---|
原則 1:前端輸出to: - podSelector: matchLabels: app: backend ports: - protocol: TCP port: 8080 原則 2:後端輸入 from: - podSelector: matchLabels: app: frontend ports: - protocol: TCP port: 8080 |
原則 1:後端輸出to: - podSelector: matchLabels: app: database ports: - protocol: TCP port: 5432 原則 2:資料庫輸入 from: - podSelector: matchLabels: app: backend ports: - protocol: TCP port: 5432 |
原則 1:後端spec: endpointSelector: matchLabels: app: backend egress: - toFQDNs: - matchName: payments.example.com ports: - protocol: TCP port: 443 |
步驟 4:管理和維護原則
安全性和平台小組會強制執行基準拒絕規則。
基準原則 平台原則 安全 - 預設拒絕所有流量 - 允許 DNS
- 允許記錄- 封鎖流量
已知
惡意IP
和網域確保應用程式的網路原則符合平臺和安全性需求,同時避免任何原則違規。
基線 平台原則 安全策略 允許前端與後端通訊 允許後端存取資料庫 允許後端連線到外部付款 API - 預設拒絕所有流量 - 允許 DNS
- 允許記錄- 封鎖對已知惡意IP和網域的流量 原則 1:前端出口:
- to:
- podSelector:
matchLabels:
應用程式:後端
港口:
- 協定: TCP
埠:8080
原則 2:後端輸入:
- from:
- podSelector:
matchLabels:
應用程式:前端
港口:
- 協定: TCP
埠:8080原則 1:後端出口:
- to:
- podSelector:
matchLabels:
app: database
港口:
- 協定: TCP
埠:5432
原則 2:資料庫輸入:
- from:
- podSelector:
matchLabels:
應用程式:後端
港口:
- 協定: TCP
埠:5432政策 1:後端
spec:
endpointSelector:
matchLabels:
應用程式:後端
出口:
- toFQDNs:
- matchName: payments.example.com
港口:
- 協定: TCP
埠:443這種結構化方法可確保安全性,而不會中斷應用程式功能。
由 Cilium 驅動的 Azure
由 Cilium 提供的 Azure 容器網路介面 (CNI) 利用 eBPF(擴充 Berkeley 封包篩選器)來為 Kubernetes 工作負載提供高效能的網路、可觀察性和安全性。 不同於依賴基於 iptables 的封包過濾的傳統 CNI,由 Cilium 推動的 Azure CNI 使用 eBPF 在內核層級運作,以有效和可擴展的方式執行網路原則。 在 Azure Kubernetes Service (AKS)上,Cilium 是唯一支援的網路原則引擎,反映了 Azure 對效能、延展性和安全性的投資。 Azure Kubernetes Service 會將 Cilium 整合為受控元件,以簡化網路安全性強制執行。 系統管理員可以直接在 AKS 叢集中定義 Cilium 網路原則,而不需要外部控制器。
Cilium 會使用身分識別來擴充標籤的使用方式。 具有許多 Pod 的大型叢集可能會在高 Pod 變動率下遇到持續更新 IP 篩選器的擴展問題。 在背後的機制中,身分識別會映射到標籤,並允許在身分識別解析後立即發起連線,這樣就不需要更新節點上的規則。
使用由 Cilium 提供的 Azure CNI,您不需要安裝個別的網路原則引擎,例如 Azure 網路原則管理員或 Calico。
使用下列命令建立由 cilium 提供的 Azure CNI 叢集
az aks create \
--name <clusterName> \
--resource-group <resourceGroupName> \
--location <location> \
--network-plugin azure \
--network-plugin-mode overlay \
--pod-cidr 192.168.0.0/16 \
--network-dataplane cilium \
--generate-ssh-keys
Cilium 網路原則的結構
透過由 Cilium 提供的 Azure CNI,您可以使用兩種可用的格式,以原生方式在 Kubernetes 中設定網路原則:
- 標準
NetworkPolicy
資源,在 Pod 輸入或輸出時可支援 L3 和 L4 原則。 - 擴充
CiliumNetworkPolicy
格式,可做為 CustomResourceDefinition,針對輸入和輸出支援第 3 層到第 7 層的原則規格。
透過這些 CRD,我們可以定義安全策略,Kubernetes 會自動將這些原則散發到叢集中的所有節點。
網路原則包含數個主要元件:
Pod 選取器:指定原則會透過標籤套用至哪些 Pod。
原則類型:判斷原則是否適用於輸入(連入流量)、輸出(連出流量)或兩者。
輸入規則:定義允許的來源(Pod、命名空間或IP範圍)和埠。
輸出規則:定義允許的目的地和埠。
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: frontend-egress namespace: default spec: podSelector: matchLabels: app: frontend policyTypes: - Egress egress: - to: - podSelector: matchLabels: app: backend ports: - protocol: TCP port: 8080
進階網路原則
Azure Kubernetes 服務提供 進階容器網路服務 (ACNS) 一套服務,旨在增強 AKS 叢集的網路功能。
ACNS 的主要功能是容器網路安全性,其提供進階安全性功能來保護容器化工作負載。 其中一個值得注意的方面是實作進階網路原則的能力,包括完整功能變數名稱 (FQDN) 篩選和第 7 層 (L7) 原則,允許更細微地控制輸出流量和應用層通訊。
使用 FQDN 篩選保護輸出流量
傳統上,Kubernetes 中的網路原則是以IP位址為基礎。 不過,在 Pod IP 經常變更的動態環境中,管理這類原則變得繁瑣。 FQDN 篩選 可藉由允許使用功能變數名稱而非IP位址來定義原則,來簡化此動作。 此方法提供更直覺且方便使用者控制網路流量的方法,讓組織能夠以更高的精確度和彈性強制執行安全策略。
在 AKS 叢集中實作 FQDN 篩選需要啟用 ACNS 並設定必要的原則來定義允許或封鎖的網域,進而增強容器化應用程式的安全性狀態。
若要在 Azure Kubernetes Service 中啟用進階容器網路服務 (ACNS),請使用 旗標 --enable-acns
範例:在現有叢集上啟用進階容器網路服務
az aks update \
--resource-group $RESOURCE_GROUP \
--name $CLUSTER_NAME \
--enable-acns
#### Example: Build a network policy that allows traffic to “bing.com”
```yaml
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
name: "allow-bing-fqdn"
spec:
endpointSelector:
matchLabels:
app: demo-container
egress:
- toEndpoints:
- matchLabels:
"k8s:io.kubernetes.pod.namespace": kube-system
"k8s:k8s-app": kube-dns
toPorts:
- ports:
- port: "53"
protocol: ANY
rules:
dns:
- matchPattern: "*.bing.com"
- toFQDNs:
- matchPattern: "*.bing.com"
使用 L7 原則保護 API 的安全性
由於新式應用程式越來越依賴 API 進行通訊,因此僅保護網路層的這些互動就不再足夠了。 標準網路原則會在第 3 層 (IP) 和第 4 層 (TCP/UDP) 上運作,控制哪些 Pod 可以通訊,但無法查看實際 API 要求。
第 7 層 (L7) 原則提供下列優點和功能:
- 細微 API 安全性:根據 HTTP、gRPC 或 Kafka 要求資料強制執行原則,而不只是 IP 位址和連接埠。
- 降低攻擊面:藉由篩選應用層的流量,防止未經授權的存取並減輕API型攻擊。
- 合規性和稽核:藉由記錄和控制特定的 API 互動,確保遵循安全性標準。
- 簡化原則管理:運用 Cilium 支援的內建 L7 控制項,避免因額外的側車 Proxy 而造成作業負擔。
L7 原則 AKS 是透過 ACNS 啟用,且可供使用由 Cilium 提供之 Azure CNI 的客戶使用。 這些原則支援 HTTP、gRPC 和 Kafka 通訊協定。
為了強制執行 L7 原則,客戶會定義 CiliumNetworkPolicy
資源,並指定應用層流量控制的規則。
範例:在現有叢集上啟用 ACNS
az aks update \
--resource-group $RESOURCE_GROUP \
--name $CLUSTER_NAME \
--enable-acns
#### Example: Allow only GET requests to /api from the frontend pod to the backend service on port 8080
```yaml
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
name: frontend-l7-policy
namespace: default
spec:
endpointSelector:
matchLabels:
app: frontend
egress:
- toEndpoints:
- matchLabels:
app: backend
toPorts:
- ports:
- port: "8080"
protocol: TCP
rules:
http:
- method: "GET"
path: "/api"
網路政策的策略
保護 Kubernetes 工作負載需要有深思熟慮的方法,才能定義及強制執行網路原則。 設計良好的策略可確保應用程式只如預期般通訊,降低未經授權的存取、橫向移動和潛在缺口的風險。 下列各節涵蓋實作有效 Kubernetes 網路原則的重要策略。
採用 Zero-Trust 模型
根據預設,Kubernetes 允許叢集中所有 Pod 之間的不受限制通訊。 Zero-Trust 方法規定預設不應信任任何流量,而且只允許明確允許的通訊路徑。 實作預設的拒絕所有網路原則可確保只有必要的流量會在工作負載之間流動。
拒絕全部策略的範例:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
namespace: default
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
### Namespace and multi-tenancy segmentation
In multi-tenant environments, namespaces help isolate workloads. Different teams typically manage their applications within dedicated namespaces, ensuring logical isolation between workloads. This separation is critical when multiple applications run alongside each other. Applying network policies at the namespace scope is often the first step in securing workloads, as it prevents unrestricted lateral movement between applications managed by different teams.
For example, restrict all ingress traffic to a namespace, allowing only traffic from the same namespace:
```yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: restrict-cross-namespace
namespace: team-a
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: team-a
### Microsegmentation for workload isolation
While namespace-based segmentation is an essential first step in securing multi-tenant Kubernetes clusters, application-level microsegmentation provides fine-grained control over how workloads interact within a namespace. Namespace isolation alone does not prevent unintended or unauthorized communication between different applications within the same namespace. This is where pod-level segmentation becomes critical.
For instance, if a frontend service should only talk to a backend service within the same namespace, a policy using pod labels can enforce this restriction:
```yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: frontend-to-backend
namespace: team-a
spec:
podSelector:
matchLabels:
app: frontend
policyTypes:
- Egress
egress:
- to:
- podSelector:
matchLabels:
app: backend
ports:
- protocol: TCP
port: 8080
This prevents frontend pods from making unintended connections to other services, reducing the risk of unauthorized access or lateral movement inside the namespace.
By combining namespace-wide isolation with fine-grained application-level policies, teams can implement a multi-layered security model that prevents unauthorized traffic while allowing necessary communication for application functionality.
### Layered security approach
Network security should be implemented in layers, combining multiple levels of enforcement:
- **L3/L4 policies**: Restrict traffic at the IP and port level (for example: allow TCP traffic on port 443).
- **FQDN-based filtering**: Restrict external communication based on domain names rather than IP addresses.
- **L7 policies**: Control communication based on application-layer attributes (for example: allow only HTTP GET requests to specific API paths).
For example, a Cilium L7 policy can restrict frontend services to only issue GET requests to the backend API:
```yaml
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
name: frontend-l7-policy
namespace: default
spec:
endpointSelector:
matchLabels:
app: frontend
egress:
- toEndpoints:
- matchLabels:
app: backend
toPorts:
- ports:
- port: "8080"
protocol: TCP
rules:
http:
- method: "GET"
path: "/api"
This prevents the frontend from making POST or DELETE requests, limiting the attack surface.
### Integrating RBAC with Network Policy management
Role-based access control (RBAC) plays a crucial role in ensuring that only authorized users or teams can create, modify, or delete network policies. Without proper access controls, a misconfigured policy could either expose workloads to unauthorized access or unintentionally block critical application traffic.
By leveraging Kubernetes RBAC in conjunction with network policies, organizations can enforce separation of duties between platform administrators, security teams, and application developers. A typical approach is:
- Platform or security teams define baseline security policies that enforce compliance and restrict external access.
- Application teams are granted limited permissions to create or update network policies only for their respective namespaces.
For example, the following RBAC policy allows developers to create and modify network policies but only within their assigned namespace:
```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: network-policy-editor
namespace: team-a
rules:
- apiGroups: ["networking.k8s.io"]
resources: ["networkpolicies"]
verbs: ["get", "list", "create", "update", "delete"]
此角色接著可以使用 RoleBinding 系結至特定小組:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: team-a-network-policy-binding
namespace: team-a
subjects:
- kind: User
name: developer@example.com
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: network-policy-editor
apiGroup: rbac.authorization.k8s.io
藉由將網路原則修改限制為指定的小組和命名空間,組織可以防止意外設定錯誤或未經授權的變更,同時仍允許開發人員實作應用程式特定安全策略的彈性。
這種方法強化最低許可權原則,同時確保網路分割策略保持一致、安全且符合組織原則。
舊版和第三方解決方案
Azure 網路原則管理員 (NPM)
Azure 網路原則管理員 (NPM) 是舊版解決方案,可用於在 AKS 上強制執行 Kubernetes 網路原則。 隨著我們持續演進網路堆疊,我們打算很快淘汰 NPM。
我們強烈建議所有客戶轉換至 Cilium 網路原則,透過 eBPF 型強制執行提供更好的效能、延展性和增強安全性。 Cilium 是 AKS 中網路原則的未來,並提供更具彈性且功能豐富的 NPM 替代方案。
Windows 節點的 NetworkPolicy 支援
AKS 無法直接以原生方式針對 Windows 節點支援 Kubernetes NetworkPolicy。 若要啟用 Windows 工作負載的網路原則,您可以使用 Calico for Windows 節點,此節點已整合至 AKS 以簡化部署。 您可以在建立叢集時使用 --network-policy calico
旗標加以啟用。
Microsoft不會維護此整合中使用的 Calico 影像。 我們的支援僅限於確保 Calico 與 AKS 正確整合,並在平臺內如預期般運作。 任何有關 Calico 上游錯誤的問題、功能要求問題,或超出 AKS 整合範圍的疑難排解問題,均應轉至 Calico 開放原始碼社群,或洽詢 Calico 維護者 Tigera。
Calico 開放原始碼 – 第三方解決方案
Calico 開放原始碼是廣泛使用的第三方解決方案,可用來強制執行 Kubernetes 網路原則。 它同時支援Linux和 Windows節點,並提供進階的網路和安全性功能,包括網路原則強制執行、工作負載身分識別和加密。
Calico 雖然與 AKS for Windows 網路原則整合--network-policy calico
,但仍然是由 Tigera 維護的開放原始碼專案。 Microsoft不會維護 Calico 影像,並提供有限的支援,著重於確保與 AKS 的適當整合。 如需 AKS 整合以外的進階疑難解答、功能要求或問題,建議您連絡 Calico 開放原始碼社群或 Tigera。
針對Linux節點,我們強烈建議使用 Cilium 來強制執行網路原則。 針對 Windows 節點,我們建議使用 Calico。
結論
網路原則是 Kubernetes 安全性的基本部分,可讓組織控制流量、強制執行工作負載隔離,並減少受攻擊面。 隨著雲端原生環境的發展,只依賴基本第 3/4 層原則已不再足夠。 進階解決方案,例如第 7 層篩選和 FQDN 型原則,可提供保護新式應用程式所需的細微安全性和彈性。
遵循最佳做法,包括零信任模型、微分類,以及採用 Azure 受控 Cilium 小組等可調整的解決方案,可以增強安全性,同時維持營運效率。 隨著 Kubernetes 網路功能持續演進,採用現代化、可觀察性導向的方法,是有效保護工作負載的關鍵。