Aller au contenu

Déployer et gérer des applications avec Kubernetes

Mise à jour :

logo kubernetes

Dans Kubernetes, un deployment est une ressource essentielle pour gérer le déploiement et la mise à jour des applications. Il permet de s’assurer que le bon nombre de pods est en cours d’exécution, de gérer les mises à jour sans interruption et de faciliter les rollbacks en cas de problème.

C’est quoi un Deployment ?

Un Deployment Kubernetes est une ressource permettant de déployer et de gérer un ensemble de pods de manière déclarative. Il assure la disponibilité des applications, gère les mises à jour et permet de revenir facilement à une version précédente en cas de problème.

Contrairement à la création manuelle de pods, un deployment offre plusieurs avantages :

  • Automatisation des déploiements : Kubernetes crée et gère les pods en fonction des règles définies.
  • Haute disponibilité et Scalabilité : le nombre de réplicas est contrôlé pour garantir qu’un minimum de pods soit toujours en fonctionnement.
  • Mises à jour progressives (Rolling Updates) : les nouvelles versions sont déployées sans interruption de service.
  • Rollback simplifié : en cas de problème, il est possible de revenir rapidement à une version précédente.

Un deployment repose sur plusieurs concepts clés :

  • ReplicaSet : il gère la création et la suppression des pods pour garantir le bon nombre d’instances en cours d’exécution.
  • Labels et Selectors : ils permettent d’identifier et de regrouper les pods associés à un deployment.
  • Stratégies de mise à jour : Kubernetes peut appliquer différentes méthodes pour déployer une nouvelle version sans interruption.

Création et gestion d’un deployement Kubernetes

Un deployment Kubernetes permet de déployer une application sous forme de pods tout en assurant leur gestion automatique. Il définit le nombre de réplicas, l’image du conteneur à utiliser et la manière dont les mises à jour seront appliquées.

Définir un deployment avec un manifeste YAML

Un deployment est généralement défini à l’aide d’un fichier YAML. Voici un exemple de définition pour une application web défini avec le fichier mon-deployment.yaml :

mon-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: echo-server
labels:
app: echo
spec:
replicas: 3
selector:
matchLabels:
app: echo
template:
metadata:
labels:
app: echo
spec:
containers:
- name: echo-container
image: hashicorp/http-echo:0.2.3
args:
- "-text=Hello Kubernetes!"
ports:
- containerPort: 5678

Explication des paramètres :

  • kind : type de ressource (ici, deployment).
  • metadata : contient le nom du deployment et des labels pour l’identifier.
  • spec.replicas : définit le nombre de pods à maintenir en fonctionnement.
  • spec.selector.matchLabels : sélectionne les pods associés à ce deployment grâce à un label commun.
  • spec.template : définit le modèle des pods à créer.
    • metadata.labels : permet d’attribuer des labels aux pods.
    • spec.containers : liste des conteneurs à exécuter dans chaque pod.
    • image : spécifie l’image du conteneur utilisée pour l’application.
    • ports : indique les ports ouverts sur le conteneur.

Déployer une application

Une fois le fichier YAML créé, appliquez-le avec kubectl :

Terminal window
kubectl apply -f mon-deployment.yaml

Kubernetes va alors créer les pods et s’assurer que le nombre de réplicas définis est bien respecté.

Vérifier l’état du deployment

Une fois déployé, vous pouvez vérifier son état avec :

Terminal window
kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
echo-server 3/3 3 3 50s
  • READY : indique le nombre de pods en cours d’exécution sur le total demandé.
  • UP-TO-DATE : montre combien de pods ont été mis à jour avec la dernière configuration.
  • AVAILABLE : indique combien de pods sont accessibles.
  • AGE : temps écoulé depuis la création du deployment.

Vérifier les replicasets créés

Un Deployment crée toujours un ReplicaSet pour gérer les Pods. Après le déploiement, vous pouvez voir le ReplicaSet correspondant :

Terminal window
kubectl get rs
NAME DESIRED CURRENT READY AGE
echo-server-6b6dbd58d6 3 3 3 10s

Ici, echo-server-6b6dbd58d6 est le ReplicaSet géré automatiquement par Kubernetes pour ce Deployment.

Vérifier les pods créés

Pour afficher les pods générés par ce deployment :

Terminal window
kubectl get pods -l app=echo
NAME READY STATUS RESTARTS AGE
echo-server-6b6dbd58d6-bk5bq 1/1 Running 0 94s
echo-server-6b6dbd58d6-d9smp 1/1 Running 0 94s
echo-server-6b6dbd58d6-xjh7s 1/1 Running 0 94s

Mettre à jour un deployment

Pour modifier l’image du conteneur et effectuer un Rolling Update :

