iducationducation
IndexArticlesFormationsProfilOutilsBibliothech
N°014 — 2026
Navigation
01Index02Articles03Formations04Profil05Outils06Bibliothech
N°014 — 2026
iducationducation
IndexArticlesFormationsProfilOutilsBibliothech
N°014 — 2026
Navigation
01Index02Articles03Formations04Profil05Outils06Bibliothech
N°014 — 2026
Formations
YAML / Bash · Intermédiaire

Kubernetes

De Docker Compose à Kubernetes : architecture complète, distributions (K8s, K3s, K0s, MicroK8s), objets fondamentaux, networking, Ingress, scaling automatique et déploiement en production.

KubernetesK3skubectlHelmDocker
01Pourquoi Kubernetes — le problème Docker seul ne résout pas02K8s, K3s, K0s, MicroK8s — quelle distribution choisir03Architecture interne — Control Plane et Worker Nodes04Installation — K3s en production et kubectl05Objets fondamentaux — Pod, Deployment, Service, Namespace06Configuration et stockage — ConfigMap, Secret, PVC07Networking et Ingress — exposer vos services08Scaling, RBAC, Helm et production
Chapitre 6·30 min

Configuration et stockage — ConfigMap, Secret, PVC

Les variables d'environnement hardcodées dans les manifestes sont un antipattern. Kubernetes offre des mécanismes dédiés : ConfigMaps pour les données de configuration, Secrets pour les données sensibles, et PersistentVolumes pour le stockage persistant.

ConfigMap — configuration non sensible

Un ConfigMap stocke des paires clé/valeur ou des fichiers entiers. Utile pour les URLs de service, les feature flags, les configurations Nginx, les fichiers de config YAML.

configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
  namespace: production
data:
  NODE_ENV: production
  LOG_LEVEL: info
  API_URL: https://api.example.com
  nginx.conf: |
    server {
      listen 80;
      location / {
        proxy_pass http://localhost:3000;
      }
    }

Injecter dans un Deployment

Via variables d'environnement :

spec:
  containers:
    - name: app
      env:
        - name: NODE_ENV
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: NODE_ENV
        - name: LOG_LEVEL
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: LOG_LEVEL
      # Ou injecter toutes les clés d'un coup
      envFrom:
        - configMapRef:
            name: app-config

Via volume (pour les fichiers de config) :

spec:
  volumes:
    - name: nginx-config
      configMap:
        name: app-config
        items:
          - key: nginx.conf
            path: nginx.conf
  containers:
    - name: nginx
      volumeMounts:
        - name: nginx-config
          mountPath: /etc/nginx/conf.d/
          readOnly: true

Mise à jour : quand vous mettez à jour un ConfigMap monté en volume, K8s synchronise les fichiers automatiquement (délai ~1 min). Pour les variables d'environnement, il faut redémarrer les pods (kubectl rollout restart deployment/mon-app).

Secret — données sensibles

Les Secrets fonctionnent comme des ConfigMaps mais les valeurs sont encodées en base64 et, avec les bonnes configurations, chiffrées au repos dans etcd.

secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: app-secrets
  namespace: production
type: Opaque
stringData:
  # stringData accepte les valeurs en clair (K8s encode en base64 automatiquement)
  database-url: postgresql://user:password@postgres:5432/mydb
  jwt-secret: mon-secret-tres-long-et-aleatoire
  redis-password: autre-secret
kubectl apply -f secret.yaml
 
# Voir les secrets (base64)
kubectl get secret app-secrets -o yaml
 
# Décoder une valeur
kubectl get secret app-secrets -o jsonpath='{.data.jwt-secret}' | base64 -d

Ne committez jamais un fichier Secret dans Git. Utilisez des outils comme Sealed Secrets, External Secrets Operator, ou Vault pour gérer les secrets K8s en sécurité.

Injecter dans un Deployment

