Aller au contenu
Conteneurs & Orchestration medium
🔐 Alerte sécurité — Incident supply chain Trivy : lire mon analyse de l'attaque

Manifests Kubernetes : produire, valider et corriger vite (CKAD)

21 min de lecture

logo kubernetes

Produire des manifests Kubernetes rapidement, c’est savoir générer un squelette avec kubectl, le compléter avec les bons champs, et valider avant d’appliquer. Ce guide vous donne les réflexes CKAD : kubectl explain, --dry-run=client -o yaml, correction rapide, et validation côté serveur.

  • Workflow examen : générer → compléter → valider → appliquer
  • Deux approches : génération assistée vs écriture manuelle
  • Namespace et contexte : éviter les erreurs de cible
  • Snippets fréquents : resources, probes, command, envFrom
  • Correction rapide : kubectl edit, kubectl patch
  • Validation complète : --dry-run=client, --dry-run=server, kubectl diff

En examen, chaque seconde compte. Voici le workflow le plus efficace :

  1. Configurer le namespace de travail

    Fenêtre de terminal
    kubectl create namespace ckad
    kubectl config set-context --current --namespace=ckad

    En changeant le namespace courant, vous évitez de répéter -n à chaque commande.

  2. Générer un squelette

    Fenêtre de terminal
    kubectl create deployment web --image=nginx:stable --dry-run=client -o yaml > web.yaml
  3. Compléter le manifest

    Fenêtre de terminal
    vim web.yaml

    Ajoutez les champs manquants : resources, probes, labels…

  4. Valider avant application

    Fenêtre de terminal
    kubectl apply --dry-run=client -f web.yaml
    kubectl diff -f web.yaml # si la ressource existe déjà
  5. Appliquer et vérifier

    Fenêtre de terminal
    kubectl apply -f web.yaml
    kubectl get all
    kubectl describe deploy web

Utile pour : gagner du temps, éviter les erreurs de base, partir d’un squelette valide.

Fenêtre de terminal
kubectl create deployment web --image=nginx:stable --dry-run=client -o yaml > web.yaml

Le YAML généré est un squelette. Vous devez presque toujours l’ajuster : labels, ports, resources, probes…

Utile pour : comprendre la structure, corriger un YAML existant, maîtriser les champs importants.

Quand vous connaissez bien la structure, vous pouvez écrire directement. Mais en examen, la génération assistée reste plus rapide.

Kubernetes utilise un langage déclaratif : vous décrivez l’état souhaité, et Kubernetes se charge de l’atteindre. Chaque manifest YAML suit une structure commune avec quatre champs obligatoires.

apiVersion: v1
kind: Pod
metadata:
name: web
namespace: ckad
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:stable
ports:
- containerPort: 80
ChampDescriptionExemples
apiVersionVersion de l’API Kubernetesv1, apps/v1, networking.k8s.io/v1
kindType de ressourcePod, Deployment, Service, ConfigMap
metadataIdentité de l’objetname, namespace, labels, annotations
specSpécification détailléeVarie selon le kind
Fenêtre de terminal
# Créer le namespace
kubectl create namespace monprojet
# Définir comme namespace courant
kubectl config set-context --current --namespace=monprojet
# Vérifier le contexte actuel
kubectl config get-contexts
ProblèmeConséquenceSolution
Oublier -nRessource créée dans defaultChanger le namespace courant
Mauvais namespaceRessource introuvablekubectl get pods -A pour chercher
ConfigMap/Secret ailleursnot found au démarrage du PodCréer dans le même namespace
Fenêtre de terminal
kubectl api-resources | head -15
NAME SHORTNAMES APIVERSION NAMESPACED KIND
configmaps cm v1 true ConfigMap
namespaces ns v1 false Namespace
pods po v1 true Pod
secrets v1 true Secret
services svc v1 true Service
deployments deploy apps/v1 true Deployment

Cette commande liste tous les types de ressources avec leur abréviation, leur apiVersion et si elles sont namespacées.

kubectl explain documente chaque champ directement depuis le cluster :

Fenêtre de terminal
kubectl explain pod.spec.containers
KIND: Pod
VERSION: v1
FIELD: containers <[]Container>
DESCRIPTION:
List of containers belonging to the pod.
FIELDS:
args <[]string>
command <[]string>
env <[]EnvVar>
image <string>
name <string> -required-
ports <[]ContainerPort>
resources <ResourceRequirements>
...