Terminal window
kubectl set image deployment/echo-server echo-container=hashicorp/http-echo:1.0.0
deployment.apps/echo-server image updated

Lorsqu’une mise à jour est effectuée, Kubernetes ne met pas à jour les Pods existants, mais crée un nouveau ReplicaSet. L’ancien est conservé jusqu’à ce que tous les nouveaux Pods soient prêts. Vous pouvez voir l’évolution des ReplicaSets avec :

Terminal window
kubectl get rs

Cela affichera à la fois l’ancien et le nouveau ReplicaSet, ce qui permet un rollback rapide si nécessaire.

Vérifier et suivre une mise à jour

Après avoir lancé la mise à jour, surveillez son avancement avec :

Terminal window
kubectl rollout status deployment/echo-server
Waiting for deployment "echo-server" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "echo-server" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "echo-server" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "echo-server" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "echo-server" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "echo-server" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "echo-server" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "echo-server" rollout to finish: 1 old replicas are pending termination...
deployment "echo-server" successfully rolled out

Si un problème survient, vous pouvez voir l’historique des mises à jour :

Terminal window
kubectl rollout history deployment/echo-server
deployment.apps/echo-server
REVISION CHANGE-CAUSE
2 <none>
3 <none>
4 <none>

Annuler une mise à jour (Rollback)

En cas de problème avec la nouvelle version, vous pouvez revenir à la précédente :

Terminal window
kubectl rollout undo deployment/echo-server

Lorsqu’un rollback est effectué, Kubernetes réactive l’ancien ReplicaSet en supprimant progressivement les Pods de la version récente et en redémarrant ceux de l’ancienne version.

Si vous souhaitez revenir à une version spécifique, identifiez-la avec la commande d’historique et utilisez :

Terminal window
kubectl rollout undo deployment/echo-server --to-revision=2

Ajuster le nombre de pods (Scaling)

Si votre application nécessite plus de ressources, vous pouvez ajuster dynamiquement le nombre de pods :

Terminal window
kubectl scale deployment/echo-server --replicas=5

Kubernetes ajoutera automatiquement deux pods supplémentaires pour atteindre un total de cinq.

Supprimer un deployment

Si vous n’avez plus besoin du deployment, vous pouvez le supprimer avec :

Terminal window
kubectl delete deployment mon-app-deployment

Cela supprimera le deployment ainsi que tous les pods associés.

Les différentes stratégies de déploiement

Un deployment Kubernetes permet de gérer les mises à jour des applications sans interruption de service. Kubernetes propose plusieurs stratégies de déploiement adaptées aux besoins de disponibilité et de contrôle des mises en production.

1. Rolling Update (Mise à jour progressive)

Le Rolling Update est la stratégie par défaut des deployments Kubernetes. Elle remplace progressivement les anciens pods par de nouveaux sans provoquer d’interruption de service.

Avantages :

  • Assure une transition fluide entre les versions.
  • Évite les temps d’arrêt.
  • Permet de revenir à une version précédente en cas d’échec.

Exemple de définition d’un deployment avec un Rolling Update :

apiVersion: apps/v1
kind: Deployment
metadata:
name: rolling-update-demo
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
template:
metadata:
labels:
app: demo
spec:
containers:
- name: demo-container
image: hashicorp/http-echo:0.2.3
  • maxUnavailable: 1 → Un seul pod peut être indisponible pendant la mise à jour.
  • maxSurge: 1 → Un nouveau pod peut être créé en plus du nombre initial.

2. Recreate (Redémarrage total)

La stratégie Recreate supprime tous les anciens pods avant de créer les nouveaux. Elle est utile lorsque l’application ne peut pas gérer plusieurs versions en parallèle, par exemple lorsqu’elle repose sur une base de données qui ne supporte pas plusieurs connexions simultanées de différentes versions.

Avantages :

  • Évite les conflits entre versions.
  • Assure un environnement propre avant le redémarrage.

Inconvénients :

  • Temps d’arrêt pendant le déploiement.

Exemple d’un deployment avec une stratégie Recreate :

apiVersion: apps/v1
kind: Deployment
metadata:
name: recreate-demo
spec:
replicas: 3
strategy:
type: Recreate
template:
metadata:
labels:
app: demo
spec:
containers:
- name: demo-container
image: hashicorp/http-echo:0.2.3

3. Blue-Green Deployment (Déploiement en parallèle)

Le Blue-Green Deployment consiste à exécuter deux versions d’une application en parallèle :

  • La version actuelle (blue) reste en production.
  • La nouvelle version (green) est déployée sur un autre ensemble de pods.

Une fois le déploiement validé, le trafic est redirigé vers la nouvelle version en mettant à jour le service Kubernetes.

Avantages :

  • Permet de tester la nouvelle version avant de basculer.
  • Retour en arrière instantané en cas de problème.

