新的 Kubernetes 安裝或當您增加 Kubernetes 負載時,可能會發生網路問題。 其他與網路問題相關的問題也可能發生。 請一律檢查 AKS 疑難解答 指南,以查看您的問題是否描述於該處。 本文說明網路疑難解答觀點和可能發生的特定問題的其他詳細數據和考慮。
用戶端無法連線到 API 伺服器
這些錯誤牽涉到您無法透過 Kubernetes 叢集命令行工具 (kubectl) 或任何其他工具連線到 Azure Kubernetes Service (AKS) 叢集 API 伺服器時所發生的連線問題,例如透過程式設計語言的 REST API。
錯誤
您可能會看到如下所示的錯誤:
Unable to connect to the server: dial tcp <API-server-IP>:443: i/o timeout
Unable to connect to the server: dial tcp <API-server-IP>:443: connectex: A connection attempt
failed because the connected party did not properly respond after a period, or established
connection failed because connected host has failed to respond.
原因 1
API 伺服器授權的IP範圍有可能在叢集的 API 伺服器上啟用,但用戶端的IP位址不包含在這些IP範圍中。 若要判斷是否啟用IP範圍,請在 Azure CLI 中使用下列 az aks show
命令。 如果啟用IP範圍,命令將會產生IP範圍清單。
az aks show --resource-group <cluster-resource-group> \
--name <cluster-name> \
--query apiServerAccessProfile.authorizedIpRanges
解決方案 1
請確定用戶端的 IP 位址位於叢集 API 伺服器授權的範圍內:
尋找您的本機IP位址。 如需如何在 Windows 和 Linux 上尋找它的資訊,請參閱 如何尋找我的 IP。
使用
az aks update
Azure CLI 中的 命令,更新 API 伺服器授權的範圍。 授權用戶端的IP位址。 如需指示,請參閱 更新叢集的 API 伺服器授權 IP 範圍。
原因 2
如果您的 AKS 叢集是私人叢集,API 伺服器端點就不會有公用 IP 位址。 您必須使用具有 AKS 叢集虛擬網路之網路存取權的 VM。
解決方案 2
如需如何解決此問題的資訊,請參閱 連線到私人叢集的選項。
Pod 無法設定 IP 位址
錯誤
Pod 停滯於 ContainerCreating
狀態中,而其事件會回報 Failed to allocate address
錯誤:
Normal SandboxChanged 5m (x74 over 8m) kubelet, k8s-agentpool-00011101-0 Pod sandbox
changed, it will be killed and re-created.
Warning FailedCreatePodSandBox 21s (x204 over 8m) kubelet, k8s-agentpool-00011101-0 Failed
create pod sandbox: rpc error: code = Unknown desc = NetworkPlugin cni failed to set up pod
"deployment-azuredisk6-874857994-487td_default" network: Failed to allocate address: Failed to
delegate: Failed to allocate address: No available addresses
或錯誤 not enough IPs available
:
Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox
'ac1b1354613465324654c1588ac64f1a756aa32f14732246ac4132133ba21364': plugin type='azure-vnet'
failed (add): IPAM Invoker Add failed with error: Failed to get IP address from CNS with error:
%w: AllocateIPConfig failed: not enough IPs available for 9c6a7f37-dd43-4f7c-a01f-1ff41653609c,
waiting on Azure CNS to allocate more with NC Status: , IP config request is [IPConfigRequest:
DesiredIPAddress , PodInterfaceID a1876957-eth0, InfraContainerID
a1231464635654a123646565456cc146841c1313546a515432161a45a5316541, OrchestratorContext
{'PodName':'a_podname','PodNamespace':'my_namespace'}]
檢查外掛程式IPAM存放區中配置的IP位址。 您可能會發現已設定所有 IP 位址,但數目遠小於執行中的 Pod 數目:
如果使用 kubenet:
# Kubenet, for example. The actual path of the IPAM store file depends on network plugin implementation.
chroot /host/
ls -la "/var/lib/cni/networks/$(ls /var/lib/cni/networks/ | grep -e "k8s-pod-network" -e "kubenet")" | grep -v -e "lock\|last\|total" -e '\.$' | wc -l
244
備註
對於沒有 Calico 的 kubenet,路徑為 /var/lib/cni/networks/kubenet
。 對於具有 Calico 的 kubenet,路徑為 /var/lib/cni/networks/k8s-pod-network
。 上述文稿會在執行命令時自動選取路徑。
# Check running Pod IPs
kubectl get pods --field-selector spec.nodeName=<your_node_name>,status.phase=Running -A -o json | jq -r '.items[] | select(.spec.hostNetwork != 'true').status.podIP' | wc -l
7
如果使用 Azure CNI 進行動態 IP 配置:
kubectl get nnc -n kube-system -o wide
NAME REQUESTED IPS ALLOCATED IPS SUBNET SUBNET CIDR NC ID NC MODE NC TYPE NC VERSION
aks-agentpool-12345678-vmss000000 32 32 subnet 10.18.0.0/15 559e239d-f744-4f84-bbe0-c7c6fd12ec17 dynamic vnet 1
# Check running Pod IPs
kubectl get pods --field-selector spec.nodeName=aks-agentpool-12345678-vmss000000,status.phase=Running -A -o json | jq -r '.items[] | select(.spec.hostNetwork != 'true').status.podIP' | wc -l
21
原因 1
此錯誤可能是網路外掛程式中的錯誤所造成。 當 Pod 終止時,外掛程式無法解除分配 IP 位址。
解決方案 1
請連絡Microsoft以取得因應措施或修正。
原因 2
Pod 建立速度比已終止 Pod 的垃圾收集快得多。
解決方案 2
設定 kubelet 的快速垃圾收集。 如需指示,請參閱 Kubernetes 垃圾收集檔。
Pod 記憶體取的服務
解決此問題的第一個步驟是檢查是否已為服務自動建立端點:
kubectl get endpoints <service-name>
如果您收到空的結果,則服務的標籤選取器可能錯誤。 確認標籤正確:
# Query Service LabelSelector.
kubectl get svc <service-name> -o jsonpath='{.spec.selector}'
# Get Pods matching the LabelSelector and check whether they're running.
kubectl get pods -l key1=value1,key2=value2
如果上述步驟傳回預期的值:
檢查 Pod
containerPort
是否與服務containerPort
相同。檢查是否
podIP:containerPort
正常運作:# Testing via cURL. curl -v telnet ://<Pod-IP>:<containerPort> # Testing via Telnet. telnet <Pod-IP>:<containerPort>
以下是服務問題的其他一些可能原因:
- 容器不會接聽指定的
containerPort
。 (檢查 Pod 描述。) - 發生 CNI 外掛程式錯誤或網路路由錯誤。
- kube-proxy 未執行,或 iptables 規則未正確設定。
- 網路原則正在卸除流量。 如需套用和測試網路原則的資訊,請參閱 Azure Kubernetes 網路原則概觀。
- 如果您使用 Calico 作為網路外掛程式,您也可以擷取網路原則流量。 如需設定該設定的資訊,請參閱 Calico 網站。
節點無法連線到 API 伺服器
許多附加元件和容器都需要存取 Kubernetes API(例如 kube-dns 和作員容器)。 如果此程式期間發生錯誤,下列步驟可協助您判斷問題的來源。
首先,確認 Kubernetes API 是否可在 Pod 中存取:
kubectl run curl --image=mcr.microsoft.com/azure-cli -i -t --restart=Never --overrides='[{"op":"add","path":"/spec/containers/0/resources","value":{"limits":{"cpu":"200m","memory":"128Mi"}}}]' --override-type json --command -- sh
然後,從您現在殼層進入的容器內執行下列命令。
# If you don't see a command prompt, try selecting Enter.
KUBE_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
curl -sSk -H "Authorization: Bearer $KUBE_TOKEN" https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT/api/v1/namespaces/default/pods
狀況良好的輸出看起來會如下所示。
{
"kind": "PodList",
"apiVersion": "v1",
"metadata": {
"selfLink": "/api/v1/namespaces/default/pods",
"resourceVersion": "2285"
},
"items": [
...
]
}
如果發生錯誤,請檢查服務及其端點是否 kubernetes-internal
狀況良好:
kubectl get service kubernetes-internal
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes-internal ClusterIP 10.96.0.1 <none> 443/TCP 25m
kubectl get endpoints kubernetes-internal
NAME ENDPOINTS AGE
kubernetes-internal 172.17.0.62:6443 25m
如果這兩個測試都傳回如上述的回應,且傳回的IP和埠符合容器的回應,則 kube-apiserver 可能未執行或遭到網路封鎖。
存取可能會遭到封鎖的主要原因有四個:
- 您的網路原則。 它們可能會防止存取 API 管理平面。 如需測試網路原則的資訊,請參閱 網路原則概觀。
- 您的 API 允許的 IP 位址。 如需解決此問題的相關信息,請參閱 更新叢集的 API 伺服器授權 IP 範圍。
- 您的私人防火牆。 如果您透過私人防火牆路由 AKS 流量,請確定有輸出規則,如 AKS 叢集所需的輸出網路規則和 FQDN 中所述。
- 您的私人 DNS。 如果您要裝載私人叢集,且無法連線到 API 伺服器,您的 DNS 轉寄站可能無法正確設定。 若要確保適當的通訊,請完成使用自定義 DNS 的樞紐輻射型模型中的步驟。
您也可以使用容器深入解析來檢查 kube-apiserver 記錄。 如需查詢 kube-apiserver 記錄和其他許多查詢的資訊,請參閱 如何從容器深入解析查詢記錄。
最後,您可以檢查 kube-apiserver 狀態及其叢集本身的記錄:
# Check kube-apiserver status.
kubectl -n kube-system get pod -l component=kube-apiserver
# Get kube-apiserver logs.
PODNAME=$(kubectl -n kube-system get pod -l component=kube-apiserver -o jsonpath='{.items[0].metadata.name}')
kubectl -n kube-system logs $PODNAME --tail 100
如果出現 403 - Forbidden
錯誤,可能是因為 kube-apiserver 已配置了角色型訪問控制(RBAC),而您的容器 ServiceAccount
尚未被授權存取資源。 在此情況下,您應該建立適當的 RoleBinding
和 ClusterRoleBinding
物件。 如需角色和角色系結的相關信息,請參閱 存取和身分識別。 如需如何在叢集上設定 RBAC 的範例,請參閱 使用 RBAC 授權。
貢獻者們
本文由 Microsoft 維護。 它最初是由下列參與者所撰寫。
主要作者:
- 邁克爾·沃爾特斯 |資深顧問
其他貢獻者:
- 米克·阿爾伯特斯 | 技術作家
- Ayobami Ayodeji |資深項目經理
- Bahram Rushenas |建築師