ITSkillsCenter
Business Digital

ConfigMaps, Secrets, ServiceAccounts et SecurityContext CKAD 2026

9 min de lecture

📍 Article principal du cluster : CKAD Certified Kubernetes Application Developer — guide pratique 2026

Ce tutoriel fait partie du cluster certification CKAD. Pour la vue d’ensemble, lisez d’abord le pilier.

Introduction

Le domaine 3 « Application Environment, Configuration and Security » pèse 25 % de l’examen CKAD — la part la plus dense du syllabus. C’est aussi le domaine où la majorité des candidats perdent des points par méconnaissance de subtilités : différence entre injection ConfigMap par variable d’environnement et par fichier monté, base64 vs chiffrement réel des Secrets, ServiceAccount par défaut vs ServiceAccount dédié, requests vs limits, ResourceQuota namespace-scoped vs LimitRange. Ce tutoriel pratique chacun de ces concepts avec des manifests testés sur cluster kind 1.35.

Prérequis

  • Cluster kind 1.35 fonctionnel
  • Avoir terminé les tutoriels précédents du cluster
  • 40 minutes

Étape 1 — Créer un ConfigMap depuis un fichier

Le ConfigMap stocke des données de configuration non-secrètes : URLs d’API, niveaux de log, feature flags, paramètres de runtime. Trois méthodes de création : `–from-literal`, `–from-file`, ou manifest YAML directe.

cat > app.properties <<EOF
LOG_LEVEL=info
API_BASE_URL=https://api.example.com
FEATURE_FLAGS=new_ui,fast_search
EOF

k create configmap app-config --from-file=app.properties $do > cm.yaml
k apply -f cm.yaml
k get configmap app-config -o yaml | head -20

La sortie YAML montre les données dans la section `data:`, avec la clé `app.properties` contenant l’intégralité du fichier comme valeur. C’est exactement ce qui est monté quand vous référez ce ConfigMap par fichier dans un Pod.

Étape 2 — Injecter un ConfigMap par variable d’environnement

L’injection par variable env est la méthode la plus simple : chaque clé du ConfigMap devient une variable d’environnement du conteneur. Limite : les changements ne sont pas propagés dynamiquement — il faut redémarrer le Pod.

k create configmap envs-cm --from-literal=APP_ENV=production --from-literal=DEBUG=false

cat > pod-env.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
  name: env-consumer
spec:
  containers:
  - name: app
    image: busybox:1.37
    command: ["sh","-c","env | grep -E 'APP_ENV|DEBUG'; sleep 3600"]
    envFrom:
    - configMapRef:
        name: envs-cm
EOF

k apply -f pod-env.yaml
sleep 5
k logs env-consumer | head -5

La sortie affiche `APP_ENV=production` et `DEBUG=false`. Le `envFrom` injecte toutes les clés du ConfigMap d’un coup. Pour ne prendre qu’une clé, utilisez `env.valueFrom.configMapKeyRef`.

Étape 3 — Injecter un ConfigMap par fichier monté

L’injection par fichier monté traite le ConfigMap comme un volume : chaque clé devient un fichier dans le répertoire monté. Avantage critique : les changements du ConfigMap sont propagés dans le volume sans redémarrage du Pod (avec un délai de quelques dizaines de secondes lié au sync kubelet).

cat > pod-mount.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
  name: file-consumer
spec:
  volumes:
  - name: config-vol
    configMap:
      name: app-config
  containers:
  - name: app
    image: busybox:1.37
    command: ["sh","-c","cat /etc/conf/app.properties; sleep 3600"]
    volumeMounts:
    - name: config-vol
      mountPath: /etc/conf
EOF

k apply -f pod-mount.yaml
sleep 5
k logs file-consumer

Le contenu du fichier `app.properties` apparaît dans les logs. Cette méthode est préférable pour des fichiers de configuration entiers (nginx.conf, my.cnf, application.yml) plutôt que pour des variables individuelles.

Étape 4 — Créer un Secret et comprendre l’encodage base64

