共用方式為


針對裝載於 AKS 叢集中之應用程式的連線問題進行疑難解答

在目前的動態雲端環境中,確保與 Azure Kubernetes Service (AKS) 叢集中裝載的應用程式順暢連線,對於維護最佳效能和用戶體驗至關重要。 本文涵蓋如何針對各種因素所造成的連線問題進行疑難解答和解決,包括應用程式端問題、網路原則、網路安全組 (NSG) 規則或其他。

注意

若要針對嘗試連線到 AKS API 伺服器時的常見問題進行疑難解答,請參閱 API 伺服器叢集連線問題的基本疑難解答。

必要條件

考量的因素

本節涵蓋當您嘗試連線到 AKS 叢集中裝載的應用程式時發生問題時所要採取的疑難解答步驟。

在任何網路案例中,系統管理員應在疑難解答時考慮下列重要因素:

  • 要求的來源和目的地為何?

  • 來源與目的地之間的躍點為何?

  • 要求-回應流程為何?

  • 哪些躍點在頂端具有額外的安全性層級,例如下列專案:

    • 防火牆
    • 網路安全性群組 (NSG)
    • 網路原則

當您檢查每個元件時, 取得並分析 HTTP 回應碼。 這些程式代碼有助於識別問題的本質,而且在應用程式回應 HTTP 要求的案例中特別有用。

如果其他疑難解答步驟未提供任何決定性的結果,請從客戶端和伺服器擷取封包。 當客戶端與伺服器之間涉及非 HTTP 流量時,封包擷取也很有用。 如需如何收集 AKS 環境封包擷取的詳細資訊,請參閱數據收集指南中的下列文章:

瞭解如何取得 HTTP 回應碼並取得封包擷取,可讓您更輕鬆地針對網路連線問題進行疑難解答。

AKS 上應用程式的基本網路流程

一般而言,當應用程式使用 Azure Load Balancer 服務類型公開時,存取它們的要求流程如下所示:

用戶端 >> DNS 名稱 >> AKS 負載平衡器 IP 位址 >> AKS 節點 >> Pod

還有其他可能的情況,其中可能涉及額外的元件。 例如:

  • 已啟用具有 應用程式路由附加 元件功能的受控 NGINX 輸入。
  • 應用程式閘道是透過 應用程式閘道 輸入控制器 (AGIC) 而不是 Azure Load Balancer 使用。
  • Azure Front Door 和 API 管理 可能會用於負載平衡器之上。
  • 此程式會使用內部負載平衡器。
  • 連線可能不會結束於Pod和要求的URL。 這可能取決於 Pod 是否可以連線到另一個實體,例如資料庫或相同叢集中的任何其他服務。

請務必瞭解應用程式的要求流程。

AKS 叢集中應用程式的基本要求流程與下圖所示的流程類似。

Azure Kubernetes Service (A K S) 叢集上應用程式的基本要求流程圖。

內部疑難解答

針對連線問題進行疑難解答可能會涉及許多檢查,但內部方法可協助找出問題的來源並找出瓶頸。 在此方法中,您會從 Pod 本身開始,檢查應用程式是否在 Pod 的 IP 位址上回應。 然後,檢查每個元件,並顯示至結束用戶端。

步驟 1:檢查 Pod 是否正在執行,且 Pod 內的應用程式或容器是否正確回應

若要判斷 Pod 是否正在執行,請執行下列 其中一個 kubectl get 命令:

# List pods in the specified namespace.
kubectl get pods -n <namespace-name>

# List pods in all namespaces.
kubectl get pods -A

如果 Pod 未執行,該怎麼辦? 在此情況下,請使用 kubectl describe 命令檢查 Pod 事件:

kubectl describe pod <pod-name> -n <namespace-name>

如果 Pod 未處於 ReadyRunning 狀態,或重新啟動多次,請檢查 kubectl describe 輸出。 這些事件會顯示任何導致您無法啟動 Pod 的問題。 或者,如果 Pod 已啟動,Pod 內的應用程式可能會失敗,導致 Pod 重新啟動。 請據以 針對 Pod 進行疑難解答,以確定其處於適當的狀態。

如果 Pod 正在執行,檢查 Pod 內容器的記錄也很有用。 執行下列一 系列 kubectl logs 命令:

kubectl logs <pod-name> -n <namespace-name>

# Check logs for an individual container in a multicontainer pod.
kubectl logs <pod-name> -n <namespace-name> -c <container-name>

# Dump pod logs (stdout) for a previous container instance.
kubectl logs <pod-name> --previous                      

# Dump pod container logs (stdout, multicontainer case) for a previous container instance.
kubectl logs <pod-name> -c <container-name> --previous      

