自訂網路安全性群組會封鎖流量
當您存取裝載在 Azure Kubernetes Service (AKS) 叢集上的應用程式時,會收到「逾時」錯誤訊息。 即使應用程式正在執行且其餘組態似乎正確,也可能發生此錯誤。
必要條件
用來連線到叢集的 Kubernetes kubectl 工具或類似的工具。 若要使用 Azure CLI 安裝 kubectl,請執行 az aks install-cli 命令。
用戶端 URL (cURL) 工具或類似的命令行工具。
用於處理封裝的 apt-get 命令行工具。
徵兆
如果您執行下列 kubectl get 和 cURL 命令,您會遇到類似下列控制台輸出的「逾時」錯誤:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
my-deployment-66648877fc-v78jm 1/1 Running 0 5m53s
$ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-loadbalancer-service LoadBalancer 10.0.107.79 10.81.x.x 80:31048/TCP 4m14s
$ curl -Iv http://10.81.124.39 # Use an IP address that fits the "EXTERNAL-IP" pattern.
* Trying 10.81.x.x:80...
* connect to 10.81.x.x port 80 failed: Timed out
* Failed to connect to 10.81.x.x port 80 after 21033 ms: Timed out
* Closing connection 0
curl: (28) Failed to connect to 10.81.x.x port 80 after 21033 ms: Timed out
原因
如果您每次都遇到相同的「逾時」錯誤,這通常表示網路元件封鎖流量。
若要針對此問題進行疑難解答,您可以從檢查 Pod 的存取權開始,然後在內部方法中移至用戶端。
若要檢查 Pod,請執行下列 kubectl get
和 kubectl 描述 命令:
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
my-deployment-66648877fc-v78jm 1/1 Running 0 53s 172.25.0.93 aks-agentpool-42617579-vmss000000
$ kubectl describe pod my-deployment-66648877fc-v78jm # Specify the pod name from the previous command.
...
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 117s default-scheduler Successfully assigned default/my-deployment-66648877fc-v78jm to aks-agentpool-42617579-vmss000000
Normal Pulling 116s kubelet Pulling image "httpd"
Normal Pulled 116s kubelet Successfully pulled image "httpd" in 183.532816ms
Normal Created 116s kubelet Created container webserver
Normal Started 116s kubelet Started container webserver
根據此輸出,Pod 似乎正在正確執行,而不會重新啟動。
開啟測試 Pod 以檢查應用程式 Pod 的存取權。 執行下列 kubectl get
、 kubectl run、 apt-get
、 和 cURL 命令:
$ kubectl get pods -o wide # Get the pod IP address.
NAME READY STATUS RESTARTS AGE IP NODE
my-deployment-66648877fc-v78jm 1/1 Running 0 7m45s 172.25.0.93 aks-agentpool-42617579-vmss000000
$ kubectl run -it --rm aks-ssh --image=debian:stable # Launch the test pod.
If you don't see a command prompt, try pressing enter.
$ root@aks-ssh:
$ # Install packages inside the test pod.
$ root@aks-ssh: apt-get update -y && apt-get install dnsutils -y && apt-get install curl -y
Get:1 http://deb.debian.org/debian bullseye InRelease [116 kB]
Get:2 http://deb.debian.org/debian bullseye-updates InRelease [39.4 kB]
...
...
Running hooks in /etc/ca-certificates/update.d...
done.
$ # Try to check access to the pod using the pod IP address from the "kubectl get" output.
$ curl -Iv http://172.25.0.93
* Trying 172.25.0.93:80...
* Connected to 172.25.0.93 (172.25.0.93) port 80 (#0)
...
...
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
...
...
* Connection #0 to host 172.25.0.93 left intact
Pod 可以直接存取。 因此,應用程式正在執行。
定義的服務是類型 LoadBalancer
。 這表示要求會從結束用戶端流向Pod,如下所示:
用戶端 >> 負載平衡器 >> AKS 節點 >> 應用程式 Pod
在此要求流程中,我們可以透過下列元件封鎖流量:
- 叢集中的網路原則
- AKS 子網和 AKS 節點的網路安全組 (NSG)
若要檢查網路原則,請執行下列 kubectl get
命令:
$ kubectl get networkpolicy --all-namespaces
NAMESPACE NAME POD-SELECTOR AGE
kube-system konnectivity-agent app=konnectivity-agent 3h8m
只有 AKS 預設原則存在。 因此,網路原則似乎不會封鎖流量。
若要使用 AKS 檢查 NSG 及其相關聯的規則,請遵循下列步驟:
在 Azure 入口網站 中,搜尋並選取 [虛擬機擴展集]。
在擴展集實例清單中,選取您使用的實例。
在延伸集實例的功能表窗格中,選取
Networking
。
擴展集執行個體的 [網路] 頁面會隨即出現。 在 [ 輸入埠規則 ] 索引標籤中,會顯示兩組規則,這些規則是根據擴展集實例上作用的兩個 NSG:
第一組是由子網層級的NSG規則所組成。 這些規則會顯示在下列附註標題底下:
網路安全組 my-aks-nsg> (附加至子網:<my-aks-subnet>)<
如果使用 AKS 叢集的自定義虛擬網路和自定義子網,則這種安排很常見。 子網層級的規則集可能類似下表。
優先順序 名稱 連接埠 通訊協定 來源 Destination 動作 65000 AllowVnetInBound 任意 任意 VirtualNetwork VirtualNetwork Allow 65001 AllowAzureLoadBalancerInBound 任意 任意 AzureLoadBalancer 任意 Allow 65500 DenyAllInBound 任意 任意 任意 任意 拒絕 第二組是由網路適配器層級的NSG規則所組成。 這些規則會顯示在下列附註標題底下:
網路安全組 aks-agentpool-agentpool-number-nsg<> (附加至網路介面:aks-agentpool-vm-scale-set-number-vmss)<>
AKS 叢集會套用此 NSG,並由 AKS 管理。 對應的規則集可能類似下表。
優先順序 名稱 連接埠 通訊協定 來源 Destination 動作 500 <guid-TCP-80-Internet> 80 TCP 網際網路 10.81.x。x 允許 65000 AllowVnetInBound 任意 任意 VirtualNetwork VirtualNetwork Allow 65001 AllowAzureLoadBalancerInBound 任意 任意 AzureLoadBalancer 任意 Allow 65500 DenyAllInBound 任意 任意 任意 任意 拒絕
在網路適配器層級,IP 位址為 10.81 的 TCP 有 NSG 輸入規則。x.埠 80 上的 x (在表格中反白顯示)。 不過,子網層級 NSG 的規則遺漏對等規則。
為什麼 AKS 不會將規則套用至自訂 NSG? 因為 AKS 不會將 NSG 套用至其子網,因此不會修改與該子網相關聯的任何 NSG。 AKS 只會在網路適配器層級修改 NSG。 如需詳細資訊,請參閱 我是否可以使用 AKS 設定 NSG?。
解決方案
如果應用程式已啟用特定埠的存取權,您必須確定自定義NSG允許該埠做為 Inbound
規則。 在子網層級的自定義NSG中新增適當的規則之後,即可存取應用程式。
$ curl -Iv http://10.81.x.x
* Trying 10.81.x.x:80...
* Connected to 10.81.x.x (10.81.x.x) port 80 (#0)
...
...
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
...
...
* Connection #0 to host 10.81.x.x left intact
與我們連絡,以取得說明
如果您有問題或需要相關協助,請建立支援要求,或詢問 Azure community 支援。 您也可以向 Azure 意見反應社群提交產品意見反應。