spec:
  containers:
    - name: app
      env:
        - name: DATABASE_URL
          valueFrom:
            secretKeyRef:
              name: app-secrets
              key: database-url
        - name: JWT_SECRET
          valueFrom:
            secretKeyRef:
              name: app-secrets
              key: jwt-secret
      envFrom:
        - secretRef:
            name: app-secrets   # toutes les clés comme variables d'env

Types de Secrets

TypeUsage
OpaqueDonnées génériques (défaut)
kubernetes.io/tlsCertificats TLS (cert.pem + key.pem)
kubernetes.io/dockerconfigjsonCredentials registry Docker
kubernetes.io/service-account-tokenToken de service account

Secret pour un registry Docker privé :

kubectl create secret docker-registry registry-credentials \
  --docker-server=registry.example.com \
  --docker-username=mon-user \
  --docker-password=mon-token \
  -n production
spec:
  imagePullSecrets:
    - name: registry-credentials
  containers:
    - name: app
      image: registry.example.com/mon-app:1.0.0

PersistentVolume et PersistentVolumeClaim

Le stockage des Pods est éphémère par défaut — quand un pod est supprimé, ses données disparaissent. Les PersistentVolumes (PV) permettent de découpler le cycle de vie du stockage de celui du pod.

StorageClass

Définit la classe de stockage disponible. K3s inclut une StorageClass local-path par défaut.

kubectl get storageclass
# NAME                   PROVISIONER             
# local-path (default)   rancher.io/local-path

PersistentVolumeClaim

Vous demandez du stockage via un PVC. K8s provisionne un PV correspondant automatiquement (provisionnement dynamique).

pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: postgres-data
  namespace: production
spec:
  accessModes:
    - ReadWriteOnce         # monté en lecture/écriture sur un seul nœud
  storageClassName: local-path
  resources:
    requests:
      storage: 20Gi

Modes d'accès :

ModeSignification
ReadWriteOnce (RWO)Lecture/écriture par un seul nœud
ReadOnlyMany (ROX)Lecture seule par plusieurs nœuds
ReadWriteMany (RWX)Lecture/écriture par plusieurs nœuds (NFS, CephFS)

Monter un PVC dans un Pod

deployment-avec-pvc.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: postgres
  namespace: production
spec:
  replicas: 1   # RWO = un seul pod peut écrire
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
        - name: postgres
          image: postgres:16-alpine
          env:
            - name: POSTGRES_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: postgres-secrets
                  key: password
            - name: PGDATA
              value: /var/lib/postgresql/data/pgdata
          volumeMounts:
            - name: data
              mountPath: /var/lib/postgresql/data
      volumes:
        - name: data
          persistentVolumeClaim:
            claimName: postgres-data
kubectl get pvc -n production
# NAME            STATUS   VOLUME          CAPACITY   ACCESS MODES
# postgres-data   Bound    pvc-abc123...   20Gi       RWO

Bound = le PVC est associé à un PV. Pending = pas de stockage disponible correspondant.

Emptydir — stockage temporaire partagé entre conteneurs

spec:
  volumes:
    - name: cache
      emptyDir: {}
  containers:
    - name: app
      volumeMounts:
        - name: cache
          mountPath: /tmp/cache
    - name: sidecar
      volumeMounts:
        - name: cache
          mountPath: /cache

emptyDir est créé vide au démarrage du pod et supprimé quand le pod est supprimé. Utile pour partager des fichiers entre conteneurs d'un même pod (logs, cache temporaire).


Configuration et stockage maîtrisés. Le chapitre suivant couvre le networking avancé : types de Services, Ingress NGINX, cert-manager pour le TLS automatique.

Précédent
Objets fondamentaux — Pod, Deployment, Service, Namespace
Suivant
Networking et Ingress — exposer vos services

Développeur fullstack passionné. J'apprends en construisant et je documente tout — front, back, outils. Le code s'apprend mieux en public.

Naviguer

IndexTous les articlesFormationsProfilOutilsBibliothech

Ailleurs

GitHub RSS

Newsletter

Les articles, libs et découvertes. Une fois par semaine, pas plus.

© 2026 William LoreeConçu & codé à la main