Résoudre les problèmes réseau dans les clusters AKS

Des problèmes réseau peuvent se produire dans de nouvelles installations de Kubernetes ou lorsque vous augmentez la charge Kubernetes. D’autres problèmes liés à la mise en réseau peuvent également se produire. Consultez toujours le guide de résolution des problèmes AKS pour voir si votre problème est décrit ici. Cet article inclut des détails et considérations supplémentaires du point de vue de la résolution des problèmes réseau et des problèmes spécifiques qui peuvent survenir.

Le client ne peut pas atteindre le serveur d’API

Ces erreurs impliquent des problèmes de connexion qui se produisent lorsque vous ne pouvez pas atteindre le serveur d’API d’un cluster Azure Kubernetes Service (AKS) via l’outil de ligne de commande du cluster Kubernetes (kubectl) ou tout autre outil, comme l’API REST via un langage de programmation.

Error

Vous pouvez voir des erreurs semblables à ce qui suit :

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. 

Cause 1

Il est possible que les plages d’adresses IP autorisées par le serveur d’API soient activées sur le serveur d’API du cluster, mais que l’adresse IP du client ne soit pas incluse dans ces plages d’adresses IP. Pour déterminer si les plages d’adresses IP sont activées, utilisez la commande az aks show suivante dans Azure CLI. Si les plages d’adresses IP sont activées, la commande produit une liste de plages d’adresses IP.

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

Solution 1

Vérifiez que l’adresse IP de votre client se trouve dans les plages autorisées par le serveur d’API du cluster :

  1. Recherchez votre adresse IP locale. Pour plus d’informations sur la façon de la trouver sur Windows et Linux, consultez Comment trouver mon adresse IP.

  2. Mettez à jour la plage autorisée par le serveur d’API à l’aide de la commande az aks update dans Azure CLI. Autorisez l’adresse IP de votre client. Pour obtenir des instructions, voir Mettre à jour les plages d’adresses IP autorisées du serveur d’API d’un cluster.

Cause 2

Si votre cluster AKS est un cluster privé, le point de terminaison du serveur d’API n’a pas d’adresse IP publique. Vous devez utiliser une machine virtuelle disposant d’un accès réseau au réseau virtuel du cluster AKS.

Solution 2

Pour plus d’informations sur la résolution de ce problème, consultez les options de connexion à un cluster privé.

Le pod ne parvient pas à allouer l’adresse IP

Error

Le pod est bloqué dans l’état ContainerCreating et ses événements signalent une erreur 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 

Ou une erreur 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'}]

Vérifiez les adresses IP allouées dans le store IPAM du plug-in. Vous pouvez constater que toutes les adresses IP sont allouées, mais que le nombre est très inférieur au nombre de pods en cours d’exécution :

Si vous utilisez 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

Remarque

Pour kubenet sans Calico, le chemin est le suivant : /var/lib/cni/networks/kubenet. Pour kubenet avec Calico, le chemin est le suivant : /var/lib/cni/networks/k8s-pod-network. Le script ci-dessus sélectionnera automatiquement le chemin d'accès lors de l'exécution de la commande.

# 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 

Si vous utilisez Azure CNI pour l'allocation dynamique des adresses 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

Cause 1

Cette erreur peut être due à un bogue dans le plug-in réseau. Il est possible que le plug-in ne puisse pas libérer l’adresse IP lorsqu’un pod est arrêté.

Solution 1

Contactez Microsoft pour obtenir une solution de contournement ou un correctif.

Cause 2

La création de pods est beaucoup plus rapide que le nettoyage de la mémoire des pods arrêtés.

Solution 2

Configurez le nettoyage de la mémoire rapide pour kubelet. Pour obtenir des instructions, consultez la documentation relative au nettoyage de la mémoire Kubernetes.

Service non accessible dans les pods

La première étape pour résoudre ce problème consiste à vérifier si les points de terminaison ont été créés automatiquement pour le service :

kubectl get endpoints <service-name> 

Si vous obtenez un résultat vide, le sélecteur d’étiquette de votre service peut être incorrect. Vérifiez que l’étiquette est correcte :

# 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 

Si les étapes précédentes retournent les valeurs attendues :

  • Vérifiez si le pod containerPort est identique au service containerPort.

  • Vérifiez si podIP:containerPort fonctionne :

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

Voici d’autres causes potentielles de problèmes de service :

  • Le conteneur n’écoute pas le containerPort spécifié. (Consultez la description du pod.)
  • Une erreur de plug-in CNI ou une erreur d’itinéraire réseau se produit.
  • kube-proxy n’est pas en cours d’exécution ou les règles iptables ne sont pas configurées correctement.
  • Les stratégies réseau suppriment le trafic. Pour plus d’informations sur l’application et le test des stratégies réseau, consultez Vue d’ensemble des stratégies réseau Azure Kubernetes.
    • Si vous utilisez Calico comme plug-in réseau, vous pouvez également capturer le trafic de stratégie réseau. Pour plus d’informations sur la configuration de ce paramètre, consultez le site Calico.

Les nœuds ne peuvent pas atteindre le serveur d’API

De nombreux modules complémentaires et conteneurs doivent accéder à l’API Kubernetes (par exemple, kube-dns et les conteneurs d’opérateurs). Si des erreurs se produisent pendant ce processus, les étapes suivantes peuvent vous aider à déterminer la source du problème.

Tout d’abord, vérifiez si l’API Kubernetes est accessible dans les pods :

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

Exécutez ensuite ce qui suit à partir du conteneur dans lequel vous êtes maintenant en 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

Voici un exemple de résultat sain.

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

Si une erreur se produit, vérifiez si le service kubernetes-internal et ses points de terminaison sont sains :

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 

Si les deux tests retournent des réponses comme celles précédentes et que l’adresse IP et le port retournés correspondent à celles de votre conteneur, il est probable que kube-apiserver n’est pas en cours d’exécution ou est bloqué sur le réseau.

L’accès peut être bloqué pour quatre principales raisons :

Vous pouvez également vérifier les journaux kube-apiserver à l’aide de Container Insights. Pour plus d’informations sur l’interrogation des journaux kube-apiserver et de nombreuses autres requêtes, consultez Comment interroger des journaux à partir de Container Insights.

Enfin, vous pouvez vérifier l’état de kube-apiserver et ses journaux sur le cluster lui-même :

# 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

Si une erreur 403 - Forbidden est retournée, kube-apiserver est probablement configuré avec le contrôle d’accès en fonction du rôle (RBAC) et il est probable que le ServiceAccount de votre conteneur ne soit pas autorisé à accéder aux ressources. Dans ce cas, vous devez créer des objets RoleBinding et ClusterRoleBinding appropriés. Pour plus d’informations sur les rôles et liaisons de rôle, consultez Access et identité. Pour obtenir des exemples de configuration du contrôle d’accès en fonction du rôle sur votre cluster, consultez Utilisation de l’autorisation RBAC.

Contributeurs

Cet article est géré par Microsoft. Il a été écrit à l’origine par les contributeurs suivants.

Auteur principal :

Autres contributeurs :

Étapes suivantes