Beheben von Netzwerkproblemen in AKS-Clustern

Netzwerkprobleme können in neuen Installationen von Kubernetes auftreten oder wenn Sie die Kubernetes-Last erhöhen. Es können auch andere Probleme auftreten, die auf Netzwerkprobleme zurückzuführen sind. Lesen Sie immer im AKS-Handbuch zur Problembehandlung nach, ob Ihr Problem dort beschrieben wird. In diesem Artikel werden zusätzliche Details und Überlegungen zur Problembehandlung in Netzwerken sowie spezifische Probleme beschrieben, die auftreten können.

Client kann den API-Server nicht erreichen

Diese Fehler umfassen Verbindungsprobleme, die auftreten, wenn Sie den API-Server eines Azure Kubernetes Service (AKS)-Clusters nicht über das Befehlszeilentool (kubectl) des Kubernetes-Clusters oder ein anderes Tool, wie die REST-API über eine Programmiersprache, erreichen können.

Fehler

Möglicherweise werden Fehler angezeigt, die wie folgt aussehen:

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. 

Ursache 1

Es ist möglich, dass IP-Bereiche, die vom API-Server autorisiert sind, auf dem API-Server des Clusters aktiviert sind, aber die IP-Adresse des Clients in diesen IP-Bereichen nicht enthalten ist. Um zu ermitteln, ob IP-Bereiche aktiviert sind, verwenden Sie den Befehl az aks show in Azure CLI. Wenn die IP-Bereiche aktiviert sind, erzeugt der Befehl eine Liste der IP-Bereiche.

az aks show --resource-group <cluster-resource-group> \ 
    --name <cluster-name> \ 
    --query apiServerAccessProfile.authorizedIpRanges 

Lösung 1

Stellen Sie sicher, dass sich die IP-Adresse Ihres Clients innerhalb der vom API-Server des Clusters autorisierten Bereiche befindet:

  1. Suchen Sie Ihre lokale IP-Adresse. Informationen zum Suchen unter Windows und Linux finden Sie unter Wie ich meine IP finde.

  2. Aktualisieren Sie den vom API-Server autorisierten Bereich, indem Sie den Befehl az aks update in Azure CLI verwenden. Autorisieren Sie die IP-Adresse Ihres Clients. Anweisungen hierzu finden Sie unter Aktualisieren der autorisierten IP-Adressbereiche des API-Servers eines Clusters.

Ursache 2

Wenn Ihr AKS-Cluster ein privater Cluster ist, verfügt der Endpunkt des API-Servers nicht über eine öffentliche IP-Adresse. Sie müssen einen virtuellen Computer verwenden, der Netzwerkzugriff auf das virtuelle Netzwerk des AKS-Clusters hat.

Lösung 2

Informationen zum Beheben dieses Problems finden Sie unter Optionen zum Herstellen einer Verbindung mit einem privaten Cluster.

Pod ordnet die IP-Adresse nicht zu

Fehler

Der Pod bleibt im Zustand ContainerCreating hängen, und seine Ereignisse melden den Fehler 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 

Oder den Fehler 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'}]

Überprüfen Sie die zugeordneten IP-Adressen im Plug-In des IPAM-Speichers. Möglicherweise finden Sie heraus, dass zwar alle IP-Adressen zugewiesen werden, aber die Zahl viel kleiner als die Anzahl der ausgeführten Pods ist:

Bei Verwendung von 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

Hinweis

Für Kubenet ohne Calico lautet der Pfad /var/lib/cni/networks/kubenet. Für Kubenet mit Calico lautet der Pfad /var/lib/cni/networks/k8s-pod-network. Während der Befehl ausgeführt wird, wählt das obige Skript automatisch den Pfad aus.

# 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 

Bei Verwendung von Azure CNI für dynamische IP-Zuordnung:

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

Ursache 1

Dieser Fehler kann durch einen Bug im Netzwerk-Plug-In verursacht werden. Das Plug-In kann die IP-Adresse nicht freigeben, wenn ein Pod beendet wird.

Lösung 1

Wenden Sie sich an Microsoft, um das Problem zu umgehen oder eine Lösung zu finden.

Ursache 2

Die Poderstellung ist viel schneller als die automatische Speicherbereinigung beendeter Pods.

Lösung 2

Konfigurieren Sie eine schnelle Garbage Collection für das Kubelet. Anweisungen finden Sie in der Dokumentation zur Kubernetes Garbage Collection.

