在 AKS 中使用網路原則保護 Pod 之間的流量
在 Kubernetes 中執行現代微服務型應用程式時,最好要能控制能與彼此通訊的元件。 最低權限準則應套用至 Azure Kubernetes Service (AKS) 叢集中 Pod 間流量的流動方式。 假設您想要封鎖直接流向後端應用程式的流量。 Kubernetes 中的網路原則功能可讓您針對叢集中 Pod 之間的輸入和輸出流量定義規則。
本文示範如何安裝網路原則引擎,並建立 Kubernetes 網路原則來控制 AKS 中 Pod 之間的流量流程。 網路原則可用於 AKS 中的 Linux 型或 Windows 型節點和 Pod。
網路原則概觀
根據預設,AKS 叢集中的所有 Pod 都可以無限制地傳送及接收流量。 為了提升安全性,您可以定義可控制流量流程的規則。 例如,後端應用程式通常只會對必要的前端服務公開。 或者,只有連線到資料庫元件的應用層才能存取它們。
網路原則是一種 Kubernetes 規格,其定義 Pod 之間通訊的存取原則。 當您使用網路原則時,您可以定義一組已排序的規則來傳送及接收流量。 您可以將規則套用至符合一或多個標籤選取器的 Pod 集合。
網路原則規則會定義為 YAML 資訊清單。 網路原則可納入更廣泛的資訊清單中,而該清單也會建立部署或服務。
AKS 中的網路原則選項
Azure 提供三個網路原則引擎來強制執行網路原則:
- 使用由 Cilium 提供的 Azure CNI 的 AKS 叢集 Cilium。
- Azure Network Policy Manager。
- Calico 是 Tigera 創建的開放原始碼網路和網路安全性解決方案。
Cilium 是我們建議的網路原則引擎。 Cilium 會使用 Linux Berkeley Packet Filter (BPF) 在流量上強制執行網路原則,這通常比 "IPTables" 更有效率。 如需詳細資訊,請參閱由 Cilium 提供的 Azure CNI 文件。
若要強制執行指定的原則,適用於 Linux 的 Azure 網路原則管理員會使用 Linux IPTables。 適用於 Windows 的 Azure 網路原則管理員會使用主機網路服務 (HNS) ACLPolicies。 這些原則會轉譯成一組允許和不允許的 IP 配對。 接著,這些配對會透過程式設計為 IPTable
或 HNS ACLPolicy
篩選規則。
網路原則引擎之間的差異:Cilium、Azure NPM 和 Calico
功能 | Azure Network Policy Manager | Calico | Cilium |
---|---|---|---|
支援的平台 | Linux、Windows Server 2022 (預覽)。 | Linux、Windows Server 2019 及 2022。 | Linux。 |
支援的網路功能選項 | Azure 容器網路介面 (CNI)。 | Azure CNI (Linux、Windows Server 2019 和 2022) 和 kubenet (Linux)。 | Azure CNI。 |
符合 Kubernetes 規格 | 支援所有原則類型 | 支援所有原則類型。 | 支援所有原則類型。 |
其他功能 | 無。 | 由全域網路原則、全域網路集和主機端點組成的延伸原則模型。 如需使用 calicoctl CLI 管理這些擴充功能的詳細資訊,請參閱 calicoctl 使用者參考。 |
無。 |
支援 | 受到 Azure 支援和工程團隊支援。 | 受到 Azure 支援和工程團隊支援。 | 受到 Azure 支援和工程團隊支援。 |
Azure 網路原則管理員的限制
注意
使用適用於Linux的 Azure NPM,我們不允許調整超過 250個節點 和 20,000個Pod。 如果您嘗試調整超過這些限制,可能會遇到 記憶體不足 (OOM) 錯誤。 為了獲得更佳的延展性和 IPv6 支援,如果有下列限制,建議您使用或升級至 由 Cilium 提供的 Azure CNI,以使用 Cilium 作為網路原則引擎。
Azure NPM 不支援 IPv6。 否則,它完全支援 Linux 中的網路原則規格。
在 Windows 中,Azure NPM 不支援網路原則規格的下列功能:
- 具名連接埠。
- 串流控制傳輸通訊協定 (SCTP)。
- 負比對標籤或命名空間選取器。 例如,除了 以外的
debug=true
所有標籤。 except
無類別的網域間路由 (CIDR) 區塊 (CIDR 除外)。
注意
如果建立不支援的網路原則,Azure 網路原則管理員 Pod 會記錄錯誤。
編輯/刪除網路原則
在某些罕見的情況下,在編輯或刪除「夠大」的網路原則時,可能會發生暫時、非預期的連線,讓任何受影響節點上的新連線與 Pod 產生暫時、非預期的連線。 達到此競爭條件永遠不會影響作用中的連線。
如果節點發生此競爭狀況,該節點上的 Azure NPM Pod 會進入無法更新安全性規則的狀態,這可能會導致受影響節點上新連線與 Pod 之間的非預期連線。 為了減輕此問題,Azure NPM Pod 會在進入此狀態后自動重新啟動約 15 秒。 當 Azure NPM 在受影響的節點上重新啟動時,它會刪除所有安全性規則,然後重新套用所有網路原則的安全性規則。 雖然正在重新套用所有安全性規則,但有可能讓受影響節點上的新連線與 Pod 之間的新連線暫時、非預期的連線。
若要限制達到此競爭條件的機會,您可以減少網路原則的大小。 此問題最有可能發生在具有數 ipBlock
個區段的網路原則。 具有四個或更少ipBlock
區段的網路原則不太可能遇到問題。
開始之前
您必須安裝並設定 Azure CLI 版本 2.0.61 或更新版本。 執行 az --version
以尋找版本。 如果您需要安裝或升級,請參閱安裝 Azure CLI。
建立 AKS 叢集並啟用網路原則
為了查看網路原則的實際運作情形,您要建立支援網路原則的 AKS 叢集,然後試著新增原則。
若要使用 Azure Network Policy Manager,您必須使用 Azure CNI 外掛程式。 Calico 可以搭配 Azure CNI 外掛程式或 Kubenet CNI 外掛程式使用。
下列範例指令碼會建立具有系統指派身分識別的 AKS 叢集,並使用 Azure Network Policy Manager 來啟用網路原則。
注意
Calico 可以搭配 --network-plugin azure
或 --network-plugin kubenet
參數使用。
您也可以使用使用者指派的身分識別,而不是使用系統指派的身分識別。 如需詳細資訊,請參閱使用受控識別。
建立已啟用 Azure Network Policy Manager 的 AKS 叢集 - 僅限 Linux
在本節中,您要建立具有 Linux 節點集區且已啟用 Azure Network Policy Manager 的叢集。
首先,您可以取代 $RESOURCE_GROUP_NAME
和 $CLUSTER_NAME
變數的值。
$RESOURCE_GROUP_NAME=myResourceGroup-NP
$CLUSTER_NAME=myAKSCluster
$LOCATION=canadaeast
建立 AKS 叢集,並針對 network-plugin
和 network-policy
指定 azure
。
若要建立叢集,請使用下列命令:
az aks create \
--resource-group $RESOURCE_GROUP_NAME \
--name $CLUSTER_NAME \
--node-count 1 \
--network-plugin azure \
--network-policy azure \
--generate-ssh-keys
建立已啟用 Azure Network Policy Manager 的 AKS 叢集 - Windows Server 2022 (預覽)
在本節中,您要建立具有 Windows 節點集區且已啟用 Azure Network Policy Manager 的叢集。
注意
具有 Windows 節點的 Azure Network Policy Manager 只能在 Windows Server 2022 上使用。
安裝 aks-preview Azure CLI 延伸模組
重要
AKS 預覽功能可透過自助服務,以加入方式使用。 預覽會以「現狀」和「可供使用時」提供,其其不受服務等級協定和有限瑕疵擔保所保護。 客戶支援部門會盡最大努力,部分支援 AKS 預覽。 因此,這些功能不適合實際執行用途。 如需詳細資訊,請參閱下列支援文章:
若要安裝 aks-preview
擴充功能,請執行下列命令:
az extension add --name aks-preview
若要更新為發行的最新版延伸模組,請執行下列命令:
az extension update --name aks-preview
註冊 WindowsNetworkPolicyPreview 功能旗標
使用 az feature register 命令以註冊 WindowsNetworkPolicyPreview
功能旗標,如下列範例所示:
az feature register --namespace "Microsoft.ContainerService" --name "WindowsNetworkPolicyPreview"
狀態需要幾分鐘的時間才會顯示「已註冊」。 使用 az feature show 命令以驗證註冊狀態:
az feature show --namespace "Microsoft.ContainerService" --name "WindowsNetworkPolicyPreview"
當狀態顯示為 [已註冊] 時,請使用 az provider register 命令重新整理 Microsoft.ContainerService
資源提供者的註冊:
az provider register --namespace Microsoft.ContainerService
建立 AKS 叢集
現在,您要取代 $RESOURCE_GROUP_NAME
、$CLUSTER_NAME
和 $WINDOWS_USERNAME
變數的值。
$RESOURCE_GROUP_NAME=myResourceGroup-NP
$CLUSTER_NAME=myAKSCluster
$WINDOWS_USERNAME=myWindowsUserName
$LOCATION=canadaeast
建立使用者名稱,以做為叢集上 Windows Server 容器的管理員認證。 下列命令會提示您輸入使用者名稱。 請將它設定為 $WINDOWS_USERNAME
。 切記,本文中的命令會輸入 Bash 殼層中。
echo "Please enter the username to use as administrator credentials for Windows Server containers on your cluster: " && read WINDOWS_USERNAME
若要建立叢集,請使用下列命令:
az aks create \
--resource-group $RESOURCE_GROUP_NAME \
--name $CLUSTER_NAME \
--node-count 1 \
--windows-admin-username $WINDOWS_USERNAME \
--network-plugin azure \
--network-policy azure \
--generate-ssh-keys
建立叢集需要幾分鐘的時間。 根據預設,您的叢集只會使用 Linux 節點集區來建立。 如果您要使用 Windows 節點集區,可新增一個集區。 以下是範例:
az aks nodepool add \
--resource-group $RESOURCE_GROUP_NAME \
--cluster-name $CLUSTER_NAME \
--os-type Windows \
--name npwin \
--node-count 1
建立已啟用 Calico 的 AKS 叢集
建立 AKS 叢集,並指定 --network-plugin azure
和 --network-policy calico
。 指定 --network-policy calico
可在 Linux 和 Windows 節點集區上啟用 Calico。
如果您打算將 Windows 節點集區新增至叢集,請包含符合 Windows 伺服器密碼需求的 windows-admin-username
和 windows-admin-password
參數。
重要
目前,使用 Calico 網路原則搭配 Windows 節點,可在新的叢集上使用 Kubernetes 1.20 版或更新版本搭配 Calico 3.17.2,且需要使用 Azure CNI 網路。 啟用 Calico 時,AKS 叢集上的 Windows 節點預設也會啟用浮動 IP。
對於只有舊版 Calico 且執行 Kubernetes 1.20 的 Linux 節點集區叢集,Calico 版本會自動升級至 3.17.2。
建立使用者名稱,以做為叢集上 Windows Server 容器的管理員認證。 下列命令會提示您輸入使用者名稱。 請將它設定為 $WINDOWS_USERNAME
。 切記,本文中的命令會輸入 Bash 殼層中。
echo "Please enter the username to use as administrator credentials for Windows Server containers on your cluster: " && read WINDOWS_USERNAME
az aks create \
--resource-group $RESOURCE_GROUP_NAME \
--name $CLUSTER_NAME \
--node-count 1 \
--windows-admin-username $WINDOWS_USERNAME \
--network-plugin azure \
--network-policy calico \
--generate-ssh-keys
建立叢集需要幾分鐘的時間。 根據預設,您的叢集只會使用 Linux 節點集區來建立。 如果您要使用 Windows 節點集區,可新增一個集區。 例如:
az aks nodepool add \
--resource-group $RESOURCE_GROUP_NAME \
--cluster-name $CLUSTER_NAME \
--os-type Windows \
--name npwin \
--node-count 1
在現有的叢集中安裝 Azure 網路原則管理員或 Calico
也支援在現有的 AKS 叢集上安裝 Azure 網路原則管理員或 Calico。
警告
升級程序會觸發每個節點集區同時重新映像。 不支援個別升級每個節點集區。 在每個節點集區內,節點會遵循與標準 Kubernetes 版本升級作業相同的程式重新製作映像,藉此暫時新增緩衝區節點,以在節點重新映像處理進行時將執行中應用程式的中斷降到最低。 因此,可能發生的任何中斷都類似於節點映像升級或 Kubernetes 版本升級 作業期間預期的情況。
安裝 Azure 網路原則管理員的範例命令:
az aks update
--resource-group $RESOURCE_GROUP_NAME \
--name $CLUSTER_NAME \
--network-policy azure
安裝 Calico 的範例命令:
警告
此警告適用於將已啟用 Calico 的 Kubenet 叢集升級至已啟用 Calico 的 Azure CNI 重疊。
- 在已啟用 Calico 的 Kubenet 叢集中,Calico 會用來做為 CNI 和網路原則引擎。
- 在 Azure CNI 叢集中,Calico 僅用於網路原則強制執行,而不是 CNI。 這可能會導致 Pod 啟動時與 Calico 允許來自 Pod 的輸出流量之間的短暫延遲。
建議使用 Cilium 而非 Calico 以避免此問題。 在由 Cilium 提供的 Azure CNI 深入了解 Cilium
az aks update
--resource-group $RESOURCE_GROUP_NAME \
--name $CLUSTER_NAME \
--network-policy calico
將已安裝 Azure NPM 或 Calico 的現有叢集升級至由 Cilium 提供的 Azure CNI
若要將已安裝網路原則引擎的現有叢集升級至由 Cilium 支援的 Azure CNI,請參閱將現有叢集升級至由 Cilium 提供的 Azure CNI
確認網路原則設定
當叢集備妥時,請使用 az aks get-credentials 命令,設定 kubectl
以連線到 Kubernetes 叢集。 此命令會下載認證,並設定 Kubernetes CLI 以使用認證:
az aks get-credentials --resource-group $RESOURCE_GROUP_NAME --name $CLUSTER_NAME
為了開始驗證網路原則,您要建立範例應用程式並設定流量規則。
首先,建立名為 demo
的命名空間以執行範例 Pod:
kubectl create namespace demo
現在,在名為 client
和 server
的叢集中建立兩個 Pod。
注意
如果您想要在特定節點上排程 client 或 server,請在 Pod 建立 kubectl run 命令中的 --command
引數前面新增下列位元:
--overrides='{"spec": { "nodeSelector": {"kubernetes.io/os": "linux|windows"}}}'
建立 server
Pod。 此 Pod 在 TCP 連接埠 80 上提供:
kubectl run server -n demo --image=k8s.gcr.io/e2e-test-images/agnhost:2.33 --labels="app=server" --port=80 --command -- /agnhost serve-hostname --tcp --http=false --port "80"
建立 client
Pod。 下列命令會在 client
Pod 上執行 Bash:
kubectl run -it client -n demo --image=k8s.gcr.io/e2e-test-images/agnhost:2.33 --command -- bash
現在,在個別視窗中執行下列命令,以取得伺服器 IP:
kubectl get pod --output=wide -n demo
輸出應會顯示如下:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
server 1/1 Running 0 30s 10.224.0.72 akswin22000001 <none> <none>
測試沒有網路原則的連線
在用戶端的殼層中執行下列命令,以確認與伺服器的連線。 使用執行上一個命令的輸出中找到的 IP 來取代 server-ip
。 如果連線成功,則沒有輸出。
/agnhost connect <server-ip>:80 --timeout=3s --protocol=tcp
測試具有網路原則的連線
若要新增網路原則,請建立名為 demo-policy.yaml
的檔案,並貼上下列 YAML 資訊清單:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: demo-policy
namespace: demo
spec:
podSelector:
matchLabels:
app: server
ingress:
- from:
- podSelector:
matchLabels:
app: client
ports:
- port: 80
protocol: TCP
指定 YAML 資訊清單的名稱,並使用 kubectl apply 加以套用:
kubectl apply –f demo-policy.yaml
現在,在用戶端的殼層中執行下列 /agnhost
命令,以確認與伺服器的連線:
/agnhost connect <server-ip>:80 --timeout=3s --protocol=tcp
因為伺服器標記為 app=server
,但用戶端未標記,因此會封鎖流量的連線。 上述 connect 命令會產生下列輸出:
TIMEOUT
執行下列命令來標記 client
,並確認與伺服器的連線。 輸出應該不會傳回任何內容。
kubectl label pod client -n demo app=client
卸載 Azure 網路原則管理員或 Calico
需求:
- Azure CLI 2.63 版或更新版本
注意
- 解除安裝程序不會移除 Calico 所使用的自訂資源定義 (CRD) 和自訂資源 (CR)。 這些 CRD 和 CR 都有以 "projectcalico.org" 或 "tigera.io" 結尾的名稱。 成功解除安裝 Calico (在移除 Calico 中斷叢集之前刪除 CRD) 之後,可以手動刪除這些 CRD 和相關聯的 CR。
- 升級不會移除叢集中的任何 NetworkPolicy 資源,但在解除安裝之後,不會再強制執行這些原則。
警告
升級程序會觸發每個節點集區同時重新映像。 不支援個別升級每個節點集區。 叢集網路的任何中斷都類似於節點映像升級或 Kubernetes 版本升級,其中節點集區中的每個節點都會重新映像。
若要從叢集移除 Azure 網路原則管理員或 Calico,請執行下列命令:
az aks update
--resource-group $RESOURCE_GROUP_NAME \
--name $CLUSTER_NAME \
--network-policy none
清除資源
在本文中,您建立了命名空間和兩個 Pod,並套用了網路原則。 若要清除這些資源,請使用 kubectl delete 命令並指定資源名稱:
kubectl delete namespace demo
下一步
如需網路資源的詳細資訊,請參閱 Azure Kubernetes Service (AKS) 中應用程式的網路概念。
若要深入了解原則,請參閱 Kubernetes 網路原則。