Les Secrets stockent des données sensibles. Point critique de l’examen : les Secrets sont encodés en base64, pas chiffrés. N’importe qui ayant accès à etcd ou à l’API Kubernetes peut décoder le secret. Le chiffrement at-rest dans etcd est une fonctionnalité séparée à activer manuellement avec `EncryptionConfiguration`.

k create secret generic db-creds \
  --from-literal=username=admin \
  --from-literal=password=Tr0ub4dor

k get secret db-creds -o yaml
echo "YWRtaW4=" | base64 -d  # admin
echo "VHIwdWI0ZG9y" | base64 -d  # Tr0ub4dor

Vous voyez clairement le username et le password en clair après décodage base64. Cette démonstration tombe systématiquement à l’examen sous forme de question piège : « les Secrets sont-ils chiffrés ? » — la réponse correcte est « non, juste encodés base64 ; le chiffrement at-rest doit être configuré séparément ».

Étape 5 — Injecter un Secret comme variable d’environnement

L’injection d’un Secret suit la même logique qu’un ConfigMap. Pratique courante : password de base de données injecté dans une application via env.

cat > pod-secret.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
  name: db-app
spec:
  containers:
  - name: app
    image: busybox:1.37
    command: ["sh","-c","echo \"User=$DB_USER\"; echo \"Pass=$DB_PASS\"; sleep 3600"]
    env:
    - name: DB_USER
      valueFrom:
        secretKeyRef:
          name: db-creds
          key: username
    - name: DB_PASS
      valueFrom:
        secretKeyRef:
          name: db-creds
          key: password
EOF

k apply -f pod-secret.yaml
sleep 5
k logs db-app

La sortie affiche `User=admin` et `Pass=Tr0ub4dor` — les Secrets sont injectés en clair dans le conteneur. C’est ainsi que les applications les consomment. La sécurité repose sur la limitation de l’accès au Pod et sur le chiffrement at-rest d’etcd.

Étape 6 — ServiceAccount dédié et token automounté

Chaque Pod tourne avec un ServiceAccount, par défaut `default`. Pour un Pod qui interagit avec l’API Kubernetes (par exemple un controller, un job de monitoring), créez un ServiceAccount dédié avec les permissions minimales nécessaires.

k create serviceaccount monitor-sa
k create role pod-reader --verb=get,list,watch --resource=pods
k create rolebinding monitor-sa-binding --role=pod-reader --serviceaccount=default:monitor-sa

cat > pod-sa.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
  name: monitor-pod
spec:
  serviceAccountName: monitor-sa
  containers:
  - name: monitor
    image: bitnami/kubectl:1.35
    command: ["sh","-c","kubectl get pods; sleep 3600"]
EOF

k apply -f pod-sa.yaml
sleep 5
k logs monitor-pod | head -10

Le Pod liste les pods du namespace `default` car son ServiceAccount a la permission `get pods`. Si vous tentez `kubectl get nodes` dans ce Pod, vous obtenez une erreur 403 Forbidden — démontrant que les permissions sont strictement scopées.

Étape 7 — Configurer requests, limits et ResourceQuota

Les requests garantissent une réservation de ressources sur le nœud. Les limits définissent le plafond — un dépassement déclenche un OOMKill (RAM) ou un throttling (CPU). Le ResourceQuota limite les ressources totales d’un namespace.

k create namespace dev-team
k create quota dev-quota --hard=cpu=2,memory=2Gi,pods=10 -n dev-team

cat > pod-resources.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
  name: app-with-limits
  namespace: dev-team
spec:
  containers:
  - name: app
    image: nginx:1.27
    resources:
      requests:
        cpu: "100m"
        memory: "64Mi"
      limits:
        cpu: "500m"
        memory: "128Mi"
EOF

k apply -f pod-resources.yaml
k describe quota dev-quota -n dev-team
k describe pod app-with-limits -n dev-team | grep -A 5 Limits

La sortie de `describe quota` montre la consommation actuelle (« used: cpu=100m, memory=64Mi, pods=1 ») par rapport au plafond. Tout Pod créé dans ce namespace doit déclarer ses resources, sinon l’admission webhook rejette la création.

Étape 8 — SecurityContext pour durcissement