Inconvénients :

  • Double consommation de ressources pendant la transition.

Exemple de mise en œuvre avec deux deployments et un Service unique :

apiVersion: apps/v1
kind: Deployment
metadata:
name: blue-deployment
spec:
replicas: 3
selector:
matchLabels:
app: demo
version: blue
template:
metadata:
labels:
app: demo
version: blue
spec:
containers:
- name: demo-container
image: hashicorp/http-echo:0.2.3
args:
- "-text=Hello from Kubernetes"
ports:
- containerPort: 5678

La mise à jour s’effectue en changeant le selector du Service pour pointer vers version: green.

4. Canary deployment (Déploiement progressif)

Le Canary Deployment consiste à déployer la nouvelle version de l’application sur un petit nombre de pods avant de généraliser la mise à jour. Cela permet de tester la nouvelle version en conditions réelles et de détecter d’éventuels problèmes avant un déploiement complet.

Avantages :

  • Déploiement progressif, réduisant les risques.
  • Possibilité d’ajuster le trafic envoyé à la nouvelle version.

Inconvénients :

  • Complexité de mise en œuvre.

Exemple de Deployment canary avec 10 % des pods sur la nouvelle version :

apiVersion: apps/v1
kind: Deployment
metadata:
name: stable-deployment
spec:
replicas: 9
template:
metadata:
labels:
app: demo
version: stable
spec:
containers:
- name: demo-container
image: hashicorp/http-echo:0.2.3
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: canary-deployment
spec:
replicas: 1
template:
metadata:
labels:
app: demo
version: canary
spec:
containers:
- name: demo-container
image: hashicorp/http-echo:0.2.4

Un ingress controller ou un service mesh comme Istio permet ensuite de diriger un pourcentage du trafic vers les nouveaux pods.

Comparaison des stratégies

StratégieInterruption ?Facilité de rollbackConsommation de ressources
Rolling UpdateNonOuiStandard
RecreateOuiNonFaible
Blue-GreenNonOui (instantané)Élevée (2 versions en parallèle)
CanaryNonOui (progressif)Élevée (2 versions en parallèle)

Conclusion

Le choix de la stratégie dépend des besoins de l’application :

  • Rolling Update est recommandé pour la plupart des cas.
  • Recreate est utile lorsque l’ancienne version ne peut pas coexister avec la nouvelle.
  • Blue-Green permet un basculement instantané en cas de problème.
  • Canary est idéal pour tester progressivement une mise à jour.

Debug des deployments Kubernetes

Lorsque l’on déploie une application sur Kubernetes, il est courant de rencontrer des problèmes comme des pods qui ne démarrent pas, des erreurs réseau ou des configurations incorrectes. Ce guide explique comment diagnostiquer et résoudre les erreurs liées aux deployments Kubernetes, en prenant l’exemple du blue/green deployment utilisant l’image hashicorp/http-echo:0.2.3.

Vérifier l’état du deployment

La première étape consiste à vérifier si Kubernetes a bien déployé les pods attendus.

Terminal window
kubectl get deployment blue-deployment
NAME READY UP-TO-DATE AVAILABLE AGE
blue-deployment 0/3 3 0 2m

Problème potentiel : 0/3 READY signifie qu’aucun pod n’est en état de fonctionnement.

Vérifier l’état des ReplicaSets

Si après une mise à jour vous constatez que certains Pods ne sont pas correctement mis à jour, vérifiez si plusieurs ReplicaSets existent toujours :

Terminal window
kubectl get rs

Si plusieurs ReplicaSets sont affichés, cela signifie que Kubernetes est encore en train de gérer la transition entre les versions. Vous pouvez voir quels Pods appartiennent à quel ReplicaSet avec :

Terminal window
kubectl get pods --show-labels

Cela permet d’identifier les Pods qui n’ont pas encore été supprimés et de vérifier leur état.

Lister les pods associés au deployment

Terminal window
kubectl get pods -l app=demo,version=blue
NAME READY STATUS RESTARTS AGE
blue-deployment-6c84db459d-6zmsv 0/1 CrashLoopBackOff 3 2m
blue-deployment-6c84db459d-fghij 0/1 Pending 0 2m
blue-deployment-6c84db459d-klmno 0/1 Running 0 2m

Problèmes détectés :

  • CrashLoopBackOff : le conteneur redémarre en boucle (peut être dû à une erreur dans l’image ou les arguments).
  • Pending : le pod ne démarre pas (peut être un problème de ressources ou d’ordonnancement).

Obtenir des détails sur un pod en échec

Si un pod ne démarre pas, utilisez describe pour obtenir plus d’informations :

Terminal window
kubectl describe pod blue-deployment-6c84db459d-6zmsv

