Introduction
L'architecture de déploiement Kubernetes expliquée avec des exemples pratiques devrait aider les opérateurs à passer d'un problème observé à un résultat vérifié. Cet article relie les composants d'un déploiement, le flux de données, la conception et les opérations à des commandes concrètes, des sorties attendues, des signaux d'échec et des décisions de récupération. L'objectif est la sécurité opérationnelle : observer avant de modifier, limiter le rayon d'impact, utiliser des espaces réservés plutôt que des secrets, vérifier le résultat et documenter comment récupérer si l'état attendu n'est pas atteint.
Tout au long de ce guide, nous utiliserons un exemple courant : une application web appelée payments-api déployée dans l'espace de noms production. Nous commencerons par un manifeste de déploiement minimal, puis ajouterons progressivement des contrôles de santé, des limites de ressources, des stratégies de déploiement, l'autoscaling et des techniques de dépannage. Chaque section comprend des commandes prêtes à copier-coller et des extraits de sortie réalistes afin que vous puissiez reproduire les étapes sur votre propre cluster.
Inventaire des versions et de l'environnement
Avant de toucher à un déploiement, confirmez la version de Kubernetes, la version de l'API de déploiement et les contrôleurs disponibles. Les différentes versions de Kubernetes modifient le comportement par défaut des mises à jour progressives, de l'arrêt des pods et des champs immuables. Exécutez les commandes suivantes pour capturer l'environnement :
kubectl version --short
# Exemple de sortie :
# Client Version: v1.27.3
# Kustomize Version: v5.0.1
# Server Version: v1.27.3
Vérifiez la version de l'API de l'objet déploiement que vous prévoyez d'utiliser. Depuis Kubernetes 1.16, apps/v1 est la version stable. extensions/v1beta1 et apps/v1beta2 sont supprimées dans les versions plus récentes et échoueront à l'application. Vérifiez avec :
kubectl api-versions | grep apps
# Attendu : apps/v1
Vérifiez également que le contrôleur de déploiement s'exécute dans kube-system :
kubectl get pods -n kube-system | grep deployment-controller
# Attendu : kube-controller-manager-<node> en cours d'exécution
Observation en lecture seule d'abord
Capturez l'état actuel de tous les déploiements pertinents avant de les modifier :
kubectl get deployments --all-namespaces -o wide
kubectl get replicasets --all-namespaces | grep payments-api
# Portez attention aux colonnes DESIRED, CURRENT, READY
Si vous soupçonnez un problème, décrivez le déploiement sans rien modifier :
kubectl describe deployment payments-api -n production
# Regardez les événements, les conditions et les identifiants OldReplicaSets/NewReplicaSet
Ce n'est qu'après avoir compris l'état actuel que vous planifiez le plus petit changement justifié. Par exemple, si trois réplicas échouent avec ImagePullBackOff, le plus petit changement pourrait être de corriger l'étiquette d'image dans le manifeste, pas de réduire ou de supprimer le déploiement.
Chemin de configuration sécurisé
Un déploiement sécurisé commence par un manifeste minimal et paramétré. Évitez de coder en dur les secrets, utilisez des ConfigMaps pour les paramètres non confidentiels et définissez les demandes et limites de ressources dès le premier jour.
Manifeste de déploiement minimal
Créez un fichier nommé payments-api-deployment.yaml :
apiVersion: apps/v1
kind: Deployment
metadata:
name: payments-api
namespace: production
labels:
app: payments-api
tier: backend
spec:
replicas: 3
selector:
matchLabels:
app: payments-api
template:
metadata:
labels:
app: payments-api
tier: backend
spec:
containers:
- name: payments-api
image: registry.example.com/payments-api:1.4.2
ports:
- containerPort: 8080
name: http
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: payments-api-secrets
key: database-url
- name: LOG_LEVEL
value: "info"
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "256Mi"
readinessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 15
periodSeconds: 20
Appliquez-le et vérifiez :
kubectl apply -f payments-api-deployment.yaml
kubectl rollout status deployment/payments-api -n production --timeout=90s
# Attendu : deployment "payments-api" successfully rolled out
Vérifiez que les trois pods sont en cours d'exécution et prêts :
kubectl get pods -n production -l app=payments-api -o wide
# NAME READY STATUS RESTARTS AGE
# payments-api-6b7f8d9c4d-abcde 1/1 Running 0 2m
# payments-api-6b7f8d9c4d-fghij 1/1 Running 0 2m
# payments-api-6b7f8d9c4d-klmno 1/1 Running 0 2m
Paramétrage avec Kustomize
Pour éviter de modifier le YAML pour chaque environnement, utilisez Kustomize. Créez un kustomization.yaml :
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- payments-api-deployment.yaml
namespace: production
images:
- name: registry.example.com/payments-api
newTag: 1.4.3
commonLabels:
environment: production
Appliquez ensuite avec kubectl apply -k .. Cela met à jour l'étiquette d'image sans modifier le manifeste de base, réduisant ainsi les erreurs humaines.
Vérification et diagnostics
Après avoir appliqué un déploiement, vérifiez toujours que le déploiement a réussi et que les nouveaux pods servent effectivement le trafic. Utilisez à la fois les commandes de déploiement et l'inspection au niveau des pods.
Historique et statut du déploiement
kubectl rollout history deployment/payments-api -n production
# REVISION CHANGE-CAUSE
# 1 <none>
# 2 kubectl set image deployment/payments-api payments-api=registry.example.com/payments-api:1.4.3 --record=true
Pour voir la spécification exacte utilisée dans une révision :
kubectl rollout history deployment/payments-api -n production --revision=2
Diagnostics au niveau des pods
Si un nouveau pod ne devient pas prêt, exécutez :
kubectl describe pod payments-api-<pod-hash> -n production
# Cherchez les événements : FailedScheduling, FailedMount, CrashLoopBackOff, Unhealthy
Pour les boucles de crash, récupérez les journaux de l'instance précédente du conteneur :
kubectl logs payments-api-<pod-hash> -n production --previous --tail=200
Vérification du trafic en direct
Pour un test local rapide sans équilibreur de charge public, utilisez le transfert de port :
kubectl port-forward deployment/payments-api 8080:8080 -n production
# Forwarding from 127.0.0.1:8080 -> 8080
Dans un autre terminal :
curl -f http://localhost:8080/healthz
# Attendu : {"status":"ok"}
Si la sonde de préparation échoue, le pod ne recevra pas de trafic même si le transfert de port est établi. Vérifiez la définition de la sonde et les journaux des points de terminaison.
Modes de défaillance et récupération
Les déploiements peuvent échouer pour de nombreuses raisons : erreurs d'extraction d'image, ressources insuffisantes, sondes mal configurées, quota dépassé ou blocage de la mise à jour progressive. Savoir comment détecter et récupérer de chacun est essentiel.
ImagePullBackOff
Symptôme : le pod reste dans ImagePullBackOff ou ErrImagePull.
kubectl get pods -n production
# NAME READY STATUS RESTARTS AGE
# payments-api-7c8d9f6b5d-xyzab 0/1 ImagePullBackOff 0 5m
Diagnostiquez :
kubectl describe pod payments-api-7c8d9f6b5d-xyzab -n production | grep -A5 Events
# Failed to pull image "registry.example.com/payments-api:1.4.3": rpc error: code = NotFound desc = failed to pull and unpack image
Récupération : vérifiez que l'étiquette d'image existe dans le registre. Sinon, revenez à une révision précédente :
kubectl rollout undo deployment/payments-api -n production
# deployment.apps/payments-api rolled back
CrashLoopBackOff
Symptôme : le pod redémarre à plusieurs reprises, statut CrashLoopBackOff.
Diagnostiquez les journaux :
kubectl logs payments-api-7c8d9f6b5d-xyzab -n production --previous
# Error: could not connect to database at postgres:5432
Récupération : corrigez l'erreur de configuration (par exemple, corrigez l'URL de la base de données dans le Secret) et appliquez le manifeste mis à jour. Ensuite, surveillez :
kubectl apply -f payments-api-deployment.yaml
kubectl rollout status deployment/payments-api -n production
Mise à jour progressive bloquée
Symptôme : le rollout status expire et le nouveau ReplicaSet ne devient jamais disponible.
Vérifiez le statut du déploiement :
kubectl get deployment payments-api -n production -o yaml | grep -A10 conditions
# - lastTransitionTime: "2023-09-20T10:00:00Z"
# message: Deployment does not have minimum availability.
# reason: MinimumReplicasUnavailable
Cause fréquente : les valeurs maxUnavailable et maxSurge sont trop restrictives, ou le cluster manque de ressources. Affichez les événements :
kubectl describe deployment payments-api -n production | grep -A10 Events
# ScalingReplicaSet: Scaled up replica set payments-api-7c8d9f6b5d to 3
# FailedCreate: pods "payments-api-7c8d9f6b5d-" is forbidden: exceeded quota
Récupération : augmentez le quota de ressources de l'espace de noms, ajustez maxUnavailable pour autoriser plus de pods indisponibles (par exemple, maxUnavailable: 1, maxSurge: 1), ou revenez en arrière.
Quota dépassé
Symptôme : la création de pod échoue avec exceeded quota.
Vérifiez le quota de ressources :
kubectl describe resourcequota -n production
# Name: compute-resources
# Resource Used Hard
# -------- ---- ----
# requests.cpu 900m 2
# requests.memory 900Mi 2Gi
Récupération : réduisez les demandes de ressources dans le déploiement, réduisez d'autres charges de travail ou demandez un quota plus élevé à l'administrateur du cluster. Ce n'est pas un problème de déploiement mais un problème de capacité de l'espace de noms.
Liste de contrôle des opérations
Utilisez cette liste de contrôle pour tout changement de déploiement en production :
- Capturez la référence : exécutez
kubectl get deployment <name> -n <ns> -o yaml > baseline.yamlavant les modifications. - Examinez le diff : utilisez
kubectl diff -f updated-deployment.yamlpour voir ce qui va changer. - Vérifiez les paramètres de déploiement : assurez-vous que
strategy.rollingUpdate.maxUnavailableetmaxSurgesont définis sur des valeurs sûres (par exemple,maxUnavailable: 0pour zéro temps d'arrêt,maxSurge: 1). - Définissez la limite de l'historique des révisions :
revisionHistoryLimit: 10pour permettre le retour en arrière et éviter l'encombrement. - Appliquez avec enregistrement : utilisez
kubectl apply -f updated-deployment.yaml --recordpour enregistrer la commande dans l'historique de déploiement (obsolète dans les versions plus récentes ; utilisez des annotations à la place). - Surveillez le déploiement : exécutez
kubectl rollout status deployment/<name> -n <ns> --timeout=120set ne continuez pas tant qu'il n'est pas terminé. - Vérifiez les pods : vérifiez le statut des pods, la préparation et les journaux pour le nouveau ReplicaSet.
- Testez les points de terminaison : utilisez le transfert de port ou l'ingress pour atteindre les points de terminaison de santé et principaux de la nouvelle version.
- Surveillez les métriques : vérifiez le CPU, la mémoire et les taux d'erreur pour les nouveaux pods dans votre pile de surveillance.
- Documentez le plan de retour en arrière : connaissez la commande exacte
kubectl rollout undoet testez-la d'abord dans un environnement de préproduction.
Exemple de séquence de commandes pour une mise à jour de type canari
Si vous souhaitez déplacer progressivement le trafic, vous pouvez créer un deuxième déploiement avec une étiquette différente et utiliser un sélecteur de service pour répartir le trafic. Pour plus de simplicité, voici une approche manuelle en deux étapes :
# Étape 1 : Mettez à jour avec maxSurge=1, maxUnavailable=0 pour éviter les temps d'arrêt
kubectl patch deployment payments-api -n production -p '{"spec":{"strategy":{"rollingUpdate":{"maxSurge":1,"maxUnavailable":0}}}}'
kubectl apply -f payments-api-deployment.yaml
# Étape 2 : Si des problèmes surviennent, revenez immédiatement en arrière
kubectl rollout undo deployment/payments-api -n production
Cela vous donne un retour en arrière rapide tout en maintenant la disponibilité pendant la mise à jour.
Conclusion
L'architecture de déploiement Kubernetes expliquée avec des exemples pratiques n'est utile que si chaque recommandation est limitée à une 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 d'exploitation.
Comme prochaine étape, choisissez une vérification à faible risque pour votre déploiement : exécutez kubectl rollout history, inspectez le ReplicaSet actuel, testez une mise à jour progressive avec maxUnavailable: 0 dans un espace de noms de préproduction et documentez la commande exacte d'annulation. Appliquez ensuite progressivement la même discipline à la production.
Un flux de travail technique fiable rend les échecs visibles, protège les valeurs sensibles, limite les modifications à la ressource prévue et définit la vérification de récupération avant qu'un incident ne force la décision. En combinant les commandes, les exemples de manifestes et les playbooks de récupération de cet article, vous pouvez exploiter les déploiements Kubernetes en toute confiance.