Le SecurityContext applique des restrictions Linux au conteneur : utilisateur non-root, capabilities Linux drop-all, filesystem en lecture seule, escalade de privilèges interdite. Domaine 3c du syllabus.

cat > pod-secure.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
  name: secure-app
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
    fsGroup: 2000
  containers:
  - name: app
    image: busybox:1.37
    command: ["sh","-c","id; ls -la /; sleep 3600"]
    securityContext:
      allowPrivilegeEscalation: false
      capabilities:
        drop: ["ALL"]
      readOnlyRootFilesystem: true
EOF

k apply -f pod-secure.yaml
sleep 5
k logs secure-app | head -5

La sortie de `id` doit afficher `uid=1000`. Le filesystem est en read-only, ce qui empêche tout malware de modifier le binaire applicatif. C’est la posture de sécurité recommandée par les Pod Security Standards Restricted.

Comprendre la différence env vs envFrom vs volumeMounts

Trois méthodes pour injecter une configuration dans un conteneur, chacune avec ses cas d’usage. env injecte une variable individuelle référençant une clé spécifique du ConfigMap ou Secret. Verbose mais explicite — vous voyez exactement quelles variables sont injectées. envFrom injecte toutes les clés du ConfigMap/Secret en une seule directive. Pratique mais opaque — un nouveau dev doit lire le ConfigMap pour savoir ce qui est exposé. volumeMounts monte le ConfigMap/Secret comme arborescence de fichiers. Préférable pour les fichiers de config entiers et permet la propagation dynamique des modifications.

Règle pratique CKAD : env pour 1-3 variables critiques (DATABASE_URL, API_KEY), envFrom pour batches de variables environnementales, volumeMounts pour les fichiers nginx.conf, application.yml, settings.json.

Erreurs fréquentes

Erreur Cause Solution
Pod refuse de démarrer avec runAsNonRoot Image conteneur tourne en root par défaut Choisir une image qui spécifie USER non-root, ou ajuster le Dockerfile
Secret non trouvé Mismatch de namespace Le Secret doit être dans le même namespace que le Pod
ResourceQuota bloque la création Pod sans requests/limits explicites Toujours déclarer resources dans les manifests si quota actif
Permission denied sur ServiceAccount RoleBinding manquante ou wrong namespace `kubectl auth can-i –as=system:serviceaccount:NS:NAME VERB RESOURCE`
ConfigMap update non propagé Injection par env Redéployer le Pod (`kubectl rollout restart`) ou utiliser volumeMount pour propagation dynamique

Adaptation au contexte ouest-africain

Pour les startups dakaroises et abidjanaises qui montent leur premier cluster k8s, le pattern recommandé est : ConfigMap pour 90 % de la config, Secret pour les credentials externes (DB, API tierces, mobile money), External Secrets Operator pour synchroniser depuis Vault ou AWS Secrets Manager si vous avez ces systèmes en place. Activer le chiffrement at-rest etcd est obligatoire pour toute application qui manipule des données utilisateurs (PCI-DSS, RGPD, OHADA-PD). Sur Hostinger Cloud Startup avec k3s, cette configuration est documentée dans la doc Rancher et prend environ 30 minutes à mettre en place.

Tutoriels frères

Pour aller plus loin

FAQ

Faut-il toujours créer un ServiceAccount dédié ?
Pour les Pods qui n’interagissent pas avec l’API Kubernetes : non, le `default` suffit. Pour les Pods controllers, jobs admin, agents : oui, créez un SA dédié avec permissions minimales.

Comment chiffrer les Secrets at-rest ?
Configurez `EncryptionConfiguration` dans kube-apiserver avec un provider AES-CBC ou KMS. Hors scope CKAD mais essentiel en production.

Mots-clés secondaires : ckad configmap secret, serviceaccount kubernetes, resourcequota limitrange, securitycontext ckad, runasnonroot, base64 vs chiffrement

Besoin d'un site web ?

Confiez-nous la Création de Votre Site Web

Site vitrine, e-commerce ou application web — nous transformons votre vision en réalité digitale. Accompagnement personnalisé de A à Z.

À partir de 250.000 FCFA
Parlons de Votre Projet
Publicité