Kadmy - Fotolia

Administration Kubernetes : les 5 dépannages à connaître

De nombreux facteurs peuvent être à l’origine d’une baisse de performance dans un cluster de containers. Cet article explique comment traquer et résoudre les problèmes les plus courants sous Kubernetes.

Kubernetes est un système complexe à dépanner. C’est une chose de reconnaître qu’un cluster de containers est indisponible ou qu’un pod ne répond pas comme prévu. Mais c’en est une autre de déterminer la cause de ces problèmes et la manière de les résoudre.

Plusieurs situations peuvent être à l’origine de problèmes nécessitant un dépannage : des nœuds indisponibles, des containers qui ne répondent pas, des problèmes liés au plan de contrôle ou d’autres encore, liés à la connectivité réseau. Vous pouvez résoudre ces problèmes en affectant suffisamment de nœuds à un cluster, en utilisant des espaces de noms et des quotas de ressources, en exécutant des commandes pour dépanner les pods qui ne répondent pas, etc.

Voici ci-dessous les cinq scénarios de pannes Kubernetes les plus courantes et comment les résoudre.

Des nœuds indisponibles

Kubernetes distribue les applications sur plusieurs nœuds de travail (« workers »). Il s’agit de serveurs physiques ou virtuels qui composent un cluster Kubernetes. Kubernetes s’appuie par ailleurs sur des serveurs qui ont le rôle de plan de contrôle (« control-plane ») pour héberger les services qui gèrent le cluster. Si un cluster ne dispose pas d’un nombre suffisant de nœuds workers pour soutenir les exigences du plan de contrôle et de toutes les applications que vous souhaitez exécuter, vous risquez de constater une dégradation des performances des applications, voire des défaillances.

Pour résoudre ce problème, il faut d’abord s’assurer qu’un nombre suffisant de nœuds workers est affecté au cluster. Le nombre minimum de nœuds dont un cluster a besoin dépend de facteurs tels que la quantité de mémoire et de processeurs sur chaque nœud au regard des besoins de vos applications. Pour les clusters de petite taille, prévoyez au moins un nœud worker pour deux applications à exécuter. Si vous souhaitez obtenir une haute disponibilité, vous devez disposer d’au moins deux serveurs control-plane. Un plus grand nombre de serveurs control-plane est encore mieux.

Si vous pensez avoir suffisamment de nœuds, mais que vous rencontrez toujours des problèmes, utilisez un outil de surveillance de l’infrastructure pour observer les serveurs qui fonctionnent comme des nœuds. Observez les quantités de mémoire et de puissance CPU consommées sur chaque nœud. Si l’utilisation totale des ressources dépasse environ 85 % du total des ressources disponibles, vos nœuds ne sont pas en mesure d’héberger vos applications. Ajoutez des nœuds supplémentaires à votre cluster ou augmentez les ressources qui leur sont allouées pour répondre aux charges de travail.

Toutefois, le fait de disposer d’un nombre suffisant de nœuds ne garantit pas une stabilité permanente. Les nœuds peuvent tomber en panne une fois que vous les avez configurés et ajoutés à un cluster. La plupart des fournisseurs de cloud et des plateformes de virtualisation sur site proposent des fonctions de reprise d’activité automatique qui redémarrent automatiquement une machine défaillante.

Si tous vos nœuds sont des machines virtuelles hébergées sur le même serveur physique, l’ensemble de votre cluster tombera en panne si ce serveur tombe en panne. Répartissez les nœuds sur un plus grand nombre de serveurs physiques afin de limiter les dommages causés à votre cluster par la défaillance d’un serveur physique.

Des ressources surutilisées

Le problème des ressources surutilisées (dit des « voisins bruyants ») est un problème courant dans un cluster Kubernetes multitenant, c’est-à-dire dont le pool de ressources est mis à la disposition de plusieurs services pour qu’ils exécutent chacun leurs charges de travail. Afin de résoudre ce problème, configurez Kubernetes avec les informations dont il a besoin pour attribuer le bon nombre de ressources à chaque charge de travail. Vous pouvez le faire au niveau des containers ou des pods individuels, en utilisant le paramètre Limit Ranges. Celui-ci configure les ressources maximales qu’un container ou qu’un pod peut consommer.

Utilisez les espaces de noms pour diviser un cluster unique en différents espaces virtuels. Ensuite, utilisez la fonction de quotas de ressources de Kubernetes pour limiter la quantité de ressources qu’un espace de noms unique peut consommer. Cela permet d’éviter qu’un espace de noms utilise plus que sa juste part de ressources. Les quotas de ressources s’appliquent à l’ensemble d’un espace de noms et ne peuvent pas contrôler le comportement des applications individuelles au sein du même espace de noms. Pour ce faire, utilisez Limit Ranges.

