共用方式為


自訂網路安全性群組會封鎖流量

當您存取裝載在 Azure Kubernetes Service (AKS) 叢集上的應用程式時,會收到「逾時」錯誤訊息。 即使應用程式正在執行且其餘組態似乎正確,也可能發生此錯誤。

必要條件

徵兆

如果您執行下列 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 getkubectl 描述 命令:

$ 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 getkubectl runapt-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 及其相關聯的規則,請遵循下列步驟:

  1. Azure 入口網站 中,搜尋並選取 [虛擬機擴展集]。

  2. 在擴展集實例清單中,選取您使用的實例。

  3. 在延伸集實例的功能表窗格中,選取 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.xx 允許
    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 意見反應社群提交產品意見反應。