Au lieu d’écrire un YAML de zéro, générez-le avec --dry-run=client -o yaml :

Fenêtre de terminal
kubectl run web --image=nginx:stable --dry-run=client -o yaml
apiVersion: v1
kind: Pod
metadata:
labels:
run: web
name: web
spec:
containers:
- image: nginx:stable
name: web
restartPolicy: Always

Ces champs reviennent constamment en CKAD. Gardez-les en mémoire.

containers:
- name: app
image: busybox:1.36
command: ["sh", "-c"]
args: ["echo hello && sleep 3600"]
env:
- name: APP_ENV
value: production
- name: APP_DEBUG
value: "false"
envFrom:
- configMapRef:
name: app-config
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "256Mi"
readinessProbe:
httpGet:
path: /healthz
port: 80
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /healthz
port: 80
initialDelaySeconds: 15
periodSeconds: 20
ports:
- containerPort: 80
name: http
- containerPort: 443
name: https
containers:
- name: app
image: nginx:stable
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: app-config

Un Pod est l’unité de base dans Kubernetes. Il exécute un ou plusieurs conteneurs.

apiVersion: v1
kind: Pod
metadata:
name: web
namespace: ckad
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:stable
ports:
- containerPort: 80
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "256Mi"
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 10
Fenêtre de terminal
kubectl apply -f pod.yaml
kubectl get pods -l app=nginx --show-labels
NAME READY STATUS RESTARTS AGE LABELS
web 1/1 Running 0 19s app=nginx

Un Deployment gère un ensemble de Pods identiques et permet les mises à jour progressives.

apiVersion: apps/v1
kind: Deployment
metadata:
name: web
namespace: ckad
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:stable
ports:
- containerPort: 80
resources:
requests:
cpu: "100m"
memory: "128Mi"
Fenêtre de terminal
kubectl apply -f deployment.yaml
kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
web 3/3 3 3 10s

Un Service expose un ensemble de Pods sur le réseau.

TypeUsageAccessibilité
ClusterIPTrafic interneDans le cluster uniquement
NodePortTests, accès externe simple<NodeIP>:<nodePort>
LoadBalancerProduction cloudIP externe via load balancer
apiVersion: v1
kind: Service
metadata:
name: web
namespace: ckad
spec:
type: ClusterIP
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80

Une ConfigMap stocke des configurations non sensibles.

apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
namespace: ckad
data:
APP_ENV: production
APP_DEBUG: "false"
config.json: |
{
"database": "postgres",
"port": 5432
}
apiVersion: v1
kind: Pod
metadata:
name: app
namespace: ckad
spec:
containers:
- name: app
image: busybox:1.36
command: ["sleep", "3600"]
envFrom:
- configMapRef:
name: app-config

Toutes les clés de la ConfigMap deviennent des variables d’environnement.

Un Secret stocke des données sensibles. Utilisez stringData pour écrire en clair dans le manifest.

apiVersion: v1
kind: Secret
metadata:
name: db-credentials
namespace: ckad
type: Opaque
stringData:
username: admin
password: S3cr3tP@ssw0rd!
apiVersion: v1
kind: Pod
metadata:
name: app
namespace: ckad
spec:
containers:
- name: app
image: busybox:1.36
command: ["sleep", "3600"]
env:
- name: DB_USER
valueFrom:
secretKeyRef:
name: db-credentials
key: username
- name: DB_PASS
valueFrom:
secretKeyRef:
name: db-credentials
key: password

Regroupez plusieurs ressources liées dans un seul fichier avec --- :

apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
namespace: ckad
data:
APP_ENV: production
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
namespace: ckad
spec:
replicas: 2
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: app
image: nginx:stable
envFrom:
- configMapRef:
name: app-config
---
apiVersion: v1
kind: Service
metadata:
name: app
namespace: ckad
spec:
selector:
app: myapp
ports:
- port: 80
Fenêtre de terminal
kubectl apply -f app-stack.yaml

Toutes les ressources sont créées en une seule commande.

Fenêtre de terminal
kubectl edit deployment web

Ouvre le manifest dans votre éditeur. Les changements sont appliqués à la sauvegarde.

Fenêtre de terminal
# Changer le nombre de réplicas
kubectl patch deployment web --type merge -p '{"spec":{"replicas":5}}'
# Changer l'image
kubectl patch deployment web --type merge \
-p '{"spec":{"template":{"spec":{"containers":[{"name":"nginx","image":"nginx:1.25"}]}}}}'
Fenêtre de terminal
# Changer l'image
kubectl set image deployment/web nginx=nginx:1.25
# Changer les resources
kubectl set resources deployment/web -c=nginx --limits=cpu=500m,memory=256Mi
Fenêtre de terminal
kubectl apply --dry-run=client -f mon-manifest.yaml

Vérifie la syntaxe YAML et la structure de base. Rapide mais limité.

Fenêtre de terminal
kubectl apply --dry-run=server -f mon-manifest.yaml

Envoie le manifest à l’API server pour validation complète :

  • Vérifie les admission controllers
  • Détecte les champs inconnus
  • Valide les contraintes (quotas, policies…)
Fenêtre de terminal
kubectl diff -f mon-manifest.yaml

Compare le manifest local avec la ressource existante :

replicas: 3
replicas: 5
ErreurConséquenceSolution
Oublier le namespaceRessource dans defaultChanger le namespace courant
Mauvais label Service/PodService sans EndpointsAligner les selectors
port vs targetPort inversésConnexion impossibleport = Service, targetPort = conteneur
Indentation YAML incorrecteErreur de parsingUtiliser 2 espaces, pas de tabs
Modifier selector d’un DeploymentErreur “immutable”Supprimer et recréer
Champ au mauvais niveauChamp ignorékubectl explain pour vérifier
ConfigMap dans un autre namespacenot foundMême namespace que le Pod
Fenêtre de terminal
# Impossible de modifier le selector d'un Deployment existant
kubectl patch deployment web --type merge -p '{"spec":{"selector":{"matchLabels":{"app":"newapp"}}}}'
# Erreur: spec.selector is immutable

Solution : supprimer et recréer le Deployment.

Fenêtre de terminal
kubectl delete deployment web
kubectl apply -f web.yaml # avec le nouveau selector

Avant chaque kubectl apply :

  • Namespace : suis-je dans le bon namespace ?
  • Labels : sont-ils cohérents entre Deployment, Pod et Service ?
  • Image : nom et tag corrects ?
  • Ports : port et targetPort alignés ?
  • Resources : requests ≤ limits ?
  • Probes : path et port corrects ?
  • Volumes : même nom entre volumes et volumeMounts ?
RessourceRôleChamps clés
PodExécuter des conteneurscontainers[].image, ports, resources
DeploymentGérer des réplicasreplicas, selector, template
ServiceExposer des Podsselector, ports, type
ConfigMapConfiguration non sensibledata (clé/valeur ou fichier)
SecretDonnées sensiblesstringData (écriture) ou data (base64)
Fenêtre de terminal
# Explorer l'API
kubectl api-resources
kubectl explain deployment.spec.template.spec.containers
# Générer des manifests
kubectl create deployment web --image=nginx --dry-run=client -o yaml > web.yaml
kubectl expose deployment web --port=80 --dry-run=client -o yaml > svc.yaml
# Valider
kubectl apply --dry-run=client -f manifest.yaml
kubectl apply --dry-run=server -f manifest.yaml
kubectl diff -f manifest.yaml
# Corriger rapidement
kubectl edit deployment web
kubectl patch deployment web --type merge -p '{"spec":{"replicas":5}}'
kubectl set image deployment/web nginx=nginx:1.25
# Débugger
kubectl get pods -A # tous les namespaces
kubectl describe pod web
kubectl logs web
kubectl exec -it web -- sh

Contrôle de connaissances

Validez vos connaissances avec ce quiz interactif

7 questions
5 min.
80% requis

Informations

  • Le chronomètre démarre au clic sur Démarrer
  • Questions à choix multiples, vrai/faux et réponses courtes
  • Vous pouvez naviguer entre les questions
  • Les résultats détaillés sont affichés à la fin

Lance le quiz et démarre le chronomètre

  1. Workflow examen : namespace → générer → compléter → valider → appliquer
  2. kubectl explain documente chaque champ depuis le cluster
  3. --dry-run=client -o yaml génère un squelette à compléter
  4. kubectl expose crée un Service avec les bons labels automatiquement
  5. Labels cohérents entre Deployment, Pod template et Service selector
  6. --dry-run=server valide contre l’API et les admission controllers
  7. kubectl edit et kubectl patch pour corriger rapidement
  8. Multi-document YAML (---) pour regrouper les ressources liées
  9. Namespace courant : le changer évite les erreurs de cible
  10. stringData dans les Secrets évite l’encodage base64 manuel

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