DevOpsFacile
AccueilParcours de formationCertificationsModulesCheat SheetÀ Propos
DevOpsFacile

Une plateforme d'apprentissage complète pour maîtriser les pratiques DevOps modernes, du débutant à l'expert.

contact@devopsfacile.fr

Formation

  • Parcours de formation
  • Modules

Informations

  • À Propos
  • Conditions d'utilisation
  • Confidentialité
  • Mentions légales

© 2026 DevOps Facile. Tous droits réservés.

Fait avec pour la communauté DevOps

ModulesCKAD - Configuration, Secrets et Sécurité

Module

Maîtrise ConfigMaps, Secrets, RBAC et Security Contexts pour configurer et sécuriser tes applications Kubernetes.

  • 1 heure 30
  • Avancé

Formation 100 % Linux

Tous les modules nécessitent un environnement Linux. Si vous êtes sur Windows, installez d'abord WSL (Windows Subsystem for Linux) avant de continuer.

CKAD - Configuration, Secrets et Sécurité

🎯 Objectifs

Dans ce module, tu vas :

  • ✅ Comprendre et utiliser ConfigMaps et Secrets
  • ✅ Injecter de la configuration dans tes Pods
  • ✅ Gérer les données sensibles (mots de passe, tokens)
  • ✅ Configurer les Security Contexts
  • ✅ Comprendre les bases du RBAC (Service Accounts, Roles)
  • ✅ Mettre en place des Pod Security Standards

📋 Prérequis

  • Module Kubernetes - Intermédiaire complété
  • Module CKAD - Préparation lu
  • Module CKAD - Applications complété

📖 Pourquoi ce module ?

C'est le domaine le plus important de la CKAD : 25% de la note. Comment tu configures tes applications, comment tu gères tes secrets et comment tu les sécurises.

En tant que développeur, tu dois savoir :

  • Injecter de la configuration sans la hardcoder
  • Gérer les secrets sans risque
  • Limiter les permissions (principe du moindre privilège)
  • Empêcher les mauvaises configurations de sécurité

🔧 ConfigMaps : Externaliser la Configuration

Problème

Tu as une app qui a besoin de configuration (URL de BD, log level, etc.). Où la mettre ?

  • En dur dans le code ? ❌ Non - tu dois reconstruire l'image pour chaque env
  • En variable d'env dans le Pod ? ❌ Non - c'est pas versionné, c'est perdu au redémarrage
  • Dans un ConfigMap ? ✅ Oui - externalise la config du code

Créer une ConfigMap

Mode impératif :

bash
# À partir de valeurs
k create configmap app-config --from-literal=LOG_LEVEL=info --from-literal=DB_HOST=db.local

# À partir d'un fichier
echo "LOG_LEVEL=debug" > config.env
k create configmap app-config --from-env-file=config.env

# À partir d'un fichier entier
k create configmap app-config --from-file=config.yaml

Mode déclaratif :

yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  # Simple key-value
  LOG_LEVEL: info
  DB_HOST: db.local
  DB_PORT: "5432"
  
  # Fichier entier
  application.yaml: |
    server:
      port: 8080
      timeout: 30s
    database:
      host: db.local
      pool_size: 10

Injecter un ConfigMap dans un Pod

Variable d'environnement :

yaml
apiVersion: v1
kind: Pod
metadata:
  name: myapp
spec:
  containers:
  - name: myapp
    image: myapp:1.0
    env:
    - name: LOG_LEVEL
      valueFrom:
        configMapKeyRef:
          name: app-config
          key: LOG_LEVEL
    - name: DB_HOST
      valueFrom:
        configMapKeyRef:
          name: app-config
          key: DB_HOST
    # Ou charger TOUS les clés en une fois
    envFrom:
    - configMapRef:
        name: app-config

Volume (pour un fichier de config) :

yaml
apiVersion: v1
kind: Pod
metadata:
  name: myapp
spec:
  containers:
  - name: myapp
    image: myapp:1.0
    volumeMounts:
    - name: config
      mountPath: /etc/config
  volumes:
  - name: config
    configMap:
      name: app-config
      # Ou des fichiers spécifiques
      items:
      - key: application.yaml
        path: app.yaml

🔐 Secrets : Gérer les Données Sensibles

Problème

Tu as besoin de stocker des mots de passe, tokens, clés API, etc. Les ConfigMaps ne conviennent pas (elles ne sont pas chiffrées par défaut).

Utilise des Secrets.

Créer un Secret

Mode impératif :

bash
# Générique
k create secret generic db-secret --from-literal=password=mysecretpassword

