
Déployer une application sur Kubernetes consiste à déclarer comment elle doit tourner, puis à lui donner un point d’accès stable. Dans ce guide, vous allez créer un namespace, déployer nginx avec un Deployment, l’exposer via un Service, vérifier qu’il répond, puis observer son comportement quand vous augmentez le nombre de réplicas.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Créer un namespace pour organiser votre application
- Déployer une application avec
kubectl create deployment - Exposer l’application avec un Service
- Comprendre le lien entre labels, sélecteurs et endpoints
- Scaler et observer l’application
- Voir ce que Kubernetes fait en arrière-plan
Ce que vous allez créer
Section intitulée « Ce que vous allez créer »À la fin de ce guide, vous aurez :
Namespace demo-app├── Deployment nginx│ └── ReplicaSet│ └── 3 Pods nginx (label: app=nginx)└── Service nginx └── sélectionne les Pods avec app=nginx- Un namespace
demo-apppour organiser les ressources - Un Deployment qui gère des Pods nginx via un ReplicaSet
- Un Service qui cible les Pods portant le label
app=nginx
Étape 1 : Créer un namespace dédié
Section intitulée « Étape 1 : Créer un namespace dédié »Un namespace organise et isole logiquement vos ressources dans le cluster. C’est une bonne habitude à prendre dès le début.
kubectl create namespace demo-appnamespace/demo-app createdVérifiez qu’il existe :
kubectl get namespace demo-appNAME STATUS AGEdemo-app Active 5sÉtape 2 : Créer un Deployment
Section intitulée « Étape 2 : Créer un Deployment »Un Deployment dit à Kubernetes : “je veux X pods qui exécutent cette image”.
Méthode impérative (pour apprendre)
Section intitulée « Méthode impérative (pour apprendre) »La commande kubectl create deployment crée un Deployment en une ligne :
kubectl create deployment nginx --image=nginx:1.28 -n demo-appdeployment.apps/nginx created| Option | Signification |
|---|---|
nginx | Nom du Deployment |
--image=nginx:1.28 | Image Docker à utiliser (version figée) |
-n demo-app | Namespace cible |
Vérifiez que le Deployment est prêt
Section intitulée « Vérifiez que le Deployment est prêt »kubectl get deployment nginx -n demo-appNAME READY UP-TO-DATE AVAILABLE AGEnginx 1/1 1 1 10s| Colonne | Signification |
|---|---|
READY | Pods prêts / Pods souhaités |
UP-TO-DATE | Pods à jour avec la dernière configuration |
AVAILABLE | Pods qui peuvent servir du trafic |
1/1 signifie : 1 pod est prêt sur 1 demandé. Quand ces chiffres correspondent, le déploiement est opérationnel.
Voir le ReplicaSet créé
Section intitulée « Voir le ReplicaSet créé »Le Deployment ne crée pas directement les Pods. Il passe par un ReplicaSet :
kubectl get replicasets -n demo-appNAME DESIRED CURRENT READY AGEnginx-6d8867d6c 1 1 1 15sLe Deployment a créé un ReplicaSet (nginx-6d8867d6c), qui lui-même crée et surveille les Pods. Vous n’avez pas besoin de manipuler le ReplicaSet directement — c’est le Deployment qui le gère.
Voir le pod créé
Section intitulée « Voir le pod créé »kubectl get pods -n demo-appNAME READY STATUS RESTARTS AGEnginx-6d8867d6c-z2j62 1/1 Running 0 18sLe nom du pod (nginx-6d8867d6c-z2j62) est généré automatiquement :
nginx: nom du Deployment6d8867d6c: identifiant du ReplicaSetz2j62: identifiant unique du pod
Étape 3 : Exposer avec un Service
Section intitulée « Étape 3 : Exposer avec un Service »Le pod tourne, mais il n’est pas accessible de manière stable. Pour l’atteindre, créez un Service.
kubectl expose deployment nginx --port=80 --type=ClusterIP -n demo-appservice/nginx exposed| Option | Signification |
|---|---|
--port=80 | Port sur lequel le Service écoute |
--type=ClusterIP | Accessible uniquement depuis l’intérieur du cluster |
Vérifiez le Service créé :
kubectl get service nginx -n demo-appNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEnginx ClusterIP 10.43.51.181 <none> 80/TCP 8s| Colonne | Signification |
|---|---|
CLUSTER-IP | Adresse IP interne au cluster |
EXTERNAL-IP | <none> car ClusterIP n’est pas exposé à l’extérieur |
PORT(S) | Port d’écoute |
Étape 4 : Comprendre comment le Service trouve les Pods
Section intitulée « Étape 4 : Comprendre comment le Service trouve les Pods »C’est ici que vous comprenez vraiment comment Kubernetes relie les choses.
Voir les labels des Pods
Section intitulée « Voir les labels des Pods »Le Deployment a créé des Pods avec le label app=nginx :
kubectl get pods -n demo-app --show-labelsNAME READY STATUS RESTARTS AGE LABELSnginx-6d8867d6c-z2j62 1/1 Running 0 45s app=nginx,pod-template-hash=6d8867d6cVoir le sélecteur du Service
Section intitulée « Voir le sélecteur du Service »kubectl describe service nginx -n demo-appName: nginxNamespace: demo-appSelector: app=nginxType: ClusterIPIP: 10.43.51.181Port: <unset> 80/TCPEndpoints: 10.42.0.15:80| Champ | Signification |
|---|---|
Selector | Label que le Service cherche (app=nginx) |
Endpoints | Adresses IP des Pods qui correspondent au sélecteur |
Le lien est maintenant clair :
- Le Deployment crée des Pods avec le label
app=nginx - Le Service sélectionne les Pods ayant
app=nginx - Les
Endpointsmontrent les Pods effectivement ciblés
Étape 5 : Vérifier que l’application répond
Section intitulée « Étape 5 : Vérifier que l’application répond »Option 1 : Tester depuis un pod temporaire
Section intitulée « Option 1 : Tester depuis un pod temporaire »Cette commande crée un Pod temporaire, exécute wget, affiche le résultat puis supprime le Pod :
kubectl run test-curl --image=busybox:1.36 --rm -i --restart=Never -n demo-app -- wget -qO- http://nginx:80<!DOCTYPE html><html><head><title>Welcome to nginx!</title>...L’application répond ! Le Service nginx est accessible depuis n’importe quel Pod du namespace via son nom DNS (nginx ou nginx.demo-app.svc.cluster.local).
| Option | Signification |
|---|---|
--rm | Supprime le pod après exécution |
-i | Mode interactif (récupère la sortie) |
--restart=Never | Ne pas redémarrer si la commande échoue |
wget -qO- | Télécharge et affiche le contenu |
Option 2 : Port-forward (accès depuis votre poste)
Section intitulée « Option 2 : Port-forward (accès depuis votre poste) »Pour accéder à nginx depuis votre navigateur :
kubectl port-forward svc/nginx 8080:80 -n demo-appForwarding from 127.0.0.1:8080 -> 80Forwarding from [::1]:8080 -> 80Ouvrez http://localhost:8080 dans votre navigateur. Vous verrez la page d’accueil nginx.
Appuyez sur Ctrl+C pour arrêter le port-forward.
Étape 6 : Scaler l’application
Section intitulée « Étape 6 : Scaler l’application »Actuellement, vous avez 1 pod. Pour en avoir 3 :
kubectl scale deployment nginx --replicas=3 -n demo-appdeployment.apps/nginx scaledVérifiez que les nouveaux pods démarrent :
kubectl get pods -n demo-appNAME READY STATUS RESTARTS AGEnginx-6d8867d6c-57bpf 1/1 Running 0 10snginx-6d8867d6c-lptvk 1/1 Running 0 10snginx-6d8867d6c-z2j62 1/1 Running 0 2m3 pods tournent maintenant. Vérifiez que le Service les voit tous :
kubectl describe service nginx -n demo-app | grep EndpointsEndpoints: 10.42.0.15:80,10.42.0.16:80,10.42.0.17:80Le Service a détecté les nouveaux Pods et les a ajoutés à sa liste d’endpoints. Il répartit automatiquement les requêtes entre eux.
Étape 7 : Observer l’application
Section intitulée « Étape 7 : Observer l’application »Voir les détails du Deployment
Section intitulée « Voir les détails du Deployment »kubectl describe deployment nginx -n demo-appName: nginxNamespace: demo-appLabels: app=nginxSelector: app=nginxReplicas: 3 desired | 3 updated | 3 total | 3 availableStrategyType: RollingUpdatePod Template: Labels: app=nginx Containers: nginx: Image: nginx:1.28Cette commande montre la configuration complète et les événements récents.
Voir les logs d’un Pod
Section intitulée « Voir les logs d’un Pod »Les logs viennent toujours d’un Pod (pas du Deployment). Identifiez d’abord un Pod :
kubectl get pods -n demo-appPuis affichez ses logs :
kubectl logs nginx-6d8867d6c-z2j62 -n demo-app --tail=102026/03/21 09:52:26 [notice] 1#1: start worker process 41...Raccourci : logs via le Deployment
Section intitulée « Raccourci : logs via le Deployment »kubectl permet de lire les logs via le nom du Deployment :
kubectl logs deployment/nginx -n demo-app --tail=10Found 3 pods, using pod/nginx-6d8867d6c-z2j622026/03/21 09:52:26 [notice] 1#1: start worker process 41...Cette forme est pratique, mais les logs viennent toujours d’un seul Pod — kubectl en choisit un pour vous.
Pour suivre les logs en temps réel :
kubectl logs deployment/nginx -n demo-app -fAppuyez sur Ctrl+C pour arrêter.
Voir les événements du namespace
Section intitulée « Voir les événements du namespace »kubectl get events -n demo-app --sort-by='.lastTimestamp'Cette commande montre ce qui s’est passé : création de pods, scaling, erreurs éventuelles.
Méthode déclarative (fichier YAML)
Section intitulée « Méthode déclarative (fichier YAML) »Les commandes impératives sont parfaites pour apprendre et explorer. En production, on préfère décrire les ressources dans des fichiers YAML versionnés dans Git.
Voici l’équivalent de ce que vous avez créé :
apiVersion: v1kind: Namespacemetadata: name: demo-app---apiVersion: apps/v1kind: Deploymentmetadata: name: nginx namespace: demo-appspec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.28 ports: - containerPort: 80---apiVersion: v1kind: Servicemetadata: name: nginx namespace: demo-appspec: selector: app: nginx ports: - port: 80 targetPort: 80 type: ClusterIPPour appliquer ce fichier :
kubectl apply -f demo-app.yamlCe que Kubernetes a fait en arrière-plan
Section intitulée « Ce que Kubernetes a fait en arrière-plan »Récapitulons ce qui s’est passé quand vous avez exécuté ces commandes :
- Vous avez créé un Deployment → Kubernetes a créé un ReplicaSet
- Le ReplicaSet a créé les Pods → Kubernetes a assigné chaque Pod à un nœud
- Chaque nœud a téléchargé l’image et démarré le conteneur nginx
- Vous avez créé un Service → Kubernetes a enregistré les Pods correspondant au sélecteur
app=nginx - Le Service a reçu une IP stable → Les endpoints pointent vers les Pods
- Vous avez scalé → Le ReplicaSet a créé 2 Pods supplémentaires
- Le Service a mis à jour ses endpoints automatiquement
C’est ça le modèle Kubernetes : vous déclarez ce que vous voulez, Kubernetes s’occupe de le réaliser et de le maintenir.
Nettoyer
Section intitulée « Nettoyer »Pour supprimer tout ce que vous avez créé, supprimez le namespace :
kubectl delete namespace demo-appnamespace "demo-app" deletedCette commande supprime toutes les ressources du namespace (Deployment, ReplicaSet, Service, Pods).
Dépannage
Section intitulée « Dépannage »Le Deployment reste à 0/1
Section intitulée « Le Deployment reste à 0/1 »kubectl describe deployment nginx -n demo-appkubectl get events -n demo-app| Cause fréquente | Solution |
|---|---|
| Image introuvable | Vérifiez le nom de l’image (nginx:1.28 pas ngix:1.28) |
| Pas de ressources | Réduisez le nombre de réplicas ou libérez de la mémoire |
| ImagePullBackOff | Problème de connexion à la registry ou image privée |
Le pod est en CrashLoopBackOff
Section intitulée « Le pod est en CrashLoopBackOff »kubectl logs <nom-du-pod> -n demo-app --previousLe flag --previous montre les logs de l’exécution précédente (avant le crash).
Le Service ne répond pas
Section intitulée « Le Service ne répond pas »kubectl describe service nginx -n demo-appVérifiez que Endpoints n’est pas vide. S’il l’est, le sélecteur du Service ne correspond à aucun Pod — vérifiez les labels avec kubectl get pods --show-labels.
Le namespace reste en Terminating
Section intitulée « Le namespace reste en Terminating »C’est normal — donnez-lui quelques secondes. Kubernetes nettoie les ressources dans l’ordre. Si ça dure trop longtemps, des finalizers peuvent bloquer la suppression.
Récapitulatif des commandes
Section intitulée « Récapitulatif des commandes »Pour apprendre (impératif)
Section intitulée « Pour apprendre (impératif) »| Action | Commande |
|---|---|
| Créer namespace | kubectl create namespace nom |
| Créer Deployment | kubectl create deployment nom --image=image -n namespace |
| Exposer avec Service | kubectl expose deployment nom --port=80 -n namespace |
| Scaler | kubectl scale deployment nom --replicas=N -n namespace |
| Supprimer tout | kubectl delete namespace nom |
Pour observer
Section intitulée « Pour observer »| Action | Commande |
|---|---|
| Voir les pods | kubectl get pods -n namespace |
| Voir les labels | kubectl get pods -n namespace --show-labels |
| Voir les endpoints | kubectl describe service nom -n namespace |
| Voir les logs | kubectl logs <pod> -n namespace |
| Port-forward | kubectl port-forward svc/nom 8080:80 -n namespace |
| Tester depuis un pod | kubectl run test --rm -i --restart=Never --image=busybox -- wget -qO- http://service |
En production (déclaratif)
Section intitulée « En production (déclaratif) »| Action | Commande |
|---|---|
| Appliquer une config | kubectl apply -f fichier.yaml |
| Voir les différences | kubectl diff -f fichier.yaml |
À retenir
Section intitulée « À retenir »- Un Deployment gère vos Pods via un ReplicaSet — il les crée, les surveille et les recrée si nécessaire
- Un Service expose vos Pods — il fournit une adresse stable même quand les Pods changent
- Le Service cible les Pods par labels, pas le Deployment — vérifiez toujours les
Endpoints - Utilisez un namespace pour organiser et nettoyer proprement
- Figez les versions d’images (
nginx:1.28pasnginx:latest) - Les commandes impératives sont pour apprendre — en production, passez au déclaratif (YAML)
kubectl describeest votre meilleur ami pour comprendre ce qui se passe- Si vous cassez quelque chose, supprimez le namespace et recommencez
Prochaines étapes
Section intitulée « Prochaines étapes »Vous savez maintenant déployer et exposer une application. Continuez avec :