## 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 Ubuntu 22.04.3 LTS 5.15.0-91-generic containerd://1.6.21 node-2 Ready 10d v1.27.3 10.0.0.2 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 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-context renvoie 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' renvoie ok ). 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 webapp-6b8f9d7c4d-fghij 1/1 Running 0 5m 10.244.2.3 node-1 Si un pod est en Pending , CrashLoopBackOff ou Error , utilisez kubectl describe 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 -n production Pour un conteneur planté, vérifiez les journaux précédents : kubectl logs --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 -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 -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 2 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-.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.