Des containers non réactifs

Même si vous configurez des plages de limites et des quotas de ressources appropriés pour vos containers, pods et espaces de noms, vous pouvez découvrir que vos containers ou pods ne répondent pas. Pour dépanner les containers ou les pods qui ne répondent pas, exécutez la commande suivante :

kubectl get pods --all-namespaces

Spécifiez le nom d’un module particulier et/ou d’un espace de noms en particulier pour affiner l’action de cette commande. La sortie répertorie tous vos modules et leur état dans un format tel que le suivant :

NAME                                           	READY   STATUS          	RESTARTS       	   AGE
ml-pipeline-685b7b74d-6pvdr                    	0/1 	ContainerCreating   0              	   294d
minio-65dff76b66-xk8jt                         	0/1 	Pending         	0              	   13s
mysql-67f7987d45-fqmw8                         	0/1 	Pending         	0              	   20s
proxy-agent-bff474798-sqc8g                    	0/1 	CrashLoopBackOff	1545 (2m13s ago)   294d

Dans ce scénario, un pod est dans l’état ContainerCreating, ce qui signifie qu’il est encore en train de lancer ses containers. Deux autres pods sont en attente, ce qui signifie que le pod n’a pas encore été planifié sur un nœud. Le dernier pod est dans l’état CrashLoopBackOff. Cela se produit généralement lorsque Kubernetes tente de redémarrer un pod, mais que celui-ci continue de se bloquer.

Obtenez des détails supplémentaires sur l’état d’un pod et des containers qu’il contient à l’aide de la commande suivante :

kubectl describe pods --all-namespaces

La sortie vous indique l’état détaillé des pods. Par exemple, voici les détails du pod bloqué dans l’état CrashLoopBackOff.

Name:         	proxy-agent-bff474798-sqc8g
Namespace:    	kubeflow
Priority:     	0
Service Account:  proxy-agent-runner
Node:         	chris-gazelle/192.168.0.107
Start Time:   	Sun, 12 Nov 2023 12:37:32 -0500
Labels:       	app=proxy-agent
              	application-crd-id=kubeflow-pipelines
              	pod-template-hash=bff474798
Annotations:  	<none>
Status:       	Running
IP:           	192.168.0.107
IPs:
  IP:       	192.168.0.107
Controlled By:  ReplicaSet/proxy-agent-bff474798
Containers:
  proxy-agent:
	Container ID:   containerd://dae867f6ff4434d50e68161fd1602889e09d0bd17486968bbee41a9fac32d7bb
	Image:      	gcr.io/ml-pipeline/inverse-proxy-agent:1.8.5
	Image ID:   	gcr.io/ml-pipeline/inverse-proxy-agent@sha256:a16f99d14ae724b94b403cb9d7ac8d8f4adce33ef6a24dd91306048c0c02c7e4
	Port:       	<none>
	Host Port:  	<none>
	State:      	Waiting
  	Reason:   	CrashLoopBackOff
	Last State: 	Terminated
  	Reason:   	Error
  	Exit Code:	6
  	Started:  	Mon, 15 Jan 2024 12:58:09 -0500
  	Finished: 	Mon, 15 Jan 2024 12:58:09 -0500
	Ready:      	False
	Restart Count:  1546
	Environment:	<none>
	Mounts:
  	/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-fsjrz (ro)
Conditions:
  Type          	Status
  Initialized   	True
  Ready         	False
  ContainersReady   False
  PodScheduled  	True
Volumes:
  kube-api-access-fsjrz:
	Type:                	Projected (a volume that contains injected data from multiple sources)
	TokenExpirationSeconds:  3607
	ConfigMapName:       	kube-root-ca.crt
	ConfigMapOptional:   	<nil>
	DownwardAPI:         	true
QoS Class:               	BestEffort
Node-Selectors:          	<none>
Tolerations:             	node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                         	node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type 	   Reason   Age                	   From 	Message
  ---- 	   ------   ---               	   ---- 	-------
  Warning  BackOff  44s (x21022 over 41d)  kubelet  Back-off restarting failed container

Ces informations fournissent plus d’indices sur la façon dont le module est configuré et sur la raison pour laquelle il continue à se bloquer. Pour résoudre le problème de l’échec, essayez ce qui suit :

  • Assurez-vous que l’image du container spécifiée dans la sortie de kubectl describe pods est disponible et qu’elle n’est pas corrompue.
  • Essayez d’exécuter le container directement à partir de la ligne de commande pour voir s’il démarre sans problème. Si c’est le cas, le problème est probablement lié à la manière dont le pod est configuré plutôt qu’au container lui-même.
  • Vérifiez la configuration du stockage et des secrets pour vous assurer qu’ils ne sont pas à l’origine de l’échec du pod.