Pod 是否正在執行? 在此情況下,請啟動叢集中的測試Pod來測試連線能力。 從測試 Pod,您可以直接存取應用程式的 Pod IP 位址,並檢查應用程式是否正確回應。 執行 kubectl runapt-getcURL 命令,如下所示:

# Start a test pod in the cluster:
kubectl run -it --rm aks-ssh --image=debian:stable

# After the test pod is running, you will gain access to the pod.
# Then you can run the following commands:
apt-get update -y && apt-get install dnsutils -y && apt-get install curl -y && apt-get install netcat-traditional -y

# After the packages are installed, test the connectivity to the application pod:
curl -Iv http://<pod-ip-address>:<port>

對於接聽其他通訊協定的應用程式,您可以在測試 Pod 內安裝相關工具,例如 netcat 工具,然後執行下列命令來檢查應用程式 Pod 的連線:

# After the packages are installed, test the connectivity to the application pod using netcat/nc command:
nc -z -v <pod-ip-address> <port>

如需針對Pod進行疑難解答的詳細資訊,請參閱 偵錯執行中的Pod。

步驟 2:檢查應用程式是否可從服務連線

針對 Pod 內應用程式正在執行的案例,您主要可以專注於針對 Pod 公開方式進行疑難解答。

Pod 是否公開為服務? 在此情況下,請檢查服務事件。 此外,檢查 Pod IP 位址和應用程式埠是否可作為服務描述中的連接點:

# Check the service details.
kubectl get svc -n <namespace-name>

# Describe the service.
kubectl describe svc <service-name> -n <namespace-name>

檢查 Pod 的 IP 位址是否存在為服務中的端點,如下列範例所示:

$ kubectl get pods -o wide  # Check the pod's IP address.
NAME            READY   STATUS        RESTARTS   AGE   IP            NODE                                
my-pod          1/1     Running       0          12m   10.244.0.15   aks-agentpool-000000-vmss000000  

$ kubectl describe service my-cluster-ip-service  # Check the endpoints in the service.
Name:              my-cluster-ip-service
Namespace:         default
Selector:          app=my-pod
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.0.174.133
IPs:               10.0.174.133
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.0.15:80     # <--- Here

$ kubectl get endpoints  # Check the endpoints directly for verification.
NAME                      ENDPOINTS           AGE
my-cluster-ip-service     10.244.0.15:80      14m

如果端點未指向正確的 Pod IP 位址,請確認 Labels Pod 和服務的 與 Selectors

服務中的端點是否正確? 如果是,請存取服務,並檢查應用程式是否可連線。

存取 ClusterIP 服務

ClusterIP針對服務,您可以在叢集中啟動測試 Pod 並存取服務 IP 位址:

在 Azure Kubernetes Service (A K S) 叢集中使用測試 Pod 來存取叢集 I P 位址的圖表。

# Start a test pod in the cluster:
kubectl run -it --rm aks-ssh --image=debian:stable
  
# After the test pod is running, you will gain access to the pod.
# Then, you can run the following commands:
apt-get update -y && apt-get install dnsutils -y && apt-get install curl -y && apt-get install netcat-traditional -y
  
# After the packages are installed, test the connectivity to the service:
curl -Iv http://<service-ip-address>:<port>

對於接聽其他通訊協定的應用程式,您可以在測試 Pod 內安裝相關工具,例如 netcat 工具,然後執行下列命令來檢查應用程式 Pod 的連線:

# After the packages are installed, test the connectivity to the application pod using netcat/nc command:
nc -z -v <pod-ip-address> <port>

如果上一個命令未傳回適當的回應,請檢查服務事件是否有任何錯誤。

存取 LoadBalancer 服務

LoadBalancer針對服務,您可以從叢集外部存取負載平衡器 IP 位址。

從 Azure Kubernetes Service (A K S) 叢集外部存取負載平衡器 I P 位址的測試用戶圖表。

curl -Iv http://<service-ip-address>:<port>

對於接聽其他通訊協定的應用程式,您可以在測試 Pod 內安裝相關工具,例如 netcat 工具,然後執行下列命令來檢查應用程式 Pod 的連線:

nc -z -v <pod-ip-address> <port>

LoadBalancer服務IP位址是否傳回正確的回應? 如果沒有,請遵循下列步驟:

  1. 確認服務的事件。

  2. 確認與 AKS 節點和 AKS 子網相關聯的網路安全組 (NSG) 允許服務埠上的連入流量。

如需疑難解答服務的詳細資訊命令,請參閱 偵錯服務

使用輸入而非服務的案例

