Tu as une image Docker qui tourne nickel en dev. Tu la pousses en staging et… rien ne marche. L’URL de la base de données est en dur dans le code, le mot de passe aussi. Tu rebuilds l’image pour chaque environnement. Classique, et totalement évitable.
Kubernetes propose deux ressources pour séparer la configuration du code : les ConfigMaps pour la config non sensible, et les Secrets pour les données confidentielles. Ce chapitre t’apprend à les maîtriser — et surtout à éviter les erreurs que tout le monde fait en production.
Pourquoi c’est important
Le principe 12-Factor App est clair : la configuration doit vivre en dehors du code. En dur dans l’image Docker, ta config devient un boulet — tu rebuilds pour chaque changement, tu dupliques des images quasi identiques, et tu risques de leaker des credentials dans ton registry.
Avec les ConfigMaps et Secrets, tu obtiens :
- Une seule image pour tous tes environnements (dev, staging, prod)
- Des modifications à chaud sans rebuild ni redéploiement
- Une séparation claire entre ce qui est sensible et ce qui ne l’est pas
- Un workflow GitOps propre où la config est versionnée à côté des manifestes
🧠 À retenir : Une image Docker ne devrait jamais contenir de configuration spécifique à un environnement. Si tu changes d’env, tu changes la ConfigMap, pas l’image.
Comprendre le concept
ConfigMap : ta config externalisée
Un ConfigMap stocke des paires clé-valeur. Tu peux y mettre des variables simples (LOG_LEVEL=info) ou des fichiers entiers (un nginx.conf, un application.yml). Kubernetes les injecte dans tes Pods de deux façons : en variables d’environnement ou en fichiers montés via un volume.
Secret : le ConfigMap des données sensibles
Un Secret fonctionne exactement comme un ConfigMap, mais il est conçu pour les mots de passe, tokens API, certificats TLS et clés SSH. Les valeurs sont encodées en base64 dans le manifeste YAML.
⚠️ Attention : base64 n’est pas du chiffrement. N’importe qui avec kubectl get secret -o yaml peut décoder tes données. En production, active le chiffrement at rest d’etcd et restreins les accès RBAC.
Sealed Secrets : le chaînon manquant pour GitOps
Tu veux stocker tes manifestes dans Git mais les Secrets contiennent des données en clair ? Sealed Secrets résout ce problème. Un outil CLI (kubeseal) chiffre tes Secrets avec une clé publique. Seul le contrôleur installé dans le cluster peut les déchiffrer. Le fichier chiffré est safe pour Git.
Commandes essentielles
Voici comment créer et consommer des ConfigMaps et Secrets au quotidien. On commence par créer une ConfigMap avec des valeurs littérales et un Secret pour les credentials d’une base de données :
# ConfigMap depuis des valeurs littérales
kubectl create configmap app-config \
--from-literal=APP_ENV=production \
--from-literal=LOG_LEVEL=info
# ConfigMap depuis un fichier de config
kubectl create configmap nginx-conf \
--from-file=default.conf=./nginx.conf
# Secret générique
kubectl create secret generic db-creds \
--from-literal=DB_USER=admin \
--from-literal=DB_PASSWORD='S3cur3P@ss!'
# Secret TLS depuis un certificat
kubectl create secret tls app-tls \
--cert=tls.crt --key=tls.key
💡 Tip DevOps : Utilise --dry-run=client -o yaml pour générer le YAML sans appliquer. Parfait pour versionner dans Git ou piper vers kubeseal.
Pour injecter ces ressources dans un Pod, tu as deux approches. L’injection en variables d’environnement est la plus simple — chaque clé devient une variable accessible dans ton conteneur :
apiVersion: v1
kind: Pod
metadata:
name: api-server
spec:
containers:
- name: api
image: my-api:2.0
env:
- name: APP_ENV
valueFrom:
configMapKeyRef:
name: app-config
key: APP_ENV
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-creds
key: DB_PASSWORD
envFrom:
- configMapRef:
name: app-config
Pour injecter un fichier de configuration complet (comme un nginx.conf), tu montes la ConfigMap comme un volume. Chaque clé devient un fichier dans le répertoire cible :
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-custom
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.27
volumeMounts:
- name: config-vol
mountPath: /etc/nginx/conf.d
readOnly: true
volumes:
- name: config-vol
configMap:
name: nginx-conf
🧠 À retenir : Les ConfigMaps montées en volume se mettent à jour automatiquement (~60s). Les variables d’environnement, non — il faut redémarrer le Pod.
Cas concret entreprise
🔥 Cas réel : Une équipe déploie une API e-commerce sur trois environnements (dev, staging, prod). Chaque env a sa propre base de données, son niveau de log et son URL de cache Redis.
Voici le manifeste déclaratif qui combine ConfigMap pour la config applicative et Secret pour les credentials. Un seul Deployment, trois comportements différents selon le namespace :
# config-prod.yaml — à appliquer dans le namespace "prod"
apiVersion: v1
kind: ConfigMap
metadata:
name: api-config
namespace: prod
data:
APP_ENV: "production"
LOG_LEVEL: "warn"
REDIS_URL: "redis-prod.internal:6379"
---
apiVersion: v1
kind: Secret
metadata:
name: api-secrets
namespace: prod
type: Opaque
stringData:
DB_URL: "postgresql://prod-db.internal:5432/shop"
DB_PASSWORD: "Pr0d-Sup3r-S3cr3t!"
API_KEY: "sk-live-abc123xyz"
L’équipe chiffre le Secret avec Sealed Secrets avant de le commiter dans Git :
# Générer le Secret en dry-run, puis chiffrer
kubectl create secret generic api-secrets \
--namespace=prod \
--from-literal=DB_URL='postgresql://prod-db.internal:5432/shop' \
--from-literal=DB_PASSWORD='Pr0d-Sup3r-S3cr3t!' \
--dry-run=client -o yaml | kubeseal --format yaml \
> sealed-api-secrets-prod.yaml
Le fichier sealed-api-secrets-prod.yaml est pushé dans le repo Git. ArgoCD l’applique automatiquement. Le contrôleur Sealed Secrets le déchiffre dans le cluster. Les vrais credentials ne quittent jamais le cluster.
💡 Tip DevOps : Versionne le nom de tes ConfigMaps immuables (api-config-v3, api-config-v4). Un rolling update se déclenche automatiquement quand tu changes la référence dans le Deployment.
Pièges fréquents
1. Croire que base64 = sécurité. Un echo YWRtaW4= | base64 -d et ton mot de passe est en clair. Toujours combiner Secrets + chiffrement at rest + RBAC strict.
2. Utiliser des variables d’environnement pour les secrets critiques. Les env vars apparaissent dans les logs de debug, les core dumps et /proc/<pid>/environ. Monte tes secrets en fichiers avec des permissions restrictives (defaultMode: 0400).
3. Oublier que les env vars ne se rafraîchissent pas. Tu modifies une ConfigMap, mais ton app garde les anciennes valeurs. Seuls les volumes montés se mettent à jour automatiquement.
4. Commiter des Secrets en clair dans Git. Même si tu les supprimes après, l’historique Git les garde. Utilise Sealed Secrets ou un vault externe (HashiCorp Vault, AWS Secrets Manager).
5. Pas de RBAC sur les Secrets. Par défaut, tout ServiceAccount peut lire tous les Secrets du namespace. Verrouille les accès avec des Roles ciblés.
⚠️ Attention : Un kubectl get secret db-creds -o jsonpath='{.data.DB_PASSWORD}' | base64 -d affiche le mot de passe en clair. Contrôle qui a accès à cette commande via RBAC et audit logs.
Exercice pratique
Objectif : Déployer Nginx avec une page de status personnalisée, alimentée par une ConfigMap, et des credentials factices dans un Secret monté en fichier.
- Crée une ConfigMap
status-configcontenant une clédefault.confavec un bloc serveur Nginx qui renvoie{"status": "ok", "env": "staging"}sur/health - Crée un Secret
app-credsavecAPI_KEY=test-key-12345 - Déploie Nginx en montant la ConfigMap dans
/etc/nginx/conf.det le Secret dans/etc/secrets - Vérifie avec
kubectl execque/etc/secrets/API_KEYcontient la valeur décodée - Modifie la ConfigMap (change
stagingenproduction) et vérifie que le fichier se met à jour sans redémarrer le Pod
💡 Solution
Crée les ressources et le Deployment dans un seul fichier :
apiVersion: v1
kind: ConfigMap
metadata:
name: status-config
data:
default.conf: |
server {
listen 80;
location /health {
default_type application/json;
return 200 '{"status": "ok", "env": "staging"}';
}
}
---
apiVersion: v1
kind: Secret
metadata:
name: app-creds
type: Opaque
stringData:
API_KEY: "test-key-12345"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-status
spec:
replicas: 1
selector:
matchLabels:
app: nginx-status
template:
metadata:
labels:
app: nginx-status
spec:
containers:
- name: nginx
image: nginx:1.27
ports:
- containerPort: 80
volumeMounts:
- name: nginx-conf
mountPath: /etc/nginx/conf.d
- name: secrets
mountPath: /etc/secrets
readOnly: true
volumes:
- name: nginx-conf
configMap:
name: status-config
- name: secrets
secret:
secretName: app-creds
defaultMode: 0400
Vérifie le résultat :
kubectl apply -f nginx-status.yaml
kubectl exec deploy/nginx-status -- cat /etc/secrets/API_KEY
# test-key-12345
kubectl port-forward deploy/nginx-status 8080:80
curl localhost:8080/health
# {"status": "ok", "env": "staging"}
À retenir
- ConfigMap = configuration non sensible (env vars, fichiers de config, feature flags)
- Secret = données sensibles (mots de passe, tokens, certificats) — base64 ≠ chiffrement
- Sealed Secrets = chiffrement côté client pour un workflow GitOps propre
- Volumes montés > variables d’environnement pour les secrets (sécurité + mise à jour auto)
- Une image, plusieurs configs : le découplage code/config est la base d’un déploiement Kubernetes sain
🧠 À retenir : Pense aux ConfigMaps comme des fichiers
.envversionnés et aux Secrets comme un coffre-fort avec une serrure en carton — rajoute un vrai verrou (Sealed Secrets, Vault) avant d’aller en production.
➡️ La suite
Prochain chapitre : la sécurité Kubernetes — RBAC, Network Policies, Pod Security Standards. Parce qu’un cluster sans sécurité, c’est une porte ouverte sur Internet.
🖥️ Pratique sur ton propre serveur
Pour suivre Apprendre Kubernetes en conditions réelles, tu as besoin d'un VPS. DigitalOcean offre 200$ de crédit gratuit pour démarrer.
Contenu réservé aux abonnés
Ce chapitre fait partie de la formation complète. Abonne-toi pour débloquer tous les contenus.
Débloquer pour 29 CHF/moisLe chapitre 1 de chaque formation est gratuit.
Série pas encore débloquée
Termine la série prérequise d'abord pour accéder à ce contenu.
Aller à la série prérequiseSérie : Apprendre Kubernetes
6 / 12- Pourquoi Kubernetes ? L'orchestration expliquée
- Architecture K8s et premières commandes kubectl
- Deployments : déployer et mettre à jour
- Services : exposer tes applications
- Volumes et stockage persistant
- 6 ConfigMaps et Secrets
- 7 RBAC : qui a accès à quoi
- 8 Network Policies et Pod Security
- 9 CNI et networking K8s en détail
- 10 Service Mesh : Istio et Linkerd
- 11 Helm : le package manager de K8s
- 12 Créer et publier son chart Helm
Sur cette page
Articles liés
Pourquoi Kubernetes ? L'orchestration expliquée
Découvre pourquoi Kubernetes est devenu le standard de l'orchestration : architecture, concepts fondamentaux et installation locale.
Architecture K8s et premières commandes kubectl
Installe Kind, lance ton premier déploiement et maîtrise les commandes kubectl essentielles.
Deployments : déployer et mettre à jour
Maîtrise les Deployments Kubernetes : ReplicaSets, rolling updates, rollbacks et scaling horizontal.