Il se peut que vous deviez consulter les logs du container ou de l’application pour obtenir des informations supplémentaires sur l’état des pods et des containers qui ne répondent pas. L’emplacement de ces logs peut varier en fonction de l’endroit où vos containers et pods écrivent les données de log.

Une mauvaise configuration des sondes d’état peut également être à l’origine de problèmes. Kubernetes utilise des sondes de disponibilité pour vérifier si un container est réactif. Si ce n’est pas le cas, Kubernetes redémarre le container. Les sondes de disponibilité déterminent si un container ou un ensemble de containers sont en place et prêts à accepter du trafic.

Ces sondes sont une bonne protection contre les situations où vous devez redémarrer manuellement un container défaillant ou lorsque les containers ne sont pas encore complètement initialisés et, par conséquent, ne sont pas prêts pour le trafic. Cependant, des sondes de disponibilité et d’état de fonctionnement trop agressives peuvent entraîner l’indisponibilité des containers.

Prenons l’exemple d’une sonde de disponibilité qui vérifie un container toutes les secondes et le redémarre si elle détermine qu’il ne répond pas. Dans certaines situations, la congestion du réseau ou les problèmes de latence font que la vérification de l’état de préparation prend plus d’une seconde, même si le container s’exécute sans problème. Par conséquent, Kubernetes redémarrera constamment le container, ce qui le rendra indisponible.

Pour éviter cela, configurez les sondes de disponibilité de manière logique pour les containers et les variables d’environnement. Évitez les configurations uniformes. Chaque container doit avoir ses propres règles.

Des problèmes liés au plan de contrôle

Le plan de contrôle Kubernetes est l’ensemble des services et des agents qui gèrent le cluster, attribuent des pods aux nœuds, etc. Si votre plan de contrôle tombe en panne, votre cluster peut se comporter de manière étrange ou échouer complètement. Des bogues logiciels ou des ressources insuffisantes sur les nœuds du plan de contrôle peuvent provoquer une défaillance de ce dernier.

Vérifiez l’état de votre plan de contrôle à l’aide de la commande suivante :

kubectl cluster-info

Le résultat ressemble à ce qui suit :

Kubernetes control plane is running at https://127.0.0.1:6443
CoreDNS is running at https://127.0.0.1:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
Metrics-server is running at https://127.0.0.1:6443/api/v1/namespaces/kube-system/services/https:metrics-server:https/proxy

Ces informations indiquent l’état du plan de contrôle et des services associés, tels que CoreDNS dans cet exemple. Si un service ne fonctionne pas comme prévu, exécutez la commande suivante pour obtenir des détails sur son état.

kubectl cluster-info dump

Si le problème ne ressort pas clairement de la commande cluster-info dump, consultez les logs du plan de contrôle. Dans la plupart des cas, vous les trouverez dans le répertoire /var/log de vos nœuds constituant le plan de contrôle.

Les problèmes de connectivité réseau

Les problèmes liés à la configuration de votre réseau Kubernetes peuvent empêcher une application en cours d’exécution d’être visible par d’autres applications ou services. Il n’existe pas de processus simple pour dépanner les réseaux Kubernetes. Toutefois, les étapes de base sont les suivantes :

  • Connectez-vous directement au nœud hôte d’une application à l’aide de SSH ou d’un protocole similaire et essayez d’envoyer un ping ou de vous connecter à l’application à partir de là. Si vous pouvez atteindre l’application depuis le nœud, mais pas depuis l’extérieur, un problème de NAT ou de pare-feu est probablement à l’origine du problème de connectivité.
  • Vérifiez les fichiers syslog des nœuds de votre cluster pour y trouver des événements et des erreurs liés à la mise en réseau.
  • Exécutez la commande tcpdump sur un nœud qui peut collecter le trafic circulant entre les pods ou les containers. Ensuite, inspectez les paquets à l’aide d’un outil tel que Wireshark pour vérifier les erreurs telles que les sommes de contrôle des paquets.

Si un équilibreur de charge externe est utilisé, assurez-vous que le service d’équilibrage de charge externe est opérationnel et que la configuration de votre équilibreur de charge pointe correctement vers lui.

Si vous rencontrez des problèmes de connectivité, redéployez l’application avec des paramètres de réseau plus simples. Par exemple, utilisez un service ClusterIP au lieu d’un équilibreur de charge pour vérifier si le problème persiste dans cette configuration. Si ce n’est pas le cas, modifiez les variables de configuration réseau une à une jusqu’à ce que vous identifiiez celle qui rend votre application inaccessible.

Pour approfondir sur Administration de systèmes