Cela affiche un rapport détaillé, y compris :

  • Événements récents (Events:) qui indiquent des erreurs de déploiement.
  • Statut du conteneur (State:) avec des erreurs comme OOMKilled (problème mémoire) ou ImagePullBackOff (erreur d’image).

Exemple d’erreur courante dans Events: :

Warning Failed 2m kubelet Error: container has runAsNonRoot and image will run as root

Problème possible : le conteneur essaie de s’exécuter en tant que root mais la politique de sécurité l’interdit.

Analyser les logs du conteneur

Si un pod est en CrashLoopBackOff, il faut vérifier ses logs pour comprendre pourquoi il échoue.

Terminal window
kubectl logs blue-deployment-6c84db459d-6zmsv
Missing -text option!

Cause du problème : L’image hashicorp/http-echo nécessite un argument -text, et s’il est absent, le conteneur ne démarre pas.

Correction : Ajouter args: ["-text=Hello from Kubernetes"] dans la définition du Deployment.

Se connecter à un pod pour des tests interactifs

Si le pod tourne, mais que l’application ne répond pas, il est possible d’ouvrir un shell à l’intérieur du conteneur :

Terminal window
kubectl exec -it blue-deployment-6c84db459d-6zmsv -- sh

Une fois connecté, testez si l’application écoute bien sur le bon port :

Terminal window
curl http://localhost:5678

Si aucune réponse n’est retournée, cela signifie que l’application ne fonctionne pas correctement à l’intérieur du pod.

Vérifier l’état des services exposant le Deployment

Si l’application tourne, mais reste inaccessible depuis l’extérieur, vérifiez l’état du Service associé :

Terminal window
kubectl get service demo-service

Si le type du service est NodePort, testez l’accès via l’IP du nœud et le port exposé :

Terminal window
curl http://<NODE-IP>:<NODE-PORT>

Si l’application ne répond pas, vérifiez si les endpoints sont bien créés :

Terminal window
kubectl get endpoints demo-service

Si la sortie est vide, cela signifie que le Service ne cible pas les pods correctement. Vérifiez les labels des pods et ceux du Service (selector:).

Vérifier les ressources et quotas

Si les pods restent en Pending, il est possible que les nœuds n’aient pas assez de ressources. Vérifiez les événements du pod :

Terminal window
kubectl describe pod blue-deployment-6c84db459d-fghij

Exemple d’erreur :

Warning FailedScheduling 1m default-scheduler 0/3 nodes are available: insufficient memory.

Solution : Augmenter les ressources disponibles ou réduire les demandes de ressources dans le Deployment :

resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "256Mi"

Appliquez ensuite la mise à jour avec :

Terminal window
kubectl apply -f mon-deployment.yml

Redémarrer un Deployment après une correction

Si une erreur de configuration a été corrigée, redémarrez le Deployment :

Terminal window
kubectl rollout restart deployment blue-deployment

Cela recrée les pods avec la nouvelle configuration.

Supprimer un pod pour forcer son remplacement

Si un pod reste bloqué, vous pouvez le supprimer manuellement :

Terminal window
kubectl delete pod blue-deployment-6c84db459d-6zmsv

Kubernetes recréera automatiquement un nouveau pod grâce au Deployment.

Résumé des commandes de debug essentielles

CommandeUtilisation
kubectl get deploymentsVérifier l’état du Deployment
kubectl get pods -l app=demo,version=blueLister les pods associés
kubectl describe pod <nom-du-pod>Afficher les détails et les erreurs
kubectl logs <nom-du-pod>Voir les logs du conteneur
kubectl exec -it <nom-du-pod-- shSe connecter à l’intérieur du conteneur
kubectl get service demo-serviceVérifier l’état du Service
kubectl get endpoints demo-serviceVérifier si le Service cible bien les pods
kubectl rollout restart deployment blue-deploymentRedémarrer un Deployment
kubectl delete pod <nom-du-pod>Forcer le remplacement d’un pod défectueux

Conclusion

Le debug des Deployments Kubernetes repose sur une approche méthodique : analyser l’état des pods, vérifier les logs, tester la connectivité et ajuster la configuration si nécessaire. En utilisant les outils intégrés comme kubectl describe, kubectl logs et kubectl exec, il est possible d’identifier et de corriger rapidement les erreurs. Une bonne gestion des mises à jour, des ressources et des services assure un déploiement fiable et performant des applications.

Autre point important qui n’est pas abordé dans ce guide : l’utilisation des Health Checks (sondes de santé) pour surveiller l’état des applications et automatiser leur redémarrage en cas de problème. Ces sondes permettent de détecter les pannes et de garantir la disponibilité des services. Tout est expliqué dans mon guide sur les probes Kubernetes.