# Docker Registry (pour les images privées)
k create secret docker-registry ghcr-secret \
  --docker-server=ghcr.io \
  --docker-username=myuser \
  --docker-password=mytoken

# TLS/HTTPS
k create secret tls tls-secret \
  --cert=path/to/cert.pem \
  --key=path/to/key.pem

Mode déclaratif :

yaml
apiVersion: v1
kind: Secret
metadata:
  name: db-secret
type: Opaque
stringData:
  # stringData = lisible (encodé en base64 à la création)
  username: admin
  password: secretpassword
---
apiVersion: v1
kind: Secret
metadata:
  name: tls-secret
type: kubernetes.io/tls
data:
  # data = base64 (manuel)
  tls.crt: LS0tLS1CRUdJTi... # base64 encodé
  tls.key: LS0tLS1CRUdJTi...

Types de Secrets

TypeUtilisation
OpaqueDonnées génériques (défaut)
kubernetes.io/dockercfgAuthentification Docker (deprecated)
kubernetes.io/dockercfg-jsonAuthentification Docker Registry
kubernetes.io/basic-authAuthentification HTTP Basic
kubernetes.io/ssh-authAuthentification SSH
kubernetes.io/tlsCertificats TLS
bootstrap.kubernetes.io/tokenToken de bootstrap

Injecter un Secret dans un Pod

Variable d'environnement :

yaml
apiVersion: v1
kind: Pod
metadata:
  name: myapp
spec:
  containers:
  - name: myapp
    image: myapp:1.0
    env:
    - name: DB_PASSWORD
      valueFrom:
        secretKeyRef:
          name: db-secret
          key: password
    envFrom:
    - secretRef:
        name: db-secret

Volume (fichiers) :

yaml
apiVersion: v1
kind: Pod
metadata:
  name: myapp
spec:
  containers:
  - name: myapp
    image: myapp:1.0
    volumeMounts:
    - name: secrets
      mountPath: /etc/secrets
      readOnly: true
  volumes:
  - name: secrets
    secret:
      secretName: db-secret

Imaginer les secrets dans le filesystem :

/etc/secrets/
├── username     (contient "admin")
└── password     (contient "secretpassword")

Utiliser un Secret pour les images Docker privées

yaml
apiVersion: v1
kind: Pod
metadata:
  name: myapp
spec:
  imagePullSecrets:
  - name: ghcr-secret  # Créé avec k create secret docker-registry
  containers:
  - name: myapp
    image: ghcr.io/myorg/myapp:1.0

👤 RBAC : Role-Based Access Control

Problème

Tu veux qu'une app n'ait accès qu'à ce dont elle a besoin (principe du moindre privilège). Par défaut, une app dans un Pod peut faire n'importe quoi dans le cluster.

Les 3 concepts

  1. ServiceAccount : Une identité pour ton app
  2. Role/ClusterRole : Une liste de permissions
  3. RoleBinding/ClusterRoleBinding : Lie l'identité aux permissions

Créer un ServiceAccount

bash
# Mode impératif
k create serviceaccount myapp-sa

# Mode déclaratif
apiVersion: v1
kind: ServiceAccount
metadata:
  name: myapp-sa

Créer une Role (pour un namespace)

yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: pod-reader
spec:
  rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["pods/logs"]
    verbs: ["get"]

Lier le Role au ServiceAccount (RoleBinding)

yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: pod-reader
subjects:
- kind: ServiceAccount
  name: myapp-sa
  namespace: default

Utiliser le ServiceAccount dans un Pod

yaml
apiVersion: v1
kind: Pod
metadata:
  name: myapp
spec:
  serviceAccountName: myapp-sa
  containers:
  - name: myapp
    image: myapp:1.0

Verbes RBAC courants

VerbeSignification
getRécupérer une ressource
listLister les ressources
watchObserver les changements
createCréer une ressource
updateModifier une ressource
patchModifier partiellement
deleteSupprimer une ressource
*Tous les verbes

🔒 Security Contexts

Problème

Par défaut, un conteneur peut tourner en root, accéder au système de fichiers, etc. Ce n'est pas sûr.

Les Security Contexts te permettent de restreindre ce que le conteneur peut faire.

Exemple simple

yaml
apiVersion: v1
kind: Pod
metadata:
  name: secure-app
spec:
  securityContext:
    runAsNonRoot: true     # Ne pas tourner en root
    runAsUser: 1000        # Tourner en tant qu'user 1000
    fsGroup: 2000          # Groupe pour les fichiers
  containers:
  - name: myapp
    image: myapp:1.0
    securityContext:
      allowPrivilegeEscalation: false  # Pas d'escalade de privilèges
      readOnlyRootFilesystem: true     # /
 est read-only
      capabilities:
        drop:
        - ALL              # Supprimer TOUTES les Linux capabilities
        add:
        - NET_BIND_SERVICE # Ajouter que ce qu'il faut (rare)

