Condividi tramite


Risolvere i problemi di rete nei cluster del servizio Azure Kubernetes

I problemi di rete possono verificarsi nelle nuove installazioni di Kubernetes o quando si aumenta il carico kubernetes. Potrebbero verificarsi anche altri problemi correlati ai problemi di rete. Controllare sempre la guida alla risoluzione dei problemi del servizio Azure Kubernetes per verificare se il problema è descritto. Questo articolo descrive dettagli aggiuntivi e considerazioni da una prospettiva di risoluzione dei problemi di rete e problemi specifici che potrebbero verificarsi.

Il client non riesce a raggiungere il server API

Questi errori comportano problemi di connessione che si verificano quando non è possibile raggiungere un server API del cluster servizio Azure Kubernetes (servizio Azure Kubernetes) tramite lo strumento da riga di comando del cluster Kubernetes (kubectl) o qualsiasi altro strumento, ad esempio l'API REST tramite un linguaggio di programmazione.

Errore

Potrebbero essere visualizzati errori simili ai seguenti:

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. 

Causa 1

È possibile che gli intervalli IP autorizzati dal server API siano abilitati nel server API del cluster, ma l'indirizzo IP del client non è incluso in tali intervalli IP. Per determinare se gli intervalli IP sono abilitati, usare il comando seguente az aks show nell'interfaccia della riga di comando di Azure. Se gli intervalli IP sono abilitati, il comando genererà un elenco di intervalli IP.

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

Soluzione 1

Assicurarsi che l'indirizzo IP del client sia compreso negli intervalli autorizzati dal server API del cluster:

  1. Trovare l'indirizzo IP locale. Per informazioni su come trovarla in Windows e Linux, vedere Come trovare l'indirizzo IP.

  2. Aggiornare l'intervallo autorizzato dal server API usando il comando nell'interfaccia az aks update della riga di comando di Azure. Autorizzare l'indirizzo IP del client. Per istruzioni, vedere Aggiornare gli intervalli IP autorizzati del server API di un cluster.

Causa 2

Se il cluster del servizio Azure Kubernetes è un cluster privato, l'endpoint del server API non ha un indirizzo IP pubblico. È necessario usare una macchina virtuale con accesso di rete alla rete virtuale del cluster del servizio Azure Kubernetes.

Soluzione 2

Per informazioni su come risolvere questo problema, vedere opzioni per la connessione a un cluster privato.

Il pod non riesce ad allocare l'indirizzo IP

Errore

Il pod è bloccato nello ContainerCreating stato e i relativi eventi segnalano un Failed to allocate address errore:

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 

Oppure un not enough IPs available errore:

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

Controllare gli indirizzi IP allocati nell'archivio Gestione indirizzi IP plug-in. È possibile che tutti gli indirizzi IP siano allocati, ma il numero è molto inferiore al numero di pod in esecuzione:

Se si usa 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

Nota

Per kubenet senza Calico, il percorso è /var/lib/cni/networks/kubenet. Per kubenet con Calico, il percorso è /var/lib/cni/networks/k8s-pod-network. Lo script precedente selezionerà automaticamente il percorso durante l'esecuzione del comando.

# 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 

Se si usa Azure CNI per l'allocazione IP dinamica:

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

Causa 1

Questo errore può essere causato da un bug nel plug-in di rete. Il plug-in può non deallocare l'indirizzo IP quando un pod viene terminato.

Soluzione 1

Per una soluzione alternativa o una correzione, contattare Microsoft.

Causa 2

La creazione di pod è molto più veloce rispetto alla Garbage Collection dei pod terminati.

Soluzione 2

Configurare fast Garbage Collection per kubelet. Per istruzioni, vedere la documentazione di Garbage Collection di Kubernetes.

Servizio non accessibile all'interno dei pod

Il primo passaggio per risolvere questo problema consiste nel verificare se gli endpoint sono stati creati automaticamente per il servizio:

kubectl get endpoints <service-name> 

Se si ottiene un risultato vuoto, il selettore di etichette del servizio potrebbe non essere corretto. Verificare che l'etichetta sia corretta:

# 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 

Se i passaggi precedenti restituiscono i valori previsti:

  • Controllare se il pod containerPort è uguale a quello del servizio containerPort.

  • Controllare se podIP:containerPort funziona:

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

Ecco alcune altre possibili cause di problemi di servizio:

  • Il contenitore non è in ascolto dell'oggetto specificato containerPort. Controllare la descrizione del pod.
  • Si è verificato un errore del plug-in CNI o un errore di route di rete.
  • kube-proxy non è in esecuzione o le regole iptables non sono configurate correttamente.
  • I criteri di rete stanno rilasciando il traffico. Per informazioni sull'applicazione e il test dei criteri di rete, vedere Panoramica dei criteri di rete di Azure Kubernetes.
    • Se si usa Calico come plug-in di rete, è anche possibile acquisire il traffico dei criteri di rete. Per informazioni sulla configurazione, vedere il sito Calico.

I nodi non possono raggiungere il server API

Molti componenti aggiuntivi e contenitori devono accedere all'API Kubernetes, ad esempio contenitori kube-dns e operatore. Se si verificano errori durante questo processo, la procedura seguente consente di determinare l'origine del problema.

Prima di tutto, verificare se l'API Kubernetes è accessibile all'interno dei 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

Eseguire quindi il comando seguente dall'interno del contenitore in cui si esegue la shell.

# 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

L'output integro sarà simile al seguente.

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

Se si verifica un errore, verificare se il kubernetes-internal servizio e i relativi endpoint sono integri:

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 

Se entrambi i test restituiscono risposte come quelle precedenti e l'INDIRIZZO IP e la porta restituiti corrispondono a quelli per il contenitore, è probabile che kube-apiserver non sia in esecuzione o sia bloccato dalla rete.

Esistono quattro motivi principali per cui l'accesso potrebbe essere bloccato:

  • Criteri di rete. Potrebbero impedire l'accesso al piano di gestione API. Per informazioni sui test dei criteri di rete, vedere Panoramica dei criteri di rete.
  • Indirizzi IP consentiti dell'API. Per informazioni sulla risoluzione di questo problema, vedere Aggiornare gli intervalli IP autorizzati del server API di un cluster.
  • Firewall privato. Se si instrada il traffico del servizio Azure Kubernetes attraverso un firewall privato, assicurarsi che siano presenti regole in uscita, come descritto in Regole di rete in uscita necessarie e FQDN per i cluster del servizio Azure Kubernetes.
  • DNS privato. Se si ospita un cluster privato e non si riesce a raggiungere il server API, i server d'inoltro DNS potrebbero non essere configurati correttamente. Per garantire una comunicazione corretta, completare i passaggi in Hub e spoke con DNS personalizzato.

È anche possibile controllare i log kube-apiserver usando Informazioni dettagliate sui contenitori. Per informazioni sull'esecuzione di query sui log kube-apiserver e su molte altre query, vedere Come eseguire query sui log da Informazioni dettagliate sui contenitori.

Infine, è possibile controllare lo stato di kube-apiserver e i relativi log nel cluster stesso:

# 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

Se viene restituito un 403 - Forbidden errore, kube-apiserver è probabilmente configurato con il controllo degli accessi in base al ruolo e probabilmente il contenitore ServiceAccount non è autorizzato ad accedere alle risorse. In questo caso, è necessario creare oggetti e ClusterRoleBinding appropriatiRoleBinding. Per informazioni sui ruoli e sulle associazioni di ruoli, vedere Accesso e identità. Per esempi di come configurare il controllo degli accessi in base al ruolo nel cluster, vedere Uso dell'autorizzazione del controllo degli accessi in base al ruolo.

Collaboratori

Questo articolo viene gestito da Microsoft. Originariamente è stato scritto dai seguenti contributori.

Autore principale:

Altri contributori:

Passaggi successivi