Introduction
L'architecture Kubernetes expliquée avec des exemples pratiques doit aider les opérateurs à passer d'un problème observé à un résultat vérifié. Commencez par identifier la version installée, la topologie de déploiement, les prérequis et le composant exact inspecté. Cet article se concentre sur l'architecture Kubernetes pour les développeurs, consultants DevOps et équipes techniques de startup. Il relie les composants Kubernetes, le flux de données Kubernetes, la conception Kubernetes et les opérations Kubernetes à des commandes, des sorties attendues, des signaux de défaillance et des décisions de récupération correspondant à la technologie sélectionnée.
L'objectif est la sécurité opérationnelle : observer avant de modifier, limiter le rayon d'impact, utiliser des espaces réservés au lieu de secrets, vérifier le résultat et documenter comment récupérer si l'état attendu n'est pas atteint. Chaque exemple inclut une commande concrète, sa sortie attendue et ce qu'il faut faire si la sortie diffère. Nous utilisons une application hypothétique appelée « webapp » s'exécutant dans l'espace de noms « production » pour tous les exemples.
Inventaire de la version et de l'environnement
Avant toute modification, capturez l'état actuel de votre cluster. Connaître la version exacte de Kubernetes et la santé des composants est le fondement d'opérations sûres. Le plan de contrôle (serveur API, etcd, gestionnaire de contrôleurs, planificateur) et les nœuds travailleurs (kubelet, kube-proxy, runtime de conteneurs) doivent être compatibles en version et en bonne santé.
Observation en lecture seule d'abord :
kubectl version --short
Sortie attendue (exemple) :
Client Version: v1.27.3
Kustomize Version: v5.0.1
Server Version: v1.27.3
Si les versions client et serveur diffèrent de plus d'une version mineure, mettez à niveau le client pour correspondre au serveur. Une erreur courante est Error from server (Forbidden): unknown lors de l'utilisation d'un client obsolète avec de nouvelles ressources API.
Vérifier l'état et la capacité des nœuds :
kubectl get nodes -o wide
Sortie attendue :
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
node-1 Ready control-plane 10d v1.27.3 10.0.0.1 <none> Ubuntu 22.04.3 LTS 5.15.0-91-generic containerd://1.6.21
node-2 Ready <none> 10d v1.27.3 10.0.0.2 <none> Ubuntu 22.04.3 LTS 5.15.0-91-generic containerd://1.6.21
Si un nœud est NotReady, investigatez avec kubectl describe node <nom-du-nœud> et vérifiez les journaux du kubelet. Sur ce nœud, exécutez journalctl -u kubelet -n 50 --no-pager pour voir les erreurs récentes du kubelet. Les causes courantes incluent la pression du disque, la pression de la mémoire ou des problèmes de plugin réseau.
Liste de contrôle des prérequis pour cette section :
- kubectl installé et configuré (
kubectl config current-contextrenvoie le bon cluster). - Accès au cluster avec au moins des autorisations en lecture seule sur les nœuds et les pods.
- Connaissance de base de la ligne de commande Linux.
- Le cluster est joignable (
kubectl get --raw='/readyz'renvoieok).
Exemple de compatibilité de version : Si votre cluster est en v1.27 et votre kubectl en v1.24, vous pourriez voir error: the server doesn't have a resource type "deployment" pour les versions d'API plus récentes. Gardez toujours kubectl à une version mineure près du serveur.
Chemin de configuration sûr
Les modifications de configuration dans Kubernetes peuvent être risquées. Suivez un chemin sûr : commencez par un manifeste local, validez-le, appliquez-le à un espace de noms de test, vérifiez, puis promouvez en production. N'appliquez jamais directement en production sans validation.
Commencez avec un manifeste de déploiement minimal pour la webapp :
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp
namespace: production
labels:
app: webapp
spec:
replicas: 2
selector:
matchLabels:
app: webapp
template:
metadata:
labels:
app: webapp
spec:
containers:
- name: webapp
image: nginx:1.25
ports:
- containerPort: 80
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "200m"
memory: "256Mi"
Validez le manifeste localement :
kubectl apply --dry-run=client -f webapp-deployment.yaml
Sortie attendue :
deployment.apps/webapp created (dry run)
S'il y a une erreur de syntaxe, kubectl affiche le numéro de ligne et la raison. Corrigez les erreurs avant de continuer.
Appliquez d'abord à un espace de noms de test (créez l'espace de noms si nécessaire) :
kubectl create namespace test
kubectl apply -f webapp-deployment.yaml -n test
Sortie attendue :
deployment.apps/webapp created
Vérifiez l'état du déploiement :
kubectl rollout status deployment/webapp -n test
Sortie attendue :
Waiting for deployment "webapp" rollout to finish: 1 of 2 updated replicas are available...
deployment "webapp" successfully rolled out
Si le déploiement échoue, utilisez kubectl describe deployment webapp -n test et vérifiez les événements pour les erreurs de tirage d'image, les dépassements de quota de ressources ou les échecs de sonde.
Vérifiez le trafic avec un Service et un transfert de port :
Créez un Service pour exposer le déploiement à l'intérieur du cluster :
apiVersion: v1
kind: Service
metadata:
name: webapp
namespace: test
spec:
selector:
app: webapp
ports:
- protocol: TCP
port: 80
targetPort: 80
Appliquez-le et utilisez le transfert de port pour y accéder localement :
kubectl apply -f webapp-service.yaml -n test
kubectl port-forward service/webapp 8080:80 -n test
Dans un autre terminal, exécutez :
curl http://localhost:8080
Sortie attendue : la page HTML de bienvenue nginx par défaut. Si vous voyez une connexion refusée, vérifiez si le pod est prêt avec kubectl get pods -n test et assurez-vous que le sélecteur de service correspond aux étiquettes du pod.
Enfin, promouvez en production après validation. Appliquez les mêmes manifestes à l'espace de noms de production, après avoir confirmé que la version de l'espace de noms de test fonctionne comme prévu et que les quotas de ressources en production permettent le déploiement.
Vérification et diagnostics
La vérification signifie confirmer que le système se comporte comme prévu. Le diagnostic signifie trouver la cause profonde lorsqu'il ne le fait pas. Kubernetes fournit des commandes puissantes pour les deux.
Vérifiez l'état et les détails des pods :
kubectl get pods -o wide -n production
Sortie attendue (exemple) :
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
webapp-6b8f9d7c4d-abcde 1/1 Running 0 5m 10.244.1.5 node-2 <none> <none>
webapp-6b8f9d7c4d-fghij 1/1 Running 0 5m 10.244.2.3 node-1 <none> <none>
Si un pod est en Pending, CrashLoopBackOff ou Error, utilisez kubectl describe pod <nom-du-pod> -n production pour voir les événements. Par exemple, FailedScheduling avec 0/2 nodes are available: 2 Insufficient cpu signifie que la demande de CPU dépasse la capacité disponible. Ajustez les demandes de ressources ou ajoutez des nœuds.
Vérifiez les journaux pour les erreurs d'application :
kubectl logs <nom-du-pod> -n production
Pour un conteneur planté, vérifiez les journaux précédents :
kubectl logs <nom-du-pod> --previous -n production
Exemple de ligne de journal utile :
2023/10/01 12:00:00 [error] 7#7: *1 connect() failed (111: Connection refused) while connecting to upstream
Cela indique que l'application ne peut pas se connecter à un service en amont. Vérifiez le nom DNS du Service et que le déploiement en amont est en cours d'exécution.
Vérifiez l'utilisation des ressources :
kubectl top pods -n production
Sortie attendue :
NAME CPU(cores) MEMORY(bytes)
webapp-6b8f9d7c4d-abcde 10m 50Mi
webapp-6b8f9d7c4d-fghij 12m 48Mi
Si les métriques ne sont pas disponibles, installez le serveur de métriques. Comparez l'utilisation réelle avec les limites pour détecter les éventuels arrêts OOM (Out Of Memory) ou les limitations CPU. Si l'utilisation de la mémoire est proche de la limite, augmentez la limite ou optimisez l'application.
Vérifiez les événements au niveau de l'espace de noms :
kubectl get events -n production --sort-by=.lastTimestamp
Recherchez des avertissements comme BackOff, FailedMount ou Unhealthy. Ceux-ci indiquent souvent des erreurs de configuration. Par exemple, FailedMount pour un secret indique un secret manquant ou mal nommé.
Modes de défaillance et récupération
Kubernetes est conçu pour être résilient, mais des défaillances surviennent encore. Connaître les modes de défaillance courants et les procédures de récupération est essentiel. Nous couvrons ici les plantages de pods, les défaillances de nœuds et les erreurs de configuration.
Boucle de plantage de pod :
Un pod plante et redémarre à plusieurs reprises. Diagnostiquez avec :
kubectl get pods -n production
Si STATUS affiche CrashLoopBackOff, vérifiez les journaux :
kubectl logs <nom-du-pod> -n production --previous
Causes courantes :
- Mauvaise configuration de l'application : variable d'environnement manquante, mauvaise chaîne de connexion à la base de données.
- Sonde de vivacité mal configurée : la sonde échoue même si l'application est saine. Ajustez les paramètres de la sonde.
- Mémoire insuffisante : pod tué avec OOM. Augmentez la limite de mémoire ou réduisez l'utilisation de la mémoire de l'application.
Exemple de récupération : Si le journal affiche Error: unable to open database file, assurez-vous que la PersistentVolumeClaim est liée et que le chemin est accessible en écriture. Ensuite, supprimez le pod pour forcer un redémarrage :
kubectl delete pod <nom-du-pod> -n production
Le contrôleur de déploiement le recréera. Si l'erreur persiste, corrigez la cause profonde dans la configuration de l'application.
Défaillance de nœud :
Si un nœud devient NotReady, les pods qui s'y trouvent seront évincés après un délai (par défaut 5 minutes). Pour vérifier l'état du nœud :
kubectl get nodes
Si node-2 est NotReady, décrivez-le :
kubectl describe node node-2
Recherchez Conditions et Events. Si le kubelet a cessé de publier son état, le nœud est peut-être en panne. Vérifiez la connectivité réseau et connectez-vous en SSH au nœud si possible. Vérifiez le service kubelet :
systemctl status kubelet
Si kubelet est arrêté, redémarrez-le :
sudo systemctl restart kubelet
Après le redémarrage, le nœud devrait redevenir Ready en une minute. Sinon, vérifiez les journaux kubelet pour des erreurs telles que des problèmes de certificat ou de runtime de conteneurs.
Erreur de configuration provoquant l'échec du déploiement :
Exemple : application d'un déploiement avec une étiquette d'image invalide.
kubectl apply -f webapp-deployment.yaml -n production
Vérifiez ensuite l'état du déploiement :
kubectl rollout status deployment/webapp -n production
S'il échoue avec error: deployment "webapp" exceeded its progress deadline, inspectez :
kubectl describe deployment webapp -n production
Recherchez des événements comme Failed to pull image "nginx:1.25-invalid". Pour récupérer, corrigez l'étiquette d'image et réappliquez :
kubectl set image deployment/webapp webapp=nginx:1.25 -n production
kubectl rollout status deployment/webapp -n production
Annuler un mauvais déploiement :
Si une nouvelle version cause des problèmes, revenez à la révision précédente :
kubectl rollout undo deployment/webapp -n production
Vérifiez l'historique :
kubectl rollout history deployment/webapp -n production
Sortie attendue :
REVISION CHANGE-CAUSE
1 <none>
2 <none>
Après l'annulation, vérifiez la santé des pods et les journaux d'application.
Liste de contrôle des opérations
Utilisez cette liste de contrôle pour les opérations quotidiennes afin de maintenir la santé et les performances du cluster. Chaque élément inclut la commande et le résultat attendu.
- Vérification de la santé du cluster
kubectl get --raw='/readyz?verbose'
Sortie attendue : [+]ping ok [+]log ok [+]etcd ok [+]informer-sync ok [+]poststarthook/start-kube-apiserver-admission-initializer ok ... readyz check passed Si une vérification échoue, investigatez le composant correspondant.
- Santé des nœuds
kubectl get nodes
Tous les nœuds doivent être Ready. Sinon, suivez les étapes de récupération de défaillance de nœud.
- Santé des pods
kubectl get pods --all-namespaces --field-selector=status.phase!=Running
Cela liste tous les pods qui ne sont pas en état Running. Investigatez tous les pods listés.
- Utilisation des ressources
kubectl top nodes
kubectl top pods -A --sort-by=cpu
Vérifiez les nœuds avec une utilisation élevée du CPU ou de la mémoire (plus de 80 %). Envisagez de mettre à l'échelle ou d'ajouter des nœuds.
- Événements et avertissements
kubectl get events -A --sort-by=.lastTimestamp | grep -i warning
Examinez les avertissements pour des problèmes potentiels.
- Expiration des certificats (si vous utilisez kubeadm)
kubeadm certs check-expiration
La sortie attendue montre le temps restant pour chaque certificat. Renouvelez s'il reste moins de 30 jours.
- Sauvegarde etcd (nœud du plan de contrôle)
ETCDCTL_API=3 etcdctl snapshot save /backup/etcd-$(date +%Y%m%d%H%M).db \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key
Vérifiez l'instantané :
ETCDCTL_API=3 etcdctl snapshot status /backup/etcd-<timestamp>.db
La sortie attendue inclut le hachage et la révision.
Assurez-vous que les journaux des conteneurs sont rotés pour éviter la pression du disque. Vérifiez la configuration du kubelet :
- Rotation des journaux
cat /var/lib/kubelet/config.yaml | grep -A4 containerLogMax
Exemple :
containerLogMaxSize: "10Mi"
containerLogMaxFiles: 5
Ajustez si nécessaire et redémarrez le kubelet.
Effectuez cette liste de contrôle quotidiennement ou au moins hebdomadairement, selon la criticité du cluster.
Conclusion
L'architecture Kubernetes expliquée avec des exemples pratiques n'est utile que si chaque recommandation est limitée à la version, observable et réversible lorsque la technologie le permet. Copier une commande sans vérifier les prérequis et la sortie attendue n'est pas une procédure opérationnelle. Cet article a fourni des commandes concrètes, des sorties attendues et des étapes de récupération pour des scénarios courants dans l'inventaire de version, la configuration sûre, la vérification, la récupération de défaillance et les opérations quotidiennes.
Comme prochaine étape, choisissez une vérification à faible risque pour l'architecture Kubernetes. Par exemple, exécutez kubectl get --raw='/readyz?verbose' et confirmez que toutes les vérifications passent. Enregistrez l'état actuel, comparez le résultat avec le signal attendu et examinez les dépendances telles que Docker, Helm et GitLab CI/CD si elles font partie de votre pipeline de livraison. Rappelez-vous de toujours observer avant de modifier, de limiter le rayon d'impact et de documenter les chemins de récupération. Avec ces pratiques, vous exploiterez vos clusters Kubernetes avec confiance et résilience.