Zugriff auf den Dienst innerhalb der Pods nicht möglich

Der erste Schritt zum Beheben dieses Problems besteht darin, zu überprüfen, ob für den Dienst automatisch Endpunkte erstellt wurden:

kubectl get endpoints <service-name> 

Wenn Sie ein leeres Ergebnis erhalten, ist die Bezeichnungsauswahl Ihres Diensts möglicherweise falsch. Vergewissern Sie sich, dass die Bezeichnung richtig ist:

# 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 

Wenn die vorangehenden Schritte erwartete Werte zurückgeben:

  • Überprüfen Sie, ob der Pod containerPort dem Dienst containerPortentspricht.

  • Überprüfen Sie, ob podIP:containerPort funktioniert:

    # Testing via cURL. 
    curl -v telnet ://<Pod-IP>:<containerPort>
    
    # Testing via Telnet. 
    telnet <Pod-IP>:<containerPort> 
    

Es gibt noch einige andere mögliche Ursachen für Dienstprobleme:

  • Der Container überwacht nicht den angegebenen containerPort. (Überprüfen Sie die Pod-Beschreibung.)
  • Ein CNI-Plug-In-Fehler oder Netzwerkroutenfehler tritt auf.
  • kube-proxy wird nicht ausgeführt oder iptables-Regeln sind nicht ordnungsgemäß konfiguriert.
  • Die Netzwerkrichtlinien verwerfen den Datenverkehr. Informationen zum Anwenden und Testen von Netzwerkrichtlinien finden Sie unter Übersicht über Azure Kubernetes-Netzwerkrichtlinien.
    • Wenn Sie Calico als Netzwerk-Plug-In verwenden, können Sie auch Netzwerkrichtlinienverkehr aufzeichnen. Informationen zum Konfigurieren dieser Informationen finden Sie auf der Calico-Website.

Knoten können den API-Server nicht erreichen

Viele Add-Ons und Container müssen auf die Kubernetes-API zugreifen (z. B. kube-dns und Operator-Container). Wenn Fehler während dieses Prozesses auftreten, können die folgenden Schritte helfen, die Ursache des Problems zu ermitteln.

Vergewissern Sie sich zunächst, ob innerhalb der Pods ein Zugriff auf die Kubernetes-API möglich ist:

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

Führen Sie dann Folgendes von dem Container aus, in dem Sie sich jetzt befinden.

# 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

Die fehlerfreie Ausgabe sieht etwa wie folgt aus.

{ 
  "kind": "PodList", 
  "apiVersion": "v1", 
  "metadata": { 
    "selfLink": "/api/v1/namespaces/default/pods", 
    "resourceVersion": "2285" 
  }, 
  "items": [ 
   ... 
  ] 
} 

Wenn ein Fehler auftritt, überprüfen Sie, ob der Dienst kubernetes-internal und seine Endpunkte fehlerfrei sind:

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 

Wenn beide Tests Antworten wie die vorherigen zurückgeben, und die zurückgegebene IP und Port mit denen Ihres Containers übereinstimmen, ist es wahrscheinlich, dass kube-apiserver nicht ausgeführt wird oder vom Netzwerk blockiert wird.

Es gibt vier wesentlich Gründe, warum der Zugriff blockiert werden kann:

Sie können auch kube-apiserver-Protokolle mithilfe von Container Insights überprüfen. Informationen zum Abfragen von kube-apiserver-Protokollen und vielen anderen Abfragen finden Sie unter Abfragen von Protokollen aus Container Insights.

Schließlich können Sie den Status von kube-apiserver und dessen Protokolle im Cluster selbst überprüfen:

# 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

Wenn der Fehler 403 - Forbidden zurückgegeben wird, ist kube-apiserver wahrscheinlich mit rollenbasierter Zugriffssteuerung (RBAC) konfiguriert und der Container ServiceAccount ist wahrscheinlich nicht für den Zugriff auf Ressourcen berechtigt. In diesem Fall sollten Sie geeignete Objekte des Typs RoleBinding und ClusterRoleBinding erstellen. Informationen zu Rollen und Rollenbindungen finden Sie unter Zugriff und Identität. Beispiele zum Konfigurieren von RBAC auf Ihrem Cluster finden Sie unter Verwenden der RBAC-Autorisierung.

Beitragende

Dieser Artikel wird von Microsoft gepflegt. Er wurde ursprünglich von folgenden Mitwirkenden geschrieben:

Hauptautor:

Andere Mitwirkende:

Nächste Schritte