針對裝載於 AKS 叢集中之應用程式的連線問題進行疑難解答
在目前的動態雲端環境中,確保與 Azure Kubernetes Service (AKS) 叢集中裝載的應用程式順暢連線,對於維護最佳效能和用戶體驗至關重要。 本文涵蓋如何針對各種因素所造成的連線問題進行疑難解答和解決,包括應用程式端問題、網路原則、網路安全組 (NSG) 規則或其他。
注意
若要針對嘗試連線到 AKS API 伺服器時的常見問題進行疑難解答,請參閱 API 伺服器叢集連線問題的基本疑難解答。
必要條件
用戶端 URL (cURL) 工具或類似的命令行工具。
用於處理封裝的 apt-get 命令行工具。
TCP 連線的 Netcat (
nc
) 命令行工具。Kubernetes kubectl 工具,或連線至叢集的類似工具。 若要使用 Azure CLI 安裝 kubectl,請執行 az aks install-cli 命令。
考量的因素
本節涵蓋當您嘗試連線到 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 叢集中應用程式的基本要求流程與下圖所示的流程類似。
內部疑難解答
針對連線問題進行疑難解答可能會涉及許多檢查,但內部方法可協助找出問題的來源並找出瓶頸。 在此方法中,您會從 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 未處於 Ready
或 Running
狀態,或重新啟動多次,請檢查 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 run、 apt-get
和 cURL
命令,如下所示:
# 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 位址:
# 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 位址。
curl -Iv http://<service-ip-address>:<port>
對於接聽其他通訊協定的應用程式,您可以在測試 Pod 內安裝相關工具,例如 netcat 工具,然後執行下列命令來檢查應用程式 Pod 的連線:
nc -z -v <pod-ip-address> <port>
LoadBalancer
服務IP位址是否傳回正確的回應? 如果沒有,請遵循下列步驟:
確認服務的事件。
確認與 AKS 節點和 AKS 子網相關聯的網路安全組 (NSG) 允許服務埠上的連入流量。
如需疑難解答服務的詳細資訊命令,請參閱 偵錯服務。
使用輸入而非服務的案例
針對使用 Ingress
資源公開應用程式的案例,流量流程類似下列進展:
用戶端 >> DNS 名稱 >> 負載平衡器或應用程式閘道 IP 位址 >> 叢集 >> 服務或 Pod 內的輸入控制器 Pod
您也可以在這裡套用內部疑難解答方法。 您也可以檢查輸入 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 不保證協力廠商連絡資訊的準確性。