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

與 Microsoft Azure Kubernetes Service (AKS) 叢集的連線問題可能代表不同的意義。 在某些情況下,這可能表示與 API 伺服器的聯機會受到影響 (例如,使用 kubectl) 。 在其他情況下,這可能表示常見的連線問題會影響裝載於 AKS 叢集上的應用程式。 本文討論如何針對 AKS 叢集連線問題進行疑難解答。

注意事項

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

必要條件

  • 用戶端 URL (cURL) 工具或類似的命令行工具。

  • 用來處理封裝 的apt-get 命令行工具。

  • Kubernetes kubectl 工具,或連線到叢集的類似工具。 若要使用 Azure CLI 安裝 kubectl,請執行 az aks install-cli 命令。

要考慮的因素

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

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

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

  • 來源與目的地之間的躍點有哪些?

  • 什麼是要求-回應流程?

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

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

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

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

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

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

一般而言,存取裝載於 AKS 叢集上之應用程式的要求流程如下:

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

在其他可能的情況下,可能會涉及額外的元件。 例如:

  • 應用程式閘道是透過 應用程式閘道 輸入控制器 (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

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

對於接聽其他通訊協定的應用程式,您可以在測試 Pod 內安裝相關工具,然後檢查應用程式 Pod 的連線能力。

如需針對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
  
# After the packages are installed, test the connectivity to the service:
curl -Iv http://<service-ip-address>:<port>

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

存取 LoadBalancer 服務

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

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

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

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

  1. 確認服務的事件。

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

如需針對服務進行疑難解答的詳細命令,請參閱 偵錯服務

使用輸入而非服務的案例

在使用 Ingress 資源公開應用程式的案例中,流量流程類似下列進度:

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

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

您也可以在這裡套用內建的疑難解答方法。 如需詳細資訊,您也可以檢查輸入和輸入控制器詳細數據:

$ 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 不保證第三方聯繫人信息的正確性。