針對使用 Ingress 資源公開應用程式的案例,流量流程類似下列進展:

用戶端 >> DNS 名稱 >> 負載平衡器或應用程式閘道 IP 位址 >> 叢集 >> 服務或 Pod 內的輸入控制器 Pod

當 Azure Kubernetes Service (A K S) 叢集內的應用程式使用輸入資源公開時,網路流量流量的圖表。

您也可以在這裡套用內部疑難解答方法。 您也可以檢查輸入 kubernetes 資源和輸入控制器詳細資料,以取得詳細資訊:

$ kubectl get ing -n <namespace-of-ingress>  # Checking the ingress details and events.
NAME                         CLASS    HOSTS                ADDRESS       PORTS     AGE
hello-world-ingress          <none>   myapp.com            20.84.x.x     80, 443   7d22h

$ kubectl describe ing -n <namespace-of-ingress> hello-world-ingress
Name:             hello-world-ingress
Namespace:        <namespace-of-ingress>
Address:          20.84.x.x
Default backend:  default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
TLS:
  tls-secret terminates myapp.com
Rules:
  Host                Path  Backends
  ----                ----  --------
  myapp.com
                      /blog   blog-service:80 (10.244.0.35:80)
                      /store  store-service:80 (10.244.0.33:80)

Annotations:          cert-manager.io/cluster-issuer: letsencrypt
                      kubernetes.io/ingress.class: nginx
                      nginx.ingress.kubernetes.io/rewrite-target: /$1
                      nginx.ingress.kubernetes.io/use-regex: true
Events:
  Type    Reason  Age    From                      Message
  ----    ------  ----   ----                      -------
  Normal  Sync    5m41s  nginx-ingress-controller  Scheduled for sync
  Normal  Sync    5m41s  nginx-ingress-controller  Scheduled for sync

此範例包含的資源 Ingress

  • 在主機上接 myapp.com 聽。
  • 已設定兩 Path 個字串。
  • 路由至後端中的兩 Services 個。

確認後端服務正在執行,並回應輸入描述中所提及的埠:

$ kubectl get svc -n <namespace-of-ingress>
NAMESPACE       NAME                                     TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)                      
ingress-basic   blog-service                             ClusterIP      10.0.155.154   <none>        80/TCP                       
ingress-basic   store-service                            ClusterIP      10.0.61.185    <none>        80/TCP             
ingress-basic   nginx-ingress-ingress-nginx-controller   LoadBalancer   10.0.122.148   20.84.x.x     80:30217/TCP,443:32464/TCP   

如果發生錯誤,請確認輸入控制器 Pod 的記錄:

$ kubectl get pods -n <namespace-of-ingress>  # Get the ingress controller pods.
NAME                                                     READY   STATUS    RESTARTS   AGE
aks-helloworld-one-56c7b8d79d-6zktl                      1/1     Running   0          31h
aks-helloworld-two-58bbb47f58-rrcv7                      1/1     Running   0          31h
nginx-ingress-ingress-nginx-controller-9d8d5c57d-9vn8q   1/1     Running   0          31h
nginx-ingress-ingress-nginx-controller-9d8d5c57d-grzdr   1/1     Running   0          31h

$ # Check logs from the pods.
$ kubectl logs -n ingress-basic nginx-ingress-ingress-nginx-controller-9d8d5c57d-9vn8q

如果用戶端向輸入主機名或IP位址提出要求,但在輸入控制器Pod的記錄中看不到任何專案,該怎麼辦? 在此情況下,要求可能無法連線到叢集,而且使用者可能會收到 Connection Timed Out 錯誤訊息。

另一個可能性是輸入 Pod 上的元件,例如 Load Balancer 或 應用程式閘道,不會正確地將要求路由傳送至叢集。 如果這是真的,您可以檢查這些資源的後端設定。

如果您收到 Connection Timed Out 錯誤訊息,請檢查與 AKS 節點相關聯的網路安全組。 此外,請檢查 AKS 子網。 它可能會封鎖從負載平衡器或應用程式閘道到 AKS 節點的流量。

如需如何針對輸入進行疑難解答的詳細資訊(例如 Nginx 輸入),請參閱 ingress-nginx 疑難解答

與我們連絡,以取得說明

如果您有問題或需要相關協助,請建立支援要求,或詢問 Azure community 支援。 您也可以向 Azure 意見反應社群提交產品意見反應。

協力廠商連絡資訊免責聲明

Microsoft 提供協力廠商連絡資訊,以協助您尋找有關此主題的其他資訊。 此連絡資訊可能會變更而不另行通知。 Microsoft 不保證協力廠商連絡資訊的準確性。