Aller au contenu
Conteneurs & Orchestration medium

Déployer et gérer des applications avec Kubernetes

22 min de lecture

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.

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

Section intitulée « 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.

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.

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

Fenêtre de terminal
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é.

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

Fenêtre de terminal
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.

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

Fenêtre de terminal
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.

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

Fenêtre de terminal
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

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

Fenêtre de terminal
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 :

Fenêtre de terminal
kubectl get rs

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

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

Fenêtre de terminal
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 :

Fenêtre de terminal
kubectl rollout history deployment/echo-server
deployment.apps/echo-server
REVISION CHANGE-CAUSE
2 <none>
3 <none>
4 <none>

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

Fenêtre de terminal
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 :

Fenêtre de terminal
kubectl rollout undo deployment/echo-server --to-revision=2

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

Fenêtre de terminal
kubectl scale deployment/echo-server --replicas=5

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

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

Fenêtre de terminal
kubectl delete deployment mon-app-deployment

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

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.

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.

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)

Section intitulée « 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.

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.

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)

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.

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.

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

Fenêtre de terminal
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.

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

Fenêtre de terminal
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 :

Fenêtre de terminal
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.

Fenêtre de terminal
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).

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

Fenêtre de terminal
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.

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

Fenêtre de terminal
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.

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

Fenêtre de terminal
kubectl exec -it blue-deployment-6c84db459d-6zmsv -- sh

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

Fenêtre de terminal
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

Section intitulée « 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é :

Fenêtre de terminal
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é :

Fenêtre de terminal
curl http://<NODE-IP>:<NODE-PORT>

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

Fenêtre de terminal
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:).

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 :

Fenêtre de terminal
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 :

Fenêtre de terminal
kubectl apply -f mon-deployment.yml

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

Fenêtre de terminal
kubectl rollout restart deployment blue-deployment

Cela recrée les pods avec la nouvelle configuration.

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

Fenêtre de terminal
kubectl delete pod blue-deployment-6c84db459d-6zmsv

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

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

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.

Autres points importants qui n’est pas abordé dans ce guide :

  • l’utilisation des Health Checks (probes) 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.
  • la définition des ressources et des limites pour chaque conteneur afin d’optimiser l’utilisation des ressources du cluster et d’éviter les problèmes de performance. Pour en savoir plus, consultez mon guide sur les requests et limits Kubernetes.