自定義網路安全組會封鎖流量
當您存取裝載於 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 叢集的自定義虛擬網路和自定義子網,這種安排很常見。 子網層級的規則集可能類似下表。
優先順序 名稱 連接埠 Protocol (通訊協定) 來源 Destination 動作 65000 AllowVnetInBound 任何 任何 VirtualNetwork VirtualNetwork 允許 65001 AllowAzureLoadBalancerInBound 任何 任何 AzureLoadBalancer 任何 允許 65500 DenyAllInBound 任何 任何 任何 任何 Deny 第二個集合是由網路適配器層級的NSG規則所組成。 這些規則會顯示在下列附註標題下:
已連結至網路介面的網路安全組 aks-agentpool-agentpool-number-nsg<> (:aks-agentpool-vm-scale-set-number-vmss<>)
此 NSG 由 AKS 叢集套用,並由 AKS 管理。 對應的規則集可能類似下表。
優先順序 名稱 連接埠 Protocol (通訊協定) 來源 Destination 動作 500 <guid-TCP-80-Internet> 80 TCP 網際網路 10.81.x。X Allow 65000 AllowVnetInBound 任何 任何 VirtualNetwork VirtualNetwork 允許 65001 AllowAzureLoadBalancerInBound 任何 任何 AzureLoadBalancer 任何 允許 65500 DenyAllInBound 任何 任何 任何 任何 Deny
在網路適配器層級,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 意應見反社群。