Passer au contenu principal

Fondamentaux (Kubernetes)

ConfigMaps et Secrets

Séparer la configuration du code et de l'image est un principe fondamental des 12-factor apps. Kubernetes fournit deux objets pour cela : ConfigMap pour les données non sensibles, Secret pour les données sensibles. Les deux s'injectent dans les pods via des variables d'environnement ou des volumes.

ConfigMap

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  APP_ENV: production
  LOG_LEVEL: info
  config.yaml: |        # Fichier entier dans une clé
    server:
      port: 8080
      timeout: 30s
# Créer depuis un fichier existant
kubectl create configmap app-config --from-file=config.yaml
# Créer depuis des valeurs littérales
kubectl create configmap app-config --from-literal=APP_ENV=prod --from-literal=LOG_LEVEL=info

Injection en variables d'environnement

spec:
  containers:
  - name: app
    image: myapp:1.0
    envFrom:
    - configMapRef:
        name: app-config   # Toutes les clés deviennent des variables d'env
    env:
    - name: SPECIFIC_KEY   # Injection d'une seule clé
      valueFrom:
        configMapKeyRef:
          name: app-config
          key: LOG_LEVEL

Injection en volume (fichiers)

spec:
  volumes:
  - name: config-vol
    configMap:
      name: app-config
  containers:
  - name: app
    volumeMounts:
    - name: config-vol
      mountPath: /etc/app    # Chaque clé = un fichier dans ce répertoire

Secret

Les Secrets sont encodés en base64 (pas chiffrés) dans etcd par défaut. Pour du chiffrement au repos, activer EncryptionConfiguration sur l'API server, ou utiliser un secret store externe (Vault, AWS Secrets Manager via External Secrets Operator).

apiVersion: v1
kind: Secret
metadata:
  name: db-credentials
type: Opaque
stringData:           # Automatiquement encodé en base64
  DB_PASSWORD: mysecretpassword
  DB_USER: appuser
# Créer depuis des valeurs littérales
kubectl create secret generic db-credentials   --from-literal=DB_PASSWORD=mysecretpassword

# Créer depuis des fichiers (certificats TLS)
kubectl create secret tls my-tls   --cert=tls.crt --key=tls.key

# Décoder un secret existant
kubectl get secret db-credentials -o jsonpath='{.data.DB_PASSWORD}' | base64 -d

Injection d'un Secret

spec:
  containers:
  - name: app
    envFrom:
    - secretRef:
        name: db-credentials
    volumeMounts:
    - name: tls-certs
      mountPath: /etc/ssl/app
      readOnly: true
  volumes:
  - name: tls-certs
    secret:
      secretName: my-tls

Mise à jour dynamique

Les ConfigMaps et Secrets montés en volume sont mis à jour automatiquement (avec un délai de quelques secondes à minutes, selon le kubelet sync period). Les variables d'environnement, elles, ne sont pas mises à jour sans recréer les pods.

Bonnes pratiques

  • Ne jamais stocker de secrets dans des ConfigMaps
  • Activer le chiffrement etcd au repos en production
  • Envisager External Secrets Operator pour synchroniser depuis Vault, AWS SSM, GCP Secret Manager
  • Versionner les ConfigMaps avec un suffixe hash dans le nom pour forcer le redémarrage des pods lors des changements

Sources