Aller au contenu
Conteneurs & Orchestration medium

kubectl create et apply : créer et déployer des ressources Kubernetes

18 min de lecture

logo kubernetes

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.

À 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 apply sans écraser les modifications manuelles
  • Valider avant d’appliquer avec --dry-run et kubectl 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 :

Fenêtre de terminal
# « 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=ClusterIP

Avantages : 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 :

deployment-nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.27
ports:
- containerPort: 80
Fenêtre de terminal
kubectl apply -f deployment-nginx.yaml

Avantages : reproductible, versionnable dans Git, traçable, idéal pour le CI/CD.

Limites : nécessite d’écrire des fichiers YAML (plus de code initial).

SituationApproche recommandéePourquoi
Test rapide en développementkubectl create (impératif)Pas besoin de traçabilité
Déploiement en productionkubectl apply -f (déclaratif)Versionné, reproductible
Pipeline CI/CDkubectl apply -f (déclaratif)Automatisable, idempotent
Créer un namespace ponctuelkubectl create (impératif)Action unique et simple
Modifier un deployment existantkubectl apply -f (déclaratif)Préserve les modifications
Générer un squelette YAMLkubectl create --dry-run=client -o yamlGain 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.

Fenêtre de terminal
kubectl create <type> <nom> [options]
# ou depuis un fichier
kubectl create -f <fichier.yaml>

Crée un deployment (un pod managé avec rolling updates) :

Fenêtre de terminal
# Syntaxe minimale
kubectl create deployment mon-app --image=nginx:1.27
# Avec réplicas et port
kubectl create deployment mon-app --image=nginx:1.27 --replicas=3 --port=80

Vérification :

Fenêtre de terminal
kubectl get deployment mon-app
# NAME READY UP-TO-DATE AVAILABLE AGE
# mon-app 3/3 3 3 12s

Astuce : 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 :

Fenêtre de terminal
# Générer le YAML d'un deployment
kubectl 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 service
kubectl create service clusterip mon-service --tcp=80:80 \
--dry-run=client -o yaml > service-mon-service.yaml
# Générer le YAML d'un secret
kubectl 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 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.

Quand vous exécutez kubectl apply, Kubernetes compare trois versions de la ressource :

  1. Le fichier local (votre YAML)
  2. L’annotation last-applied (stockée par le dernier apply)
  3. 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)
Fenêtre de terminal
# Créer ou mettre à jour une ressource
kubectl apply -f deployment.yaml
# Appliquer dans un namespace spécifique
kubectl apply -f deployment.yaml -n staging
Fenêtre de terminal
# 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 fois
kubectl apply -f deployment.yaml -f service.yaml -f configmap.yaml
Fenêtre de terminal
# Depuis un dépôt Git (raw)
kubectl apply -f https://raw.githubusercontent.com/org/repo/main/deploy.yaml

Kustomize est intégré nativement à kubectl. Il permet de personnaliser des manifests sans les modifier directement :

Fenêtre de terminal
# Appliquer un projet kustomize
kubectl apply -k ./overlay/production/
# Prévisualiser ce que kustomize va générer
kubectl kustomize ./overlay/production/

Structure typique d’un projet kustomize :

├── base/
│ ├── deployment.yaml
│ ├── service.yaml
│ └── kustomization.yaml
└── overlay/
├── staging/
│ └── kustomization.yaml
└── production/
└── kustomization.yaml

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 :

Fenêtre de terminal
kubectl apply -f deployment.yaml --server-side
# Forcer l'adoption des champs en conflit
kubectl apply -f deployment.yaml --server-side --force-conflicts

Le 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.

Voici la procédure recommandée pour appliquer des changements de façon sûre.

  1. É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.

  2. Validez la structure avec —dry-run

    L’option --dry-run=server envoie 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.

  3. Comparez avec l’état actuel via kubectl diff

    kubectl diff affiche les différences entre votre fichier local et l’état du cluster, comme un git diff :

    Fenêtre de terminal
    kubectl diff -f deployment.yaml

    Exemple de sortie :

    replicas: 2
    replicas: 3
    image: nginx:1.26
    image: nginx:1.27

    Relisez attentivement les changements avant de continuer.

  4. Appliquez les changements

    Fenêtre de terminal
    kubectl apply -f deployment.yaml
    # deployment.apps/mon-app configured

    Trois réponses possibles :

    SortieSignification
    createdRessource créée (n’existait pas)
    configuredRessource mise à jour
    unchangedAucun changement détecté
  5. Vérifiez le résultat

    Fenêtre de terminal
    # L'état de la ressource
    kubectl get deployment mon-app
    # Le détail (events, conditions)
    kubectl describe deployment mon-app
    # Le rollout (pour les deployments)
    kubectl rollout status deployment/mon-app

    Si le déploiement échoue, consultez le guide Diagnostiquer avec kubectl.

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/
Fenêtre de terminal
# Déployer tout le projet
kubectl apply -f k8s/ -R
# Déployer seulement le backend
kubectl apply -f k8s/apps/backend/

Pour supprimer les ressources créées par un fichier ou un dossier :

Fenêtre de terminal
# Supprimer tout ce qui a été créé par le fichier
kubectl delete -f deployment.yaml
# Supprimer tout le contenu d'un dossier
kubectl delete -f k8s/apps/backend/

Vous pouvez chaîner des commandes pour des workflows avancés :

Fenêtre de terminal
# Appliquer la sortie de kustomize
kubectl kustomize ./overlay/prod/ | kubectl apply -f -
# Appliquer un manifest généré dynamiquement
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
name: dynamic-config
namespace: default
data:
APP_VERSION: "2.1.0"
DEPLOY_DATE: "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
EOF
  • Versionnez vos manifests dans Git — ne déployez jamais un YAML écrit à la volée en production.
  • Utilisez --dry-run=server avant chaque apply — la validation côté serveur détecte les erreurs que le client ne voit pas (CRD manquants, quotas dépassés).
  • Exécutez kubectl diff systématiquement — comprenez exactement ce qui va changer avant d’appliquer.
  • Ajoutez des labels à toutes vos ressourcesapp, env, version au minimum. Cela facilite le filtrage et le nettoyage. Voir le guide labels et annotations.
  • Un namespace par environnement — séparez dev, staging et production pour limiter les erreurs de déploiement.
  • Préférez apply à create dès que la ressource peut évoluerapply est 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é.
SymptômeCause probableSolution
error: resource already existsRessource créée avec create, déjà présenteUtilisez kubectl apply à la place
error: the object has been modifiedConflit 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 annotationRessource créée avec create puis mise à jour avec applyNormal au premier apply — l’annotation sera ajoutée
error: unable to recognize "fichier.yaml"apiVersion ou kind incorrect/manquantVé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éeInstallez le CRD ou mettez à jour l’apiVersion
The Deployment is invalid: spec.selectorLe sélecteur ne correspond pas aux labels du templateLes labels du selector.matchLabels doivent correspondre exactement au template.metadata.labels
forbidden: User cannot create resourcePermissions RBAC insuffisantesVérifiez avec kubectl auth can-i create deployments
kubectl diff retourne une erreur sans diffLe KUBECONFIG n’est pas configuré ou le cluster est injoignableVérifiez votre contexte avec kubectl config current-context
  • kubectl create cré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 apply cré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 apply préserve les modifications manuelles et ne touche qu’aux champs que vous avez changés.
  • --dry-run=client -o yaml est 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.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn