Aller au contenu principal

Manifests YAML et kubectl : le workflow déclaratif

Résumé : dans Kubernetes, vous ne dites jamais ce qu'il faut faire — vous décrivez l'état voulu dans un fichier YAML, et Kubernetes converge en continu vers cet état. Cette leçon explique le modèle déclaratif convergent, les commandes kubectl essentielles, le concept d'idempotence, et comment Git + kubectl deviennent naturellement une pratique GitOps.


1. Impératif vs déclaratif — le changement de paradigme

Kubernetes impose une révolution mentale pour beaucoup de développeurs venant du monde script bash ou Docker.

En une phrase : impératif = « fais ceci maintenant ». Déclaratif = « maintiens toujours ceci ».


2. YAML — la langue de Kubernetes

Kubernetes utilise YAML pour tous ses manifests. Voici les 5 règles à retenir absolument pour éviter les pièges.

Erreur numéro 1 des débutants : mélanger tabulation et espaces. Configurez votre éditeur (VS Code, Vim, IntelliJ) pour toujours convertir Tab en 2 espaces sur les fichiers .yaml.


3. Anatomie d'un manifest Kubernetes

Tous les manifests partagent la même structure de base.

apiVersion: apps/v1        # Version de l'API Kubernetes
kind: Deployment # Type d'objet
metadata: # Métadonnées de l'objet
name: mon-app
namespace: production
labels:
app: mon-app
tier: backend
spec: # Spécification · l'état voulu
replicas: 3
selector:
matchLabels:
app: mon-app
template:
metadata:
labels:
app: mon-app
spec:
containers:
- name: mon-app
image: mon-app:v2.5

Les 4 sections universelles :

SectionRôle
apiVersionQuelle API Kubernetes on cible (v1, apps/v1, batch/v1, etc.)
kindLe type d'objet (Pod, Deployment, Service, etc.)
metadataNom, namespace, labels, annotations
specLa description de l'état voulu (varie selon kind)

Astuce productive : kubectl explain deployment.spec vous liste tous les champs disponibles avec leur signification.


4. Exemple concret complet — une application web en Kubernetes

Voici un manifest complet et réel qui déploie une application web avec base de données PostgreSQL.

# ----------- 1. Namespace -----------
apiVersion: v1
kind: Namespace
metadata:
name: production

---
# ----------- 2. ConfigMap · configuration non sensible -----------
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
namespace: production
data:
DATABASE_HOST: "postgres-svc"
DATABASE_PORT: "5432"
LOG_LEVEL: "info"

---
# ----------- 3. Secret · mot de passe base -----------
apiVersion: v1
kind: Secret
metadata:
name: db-credentials
namespace: production
type: Opaque
stringData:
DATABASE_USER: "app_user"
DATABASE_PASSWORD: "super-secret-generated"

---
# ----------- 4. Deployment · l'application web -----------
apiVersion: apps/v1
kind: Deployment
metadata:
name: mon-app
namespace: production
spec:
replicas: 3
selector:
matchLabels:
app: mon-app
template:
metadata:
labels:
app: mon-app
spec:
containers:
- name: mon-app
image: mon-registry/mon-app:v2.5
ports:
- containerPort: 8080
envFrom:
- configMapRef:
name: app-config
- secretRef:
name: db-credentials
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5

---
# ----------- 5. Service · accès stable -----------
apiVersion: v1
kind: Service
metadata:
name: mon-app-svc
namespace: production
spec:
type: ClusterIP
selector:
app: mon-app
ports:
- port: 80
targetPort: 8080

---
# ----------- 6. Ingress · exposition publique -----------
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: mon-app-ingress
namespace: production
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
ingressClassName: nginx
tls:
- hosts:
- api.mon-site.com
secretName: mon-site-tls
rules:
- host: api.mon-site.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: mon-app-svc
port:
number: 80

Ce que ce manifest fait en une commande kubectl apply :

  1. Crée le namespace production.
  2. Injecte la config non sensible via ConfigMap.
  3. Injecte le mot de passe DB via Secret (chiffré au repos).
  4. Lance 3 réplicas de l'app avec sondes santé.
  5. Crée un Service interne pour équilibrer le trafic.
  6. Expose l'app publiquement en HTTPS via Ingress + Let's Encrypt.

Résultat : votre application est en production, exposée sur api.mon-site.com, en HTTPS, avec certificats auto-renouvelés, en moins de 60 secondes.

Ce même fichier peut être appliqué sur n'importe quel cluster Kubernetes (EKS, GKE, AKS, on-premise) sans modification. C'est la portabilité Kubernetes.


5. kubectl — l'outil de la ligne de commande

kubectl est la commande que tout ingénieur Kubernetes tape des dizaines de fois par jour. Elle communique avec l'API Server.

5.1 · Les 15 commandes qui couvrent 90 % des cas

Astuces qui doublent votre productivité kubectl :

  • Alias : alias k=kubectl — vous tapez k get pods au lieu de kubectl get pods.
  • Autocomplétion : source <(kubectl completion bash) — Tab complète tout.
  • Contexte : kubectl config use-context prod — bascule entre clusters.
  • Namespace par défaut : kubectl config set-context --current --namespace=production — évite de taper -n production partout.

5.2 · kubectl vs curl direct — que fait vraiment kubectl ?

kubectl est un client HTTP qui parle à l'API Server via HTTPS avec authentification.

Vous pouvez faire la même chose en curl (utile pour du scripting avancé), mais kubectl vous facilite énormément la vie.


6. Idempotence — le superpouvoir déclaratif

L'idempotence signifie appliquer la même commande N fois donne le même résultat. Kubernetes est totalement idempotent par conception.

Cette propriété est révolutionnaire — vous pouvez automatiser vos déploiements sans peur. Un pipeline CI/CD qui applique 100 fois par jour le même manifest ne fait rien de dangereux — Kubernetes converge intelligemment.


7. GitOps — la conséquence logique

Question logique : si vos manifests YAML sont la source de vérité de votre infrastructure, où les stocker ?

Réponse évidente : dans Git. C'est ce qu'on appelle GitOps.

Avantages de GitOps :

  • Historique complet — chaque déploiement est un commit Git tracé.
  • Rollback trivialgit revert du commit fautif.
  • Audit — qui a déployé quoi, quand, pourquoi ?
  • Multi-cluster — un seul repo Git peut piloter 5 clusters (dev, staging, prod-EU, prod-US, prod-DR).
  • Aucun accès direct au cluster pour les développeurs — tout passe par PR.

Outils GitOps populaires 2026 : Argo CD (le plus utilisé), Flux CD (CNCF graduated), Fleet (Rancher).


8. Helm — les paquets Kubernetes

Écrire tous ces YAML à la main devient vite pénible pour des applications complexes. Helm est le gestionnaire de paquets de Kubernetes — comme apt pour Ubuntu ou npm pour Node.js.

Cas d'usage typique : au lieu d'écrire vous-même 50 manifests YAML pour déployer Prometheus + Grafana + Alertmanager, vous faites :

helm install monitoring prometheus-community/kube-prometheus-stack

Et toute la stack monitoring est déployée, correctement configurée, avec les meilleures pratiques.


Retenir en 30 secondes

  • Kubernetes utilise le modèle déclaratif convergent — vous décrivez, K8s exécute.
  • YAML est la langue — attention à l'indentation par espaces, pas tabulation.
  • Un manifest a 4 sections : apiVersion, kind, metadata, spec.
  • kubectl est le client HTTP qui parle à l'API Server.
  • kubectl apply est idempotent — appliquer 10 fois donne le même résultat.
  • GitOps = Kubernetes + Git + Argo CD / Flux — la source de vérité est Git.
  • Helm = le gestionnaire de paquets Kubernetes (charts, values, install/upgrade).

Suivant : Écosystème et alternatives : EKS, GKE, AKS, K8s vs Docker Swarm vs Nomad →