Dela via


Felsöka nätverksproblem i AKS-kluster

Nätverksproblem kan uppstå i nya installationer av Kubernetes eller när du ökar Kubernetes-belastningen. Andra problem som är relaterade till nätverksproblem kan också uppstå. Kontrollera alltid aks-felsökningsguiden för att se om problemet beskrivs där. Den här artikeln beskriver ytterligare information och överväganden från ett nätverksfelsökningsperspektiv och specifika problem som kan uppstå.

Klienten kan inte nå API-servern

Dessa fel omfattar anslutningsproblem som uppstår när du inte kan nå ett Azure Kubernetes Service-klusters API-server (AKS) via kubernetes-klustrets kommandoradsverktyg (kubectl) eller något annat verktyg, som REST API via ett programmeringsspråk.

Fel

Du kan se fel som ser ut så här:

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. 

Orsak 1

Det är möjligt att IP-intervall som auktoriseras av API-servern är aktiverade på klustrets API-server, men klientens IP-adress ingår inte i dessa IP-intervall. Om du vill ta reda på om IP-intervall är aktiverade använder du följande az aks show kommando i Azure CLI. Om IP-intervallen är aktiverade skapar kommandot en lista över IP-intervall.

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

Lösning 1

Kontrollera att klientens IP-adress ligger inom de intervall som godkänts av klustrets API-server:

  1. Hitta din lokala IP-adress. Information om hur du hittar den i Windows och Linux finns i Så här hittar du min IP-adress.

  2. Uppdatera intervallet som har auktoriserats av API-servern med hjälp az aks update av kommandot i Azure CLI. Auktorisera klientens IP-adress. Anvisningar finns i Uppdatera ett klusters API-serverauktoriserade IP-intervall.

Orsak 2

Om DITT AKS-kluster är ett privat kluster har API-serverslutpunkten ingen offentlig IP-adress. Du måste använda en virtuell dator som har nätverksåtkomst till AKS-klustrets virtuella nätverk.

Lösning 2

Information om hur du löser det här problemet finns i alternativ för att ansluta till ett privat kluster.

Podden kan inte allokera IP-adressen

Fel

Podden har fastnat i tillståndet ContainerCreating och dess händelser rapporterar ett Failed to allocate address fel:

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 

Eller ett not enough IPs available fel:

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'}]

Kontrollera de allokerade IP-adresserna i IPAM-plugin-arkivet. Du kanske upptäcker att alla IP-adresser allokeras, men antalet är mycket mindre än antalet poddar som körs:

Om du använder 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

Kommentar

För kubenet utan Calico är /var/lib/cni/networks/kubenetsökvägen . För kubenet med Calico är /var/lib/cni/networks/k8s-pod-networksökvägen . Skriptet ovan väljer sökvägen automatiskt när kommandot körs.

# 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 

Om du använder Azure CNI för dynamisk IP-allokering:

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

Orsak 1

Det här felet kan orsakas av en bugg i nätverks-plugin-programmet. Plugin-programmet kan inte frigöra IP-adressen när en podd avslutas.

Lösning 1

Kontakta Microsoft om du vill ha en lösning eller korrigering.

Orsak 2

Det går mycket snabbare att skapa poddar än skräpinsamling av avslutade poddar.

Lösning 2

Konfigurera snabb skräpinsamling för kubelet. Anvisningar finns i dokumentationen för Kubernetes-skräpinsamling.

Tjänsten är inte tillgänglig i poddar

Det första steget för att lösa det här problemet är att kontrollera om slutpunkter har skapats automatiskt för tjänsten:

kubectl get endpoints <service-name> 

Om du får ett tomt resultat kan tjänstens etikettväljare vara fel. Kontrollera att etiketten är korrekt:

# 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 

Om föregående steg returnerar förväntade värden:

  • Kontrollera om podden containerPort är samma som tjänsten containerPort.

  • Kontrollera om podIP:containerPort fungerar:

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

Det här är några andra möjliga orsaker till tjänstproblem:

  • Containern lyssnar inte på den angivna containerPort. (Kontrollera poddbeskrivningen.)
  • Ett CNI-plugin-fel eller nätverksvägsfel inträffar.
  • kube-proxy körs inte eller iptables-regler är inte korrekt konfigurerade.
  • Nätverksprinciper släpper trafik. Information om hur du tillämpar och testar nätverksprinciper finns i Översikt över Azure Kubernetes-nätverksprinciper.
    • Om du använder Calico som nätverksinsticksprogram kan du även samla in nätverksprinciptrafik. Information om hur du konfigurerar det finns på Calico-webbplatsen.

Noder kan inte nå API-servern

Många tillägg och containrar måste ha åtkomst till Kubernetes API (till exempel kube-dns- och operatorcontainrar). Om fel inträffar under den här processen kan följande steg hjälpa dig att fastställa orsaken till problemet.

Kontrollera först om Kubernetes-API:et är tillgängligt i poddar:

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

Kör sedan följande inifrån containern som du nu är uppskalad i.

# 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

Felfria utdata ser ut ungefär så här.

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

Om ett fel inträffar kontrollerar du om kubernetes-internal tjänsten och dess slutpunkter är felfria:

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 

Om båda testerna returnerar svar som föregående och IP-adressen och porten som returneras matchar dem för din container, är det troligt att kube-apiservern inte körs eller blockeras från nätverket.

Det finns fyra huvudsakliga orsaker till att åtkomsten kan blockeras:

Du kan också kontrollera kube-apiserverloggar med hjälp av Container Insights. Information om hur du kör frågor mot kube-apiserverloggar och många andra frågor finns i Fråga efter loggar från Container Insights.

Slutligen kan du kontrollera kube-apiserverstatusen och dess loggar i själva klustret:

# 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

Om ett 403 - Forbidden fel returneras konfigureras kube-apiserver förmodligen med rollbaserad åtkomstkontroll (RBAC) och containerns ServiceAccount har förmodligen inte behörighet att komma åt resurser. I det här fallet bör du skapa lämpliga RoleBinding objekt och ClusterRoleBinding objekt. Information om roller och rollbindningar finns i Åtkomst och identitet. Exempel på hur du konfigurerar RBAC i klustret finns i Använda RBAC-auktorisering.

Deltagare

Den här artikeln underhålls av Microsoft. Det har ursprungligen skrivits av följande medarbetare.

Huvudförfattare:

Övriga medarbetare:

Nästa steg