Options courantes

OptionEffet
runAsUserUID pour tourner le conteneur
runAsNonRootInterdire root (true = safe)
fsGroupPropriétaire des volumes
allowPrivilegeEscalationInterdire sudo (false = safe)
readOnlyRootFilesystem/ est read-only (true = safe)
privilegedMode privilégié (false = safe)
capabilitiesLinux capabilities

🛡️ Pod Security Standards

Les Pod Security Standards remplacent les Pod Security Policies (deprecated). Ce sont des ensembles de recommandations de sécurité.

Trois niveaux

NiveauSévéritéUtilisation
restrictedMaximumProduction, données sensibles
baselineDéfautPlupart des apps
privilegedMinimalApps spéciales (Kubernetes system)

Appliquer une Pod Security Policy

yaml
apiVersion: v1
kind: Namespace
metadata:
  name: production
  labels:
    pod-security.kubernetes.io/enforce: restricted
    pod-security.kubernetes.io/audit: restricted
    pod-security.kubernetes.io/warn: restricted

Cela force tous les Pods du namespace à respecter les règles restricted.


🔧 Exemple complet : App sécurisée et configurée

yaml
---
apiVersion: v1
kind: Namespace
metadata:
  name: myapp-ns
  labels:
    pod-security.kubernetes.io/enforce: baseline

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
  namespace: myapp-ns
data:
  LOG_LEVEL: info
  API_TIMEOUT: "30"

---
apiVersion: v1
kind: Secret
metadata:
  name: app-secrets
  namespace: myapp-ns
stringData:
  DB_PASSWORD: secretpassword123
  API_KEY: sk-1234567890

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: myapp-sa
  namespace: myapp-ns

---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: myapp-reader
  namespace: myapp-ns
rules:
- apiGroups: [""]
  resources: ["configmaps"]
  verbs: ["get"]
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: myapp-reader-binding
  namespace: myapp-ns
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: myapp-reader
subjects:
- kind: ServiceAccount
  name: myapp-sa
  namespace: myapp-ns

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
  namespace: myapp-ns
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      serviceAccountName: myapp-sa
      securityContext:
        runAsNonRoot: true
        runAsUser: 1000
        fsGroup: 2000
      containers:
      - name: myapp
        image: myapp:1.0
        ports:
        - containerPort: 8080
        env:
        - name: LOG_LEVEL
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: LOG_LEVEL
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: app-secrets
              key: DB_PASSWORD
        securityContext:
          allowPrivilegeEscalation: false
          readOnlyRootFilesystem: true
          capabilities:
            drop:
            - ALL
        resources:
          requests:
            cpu: 100m
            memory: 128Mi
          limits:
            cpu: 500m
            memory: 512Mi

📊 Résumé

ConceptUtilisationSensibilité
ConfigMapConfiguration non-sensiblePublic
SecretDonnées sensiblesPrivé
ServiceAccountIdentité pour l'appNormal
RolePermissions limitéesNormal
Security ContextRestrictions conteneurNormal
Pod Security StandardPolitique de sécuritéNormal

🚀 Prochaines Étapes

  • CKAD : Services et Networking - Services, Ingress et DNS
  • CKAD : Volumes et Persistance - Stockage et données persistantes
Retour aux modules

Sur cette page

  • 🎯 Objectifs
  • 📋 Prérequis
  • 📖 Pourquoi ce module ?
  • 🔧 ConfigMaps : Externaliser la Configuration
  • Problème
  • Créer une ConfigMap
  • Injecter un ConfigMap dans un Pod
  • 🔐 Secrets : Gérer les Données Sensibles
  • Problème
  • Créer un Secret
  • Types de Secrets
  • Injecter un Secret dans un Pod
  • Utiliser un Secret pour les images Docker privées
  • 👤 RBAC : Role-Based Access Control
  • Problème
  • Les 3 concepts
  • Créer un ServiceAccount
  • Créer une Role (pour un namespace)
  • Lier le Role au ServiceAccount (RoleBinding)
  • Utiliser le ServiceAccount dans un Pod
  • Verbes RBAC courants
  • 🔒 Security Contexts
  • Problème
  • Exemple simple
  • Options courantes
  • 🛡️ Pod Security Standards
  • Trois niveaux
  • Appliquer une Pod Security Policy
  • 🔧 Exemple complet : App sécurisée et configurée
  • 📊 Résumé
  • 🚀 Prochaines Étapes