
kubectl create crée une ressource Kubernetes en une commande, kubectl apply déploie et met à jour des ressources à partir de fichiers YAML versionnés. La différence fondamentale : create échoue si la ressource existe déjà, apply la met à jour intelligemment. Ce guide vous apprend à utiliser les deux commandes, à choisir la bonne approche selon le contexte, et à adopter un workflow sûr pour vos déploiements.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »À la fin de ce guide, vous saurez :
- Distinguer l’approche impérative (
create) de l’approche déclarative (apply) et choisir selon le contexte - Créer des ressources rapidement avec
kubectl create(deployments, services, configmaps, secrets, namespaces) - Déployer et mettre à jour des ressources avec
kubectl applysans écraser les modifications manuelles - Valider avant d’appliquer avec
--dry-runetkubectl diff - Gérer des manifests multi-fichiers : dossiers, récursif, kustomize, URLs
- Éviter les erreurs courantes : conflits, ressources orphelines, YAML invalide
Impératif vs déclaratif : deux façons de gérer Kubernetes
Section intitulée « Impératif vs déclaratif : deux façons de gérer Kubernetes »Avant de plonger dans les commandes, il est essentiel de comprendre les deux approches de gestion des ressources.
Approche impérative : « fais cette action maintenant »
Section intitulée « Approche impérative : « fais cette action maintenant » »Vous dites à Kubernetes quoi faire étape par étape. C’est rapide et direct, comme donner des ordres à voix haute :
# « Crée un deployment nginx avec 3 réplicas »kubectl create deployment nginx --image=nginx --replicas=3
# « Expose-le sur le port 80 »kubectl expose deployment nginx --port=80 --type=ClusterIPAvantages : rapide pour du prototypage, des tests ou des opérations ponctuelles.
Limites : aucune trace de ce qui a été fait. Si vous voulez reproduire l’action sur un autre cluster, vous devez vous souvenir des commandes.
Approche déclarative : « voici l’état souhaité »
Section intitulée « Approche déclarative : « voici l’état souhaité » »Vous décrivez dans un fichier YAML l’état final que vous voulez, et Kubernetes se charge d’y arriver :
apiVersion: apps/v1kind: Deploymentmetadata: name: nginx labels: app: nginxspec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.27 ports: - containerPort: 80kubectl apply -f deployment-nginx.yamlAvantages : reproductible, versionnable dans Git, traçable, idéal pour le CI/CD.
Limites : nécessite d’écrire des fichiers YAML (plus de code initial).
Tableau de décision
Section intitulée « Tableau de décision »| Situation | Approche recommandée | Pourquoi |
|---|---|---|
| Test rapide en développement | kubectl create (impératif) | Pas besoin de traçabilité |
| Déploiement en production | kubectl apply -f (déclaratif) | Versionné, reproductible |
| Pipeline CI/CD | kubectl apply -f (déclaratif) | Automatisable, idempotent |
| Créer un namespace ponctuel | kubectl create (impératif) | Action unique et simple |
| Modifier un deployment existant | kubectl apply -f (déclaratif) | Préserve les modifications |
| Générer un squelette YAML | kubectl create --dry-run=client -o yaml | Gain de temps sur l’écriture |
kubectl create : créer des ressources en mode impératif
Section intitulée « kubectl create : créer des ressources en mode impératif »La commande kubectl create crée une nouvelle ressource. Si la ressource existe déjà, elle échoue avec l’erreur AlreadyExists.
Syntaxe de base
Section intitulée « Syntaxe de base »kubectl create <type> <nom> [options]# ou depuis un fichierkubectl create -f <fichier.yaml>Créer les ressources les plus courantes
Section intitulée « Créer les ressources les plus courantes »Crée un deployment (un pod managé avec rolling updates) :
# Syntaxe minimalekubectl create deployment mon-app --image=nginx:1.27
# Avec réplicas et portkubectl create deployment mon-app --image=nginx:1.27 --replicas=3 --port=80Vérification :
kubectl get deployment mon-app# NAME READY UP-TO-DATE AVAILABLE AGE# mon-app 3/3 3 3 12sCrée un service pour exposer un deployment :
# ClusterIP (interne au cluster)kubectl create service clusterip mon-service --tcp=80:80
# NodePort (accessible depuis l'extérieur)kubectl create service nodeport mon-service --tcp=80:80 --node-port=30080Stocke de la configuration non confidentielle :
# Depuis des valeurs littéraleskubectl create configmap app-config \ --from-literal=DB_HOST=postgres.default.svc \ --from-literal=DB_PORT=5432
# Depuis un fichierkubectl create configmap nginx-conf --from-file=nginx.conf
# Depuis un dossier entierkubectl create configmap app-configs --from-file=configs/Vérification :
kubectl get configmap app-config -o yamlStocke des données sensibles (encodées en base64) :
# Depuis des valeurs littéraleskubectl create secret generic db-credentials \ --from-literal=username=admin \ --from-literal=password=S3cur3P@ss
# Depuis un fichier (ex: certificat TLS)kubectl create secret tls mon-tls \ --cert=tls.crt --key=tls.key
# Secret de type docker-registry (pour puller des images privées)kubectl create secret docker-registry regcred \ --docker-server=registry.example.com \ --docker-username=deploy \ --docker-password=token123# Créer un namespacekubectl create namespace staging
# Créer un job ponctuelkubectl create job backup-db --image=postgres:16 \ -- pg_dump -h postgres -U admin mydb > /backup/dump.sql
# Créer un cronjobkubectl create cronjob backup-daily --image=postgres:16 \ --schedule="0 2 * * *" \ -- pg_dump -h postgres -U admin mydbAstuce : générer un squelette YAML avec —dry-run
Section intitulée « Astuce : générer un squelette YAML avec —dry-run »L’option --dry-run=client -o yaml transforme n’importe quelle commande create en générateur de manifest YAML, sans rien créer dans le cluster. C’est la façon la plus rapide de produire un fichier de base :
# Générer le YAML d'un deploymentkubectl create deployment mon-app --image=nginx:1.27 --replicas=3 \ --dry-run=client -o yaml > deployment-mon-app.yaml
# Générer le YAML d'un servicekubectl create service clusterip mon-service --tcp=80:80 \ --dry-run=client -o yaml > service-mon-service.yaml
# Générer le YAML d'un secretkubectl create secret generic db-creds \ --from-literal=password=secret \ --dry-run=client -o yaml > secret-db-creds.yamlÉditez ensuite le fichier généré pour ajouter labels, annotations, resource limits, et appliquez-le avec kubectl apply -f.
kubectl apply : l’approche déclarative
Section intitulée « kubectl apply : l’approche déclarative »kubectl apply est la commande de référence pour les déploiements en conditions réelles. Elle crée la ressource si elle n’existe pas, ou la met à jour si elle existe déjà, en fusionnant intelligemment les modifications.
Comment fonctionne la fusion (3-way merge)
Section intitulée « Comment fonctionne la fusion (3-way merge) »Quand vous exécutez kubectl apply, Kubernetes compare trois versions de la ressource :
- Le fichier local (votre YAML)
- L’annotation last-applied (stockée par le dernier
apply) - L’état actif dans le cluster (modifications manuelles comprises)
Cette comparaison en 3 points (appelée 3-way merge) permet à apply de :
- Ajouter les champs présents dans votre fichier mais absents du cluster
- Modifier les champs dont la valeur a changé dans votre fichier
- Conserver les champs modifiés manuellement dans le cluster mais absents de votre fichier (ex: réplicas ajustés par un HPA)
Appliquer un fichier
Section intitulée « Appliquer un fichier »# Créer ou mettre à jour une ressourcekubectl apply -f deployment.yaml
# Appliquer dans un namespace spécifiquekubectl apply -f deployment.yaml -n stagingAppliquer un dossier complet
Section intitulée « Appliquer un dossier complet »# Tous les fichiers YAML d'un dossier (non récursif)kubectl apply -f manifests/
# Récursif (tous les sous-dossiers)kubectl apply -f manifests/ -R
# Plusieurs fichiers à la foiskubectl apply -f deployment.yaml -f service.yaml -f configmap.yamlAppliquer depuis une URL
Section intitulée « Appliquer depuis une URL »# Depuis un dépôt Git (raw)kubectl apply -f https://raw.githubusercontent.com/org/repo/main/deploy.yamlAppliquer avec Kustomize
Section intitulée « Appliquer avec Kustomize »Kustomize est intégré nativement à kubectl. Il permet de personnaliser des manifests sans les modifier directement :
# Appliquer un projet kustomizekubectl apply -k ./overlay/production/
# Prévisualiser ce que kustomize va générerkubectl kustomize ./overlay/production/Structure typique d’un projet kustomize :
├── base/│ ├── deployment.yaml│ ├── service.yaml│ └── kustomization.yaml└── overlay/ ├── staging/ │ └── kustomization.yaml └── production/ └── kustomization.yamlServer-side apply (SSA)
Section intitulée « Server-side apply (SSA) »Depuis Kubernetes 1.22, le server-side apply délègue la fusion au serveur API plutôt qu’au client. C’est l’approche recommandée pour les contrôleurs et les outils qui gèrent des champs partagés :
kubectl apply -f deployment.yaml --server-side
# Forcer l'adoption des champs en conflitkubectl apply -f deployment.yaml --server-side --force-conflictsLe SSA utilise un système de field managers : chaque outil ou utilisateur qui modifie un champ est identifié, ce qui évite les écrasements involontaires entre outils.
Workflow complet : du manifest au cluster
Section intitulée « Workflow complet : du manifest au cluster »Voici la procédure recommandée pour appliquer des changements de façon sûre.
-
Écrivez ou modifiez votre manifest YAML
Partez d’un fichier existant ou générez un squelette avec
--dry-run=client -o yaml. Validez la syntaxe YAML dans votre éditeur. -
Validez la structure avec —dry-run
L’option
--dry-run=serverenvoie le manifest au serveur API pour validation sans l’appliquer :Fenêtre de terminal kubectl apply -f deployment.yaml --dry-run=server# deployment.apps/mon-app created (dry run)Si le YAML est invalide ou le type de ressource inconnu, l’erreur apparaît ici.
-
Comparez avec l’état actuel via kubectl diff
kubectl diffaffiche les différences entre votre fichier local et l’état du cluster, comme ungit diff:Fenêtre de terminal kubectl diff -f deployment.yamlExemple de sortie :
replicas: 2replicas: 3image: nginx:1.26image: nginx:1.27Relisez attentivement les changements avant de continuer.
-
Appliquez les changements
Fenêtre de terminal kubectl apply -f deployment.yaml# deployment.apps/mon-app configuredTrois réponses possibles :
Sortie Signification createdRessource créée (n’existait pas) configuredRessource mise à jour unchangedAucun changement détecté -
Vérifiez le résultat
Fenêtre de terminal # L'état de la ressourcekubectl get deployment mon-app# Le détail (events, conditions)kubectl describe deployment mon-app# Le rollout (pour les deployments)kubectl rollout status deployment/mon-appSi le déploiement échoue, consultez le guide Diagnostiquer avec kubectl.
Gérer les manifests en pratique
Section intitulée « Gérer les manifests en pratique »Organiser ses fichiers
Section intitulée « Organiser ses fichiers »Une organisation claire facilite la maintenance et le travail en équipe :
k8s/├── base/ # Ressources communes│ ├── namespace.yaml│ ├── configmap.yaml│ └── networkpolicy.yaml├── apps/│ ├── frontend/│ │ ├── deployment.yaml│ │ ├── service.yaml│ │ └── ingress.yaml│ └── backend/│ ├── deployment.yaml│ ├── service.yaml│ └── secret.yaml└── monitoring/ ├── prometheus/ └── grafana/# Déployer tout le projetkubectl apply -f k8s/ -R
# Déployer seulement le backendkubectl apply -f k8s/apps/backend/Supprimer les ressources gérées
Section intitulée « Supprimer les ressources gérées »Pour supprimer les ressources créées par un fichier ou un dossier :
# Supprimer tout ce qui a été créé par le fichierkubectl delete -f deployment.yaml
# Supprimer tout le contenu d'un dossierkubectl delete -f k8s/apps/backend/Piping et stdin
Section intitulée « Piping et stdin »Vous pouvez chaîner des commandes pour des workflows avancés :
# Appliquer la sortie de kustomizekubectl kustomize ./overlay/prod/ | kubectl apply -f -
# Appliquer un manifest généré dynamiquementcat <<EOF | kubectl apply -f -apiVersion: v1kind: ConfigMapmetadata: name: dynamic-config namespace: defaultdata: APP_VERSION: "2.1.0" DEPLOY_DATE: "$(date -u +%Y-%m-%dT%H:%M:%SZ)"EOFBonnes pratiques
Section intitulée « Bonnes pratiques »- Versionnez vos manifests dans Git — ne déployez jamais un YAML écrit à la volée en production.
- Utilisez
--dry-run=serveravant chaqueapply— la validation côté serveur détecte les erreurs que le client ne voit pas (CRD manquants, quotas dépassés). - Exécutez
kubectl diffsystématiquement — comprenez exactement ce qui va changer avant d’appliquer. - Ajoutez des labels à toutes vos ressources —
app,env,versionau minimum. Cela facilite le filtrage et le nettoyage. Voir le guide labels et annotations. - Un namespace par environnement — séparez
dev,stagingetproductionpour limiter les erreurs de déploiement. - Préférez
applyàcreatedès que la ressource peut évoluer —applyest idempotent (vous pouvez le relancer sans risque),createéchoue si la ressource existe. - En CI/CD, appliquez toujours depuis un fichier — jamais de commandes impératives dans un pipeline automatisé.
Dépannage
Section intitulée « Dépannage »| Symptôme | Cause probable | Solution |
|---|---|---|
error: resource already exists | Ressource créée avec create, déjà présente | Utilisez kubectl apply à la place |
error: the object has been modified | Conflit de version (quelqu’un a modifié entre-temps) | Refaites kubectl apply (il re-fusionnera) |
Warning: resource is missing the kubectl.kubernetes.io/last-applied-configuration annotation | Ressource créée avec create puis mise à jour avec apply | Normal au premier apply — l’annotation sera ajoutée |
error: unable to recognize "fichier.yaml" | apiVersion ou kind incorrect/manquant | Vérifiez apiVersion et kind dans le fichier |
error: no matches for kind "X" in version "Y" | CRD non installé ou version API dépréciée | Installez le CRD ou mettez à jour l’apiVersion |
The Deployment is invalid: spec.selector | Le sélecteur ne correspond pas aux labels du template | Les labels du selector.matchLabels doivent correspondre exactement au template.metadata.labels |
forbidden: User cannot create resource | Permissions RBAC insuffisantes | Vérifiez avec kubectl auth can-i create deployments |
kubectl diff retourne une erreur sans diff | Le KUBECONFIG n’est pas configuré ou le cluster est injoignable | Vérifiez votre contexte avec kubectl config current-context |
À retenir
Section intitulée « À retenir »kubectl createcrée une ressource — si elle existe déjà, la commande échoue. Idéal pour les tests rapides et la génération de squelettes YAML.kubectl applycrée ou met à jour une ressource de façon déclarative — c’est la commande de référence pour la production et le CI/CD.- Le 3-way merge de
applypréserve les modifications manuelles et ne touche qu’aux champs que vous avez changés. --dry-run=client -o yamlest le moyen le plus rapide de générer un manifest YAML sans écrire une ligne.- Le workflow sûr : écrire → dry-run → diff → apply → vérifier.
- Les manifests versionnés dans Git sont la norme en production : reproductibilité, traçabilité, revue par les pairs.