ConfigMap Kubernetes : la configuration hors de l’image

Changer une couleur ne devrait pas demander de reconstruire une image Docker. Le ConfigMap sort les réglages du code — avec un piège sur la mise à jour des Pods.

5 min de lecturekubernetesconteneursdevops

Une image Docker est figée. C’est sa qualité principale : ce qui a été testé est exactement ce qui tourne. C’est aussi son inconvénient dès qu’une valeur doit changer.

Le problème, avec un exemple minuscule

Votre application affiche une page avec un titre et une couleur de fond. La couleur est écrite dans le code. On vous demande de passer du bleu au rouge.

Si la valeur est dans l’image :

bash
docker build -t demo-k8s:1.1 ./app    # reconstruire
docker push demo-k8s:1.1              # publier
kubectl set image ...                 # redéployer

Trois étapes, plusieurs minutes, un nouveau numéro de version — pour six caractères hexadécimaux. Et il faudra recommencer au prochain ajustement.

Le ConfigMap

Une petite boîte où Kubernetes garde des réglages, séparés du code et de l’image.

yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: demo-config
  labels:
    app: demo-web
data:
  APP_TITLE: 'Bonjour depuis Kubernetes'
  APP_VERSION: '1.0.0'
  BG_COLOR: '#0f172a'

C’est un dictionnaire, rien de plus : des clés, des valeurs, toutes des chaînes de caractères. Les Pods viennent y lire ce dont ils ont besoin.

     CONFIGMAP
   APP_TITLE
   APP_VERSION
   BG_COLOR

   ┌────┼────┐
   ↓    ↓    ↓
 Pod 1 Pod 2 Pod 3

Le même ConfigMap alimente tous les Pods. Une valeur changée est changée partout.

Deux façons de le consommer, et elles ne se valent pas

C’est le point qui décide du reste, et celui que les tutoriels passent sous silence.

En variables d’environnement

yaml
containers:
  - name: demo-web
    image: demo-k8s:1.0
    envFrom:
      - configMapRef:
          name: demo-config

Simple, lisible, et c’est ce qu’attendent la plupart des applications. Mais les variables d’environnement d’un processus sont fixées à son démarrage et ne peuvent plus changer. Modifier le ConfigMap ne touche donc pas les Pods qui tournent.

En fichiers montés

yaml
containers:
  - name: demo-web
    volumeMounts:
      - name: config
        mountPath: /etc/config
volumes:
  - name: config
    configMap:
      name: demo-config

Chaque clé devient un fichier dans /etc/config. Ici, Kubernetes met à jour le contenu quand le ConfigMap change — avec un délai de l’ordre d’une minute. Reste à ce que l’application relise ses fichiers, ce qui n’est pas automatique non plus.

Variables d’environnementFichiers montés
Simplicitégrandemoyenne
Mise à jour sans redémarrageimpossiblepossible
Valeurs longues ou multilignesmal adaptéfait pour ça

Ce que devient un changement, selon le mode choisi :

Le piège : modifier un ConfigMap ne redémarre rien

C’est l’erreur qui fait perdre une demi-heure. Vous appliquez :

bash
kubectl apply -f k8s/configmap.yaml

La commande réussit, la nouvelle valeur est bien dans le cluster — et la page affiche toujours l’ancienne couleur. Rien ne signale le problème, parce qu’il n’y a pas de problème : Kubernetes a fait exactement ce qu’on lui demandait, c’est-à-dire mettre à jour un ConfigMap.

Il faut redémarrer les Pods :

bash
kubectl rollout restart deployment demo-web

Ce qui déclenche un remplacement progressif, sans coupure. Vérification :

bash
kubectl rollout status deployment demo-web
Comment faire pour que ce soit automatique ?

La technique courante est de mettre une empreinte du ConfigMap dans les annotations du template de Pod. Comme le template change, le Deployment considère qu’il y a une nouvelle version et remplace les Pods de lui-même.

yaml
template:
  metadata:
    annotations:
      checksum/config: '<empreinte du contenu du ConfigMap>'

Helm le fait en une ligne, et les outils de déploiement continu proposent l’équivalent. C’est plus fiable que de compter sur quelqu’un pour penser au rollout restart.

Ce qu’un ConfigMap n’est pas

Un endroit pour les secrets. Les valeurs y sont stockées en clair, visibles par quiconque peut lire les ressources du namespace. Mots de passe, clés d’API et jetons vont dans un Secret.

Avec une nuance qu’il faut connaître : un Secret n’est encodé qu’en base64, ce qui n’est pas du chiffrement. Il apporte un contrôle d’accès distinct et l’absence d’affichage dans les journaux, pas de la confidentialité. Pour une vraie protection, il faut le chiffrement au repos activé sur le cluster, ou un gestionnaire de secrets externe — ce que le Secret protège et ce qu’il ne protège pas fait le tour de la question.

Un magasin de données. La limite est de 1 Mio, et ce n’est pas une invitation à s’en approcher. Un ConfigMap tient des réglages, pas un jeu de données.

Un objet versionné. Il n’y a pas d’historique et pas de retour en arrière. Une mauvaise valeur appliquée est appliquée ; d’où l’intérêt de garder ces fichiers dans un dépôt Git, qui fournit la version et la revue que Kubernetes ne fournit pas.

Ce qu’il faut retenir

Le ConfigMap sépare ce que fait l’application de comment elle est réglée. L’image reste identique d’un environnement à l’autre — développement, recette, production — et seuls les réglages changent. C’est ce qui rend une image réellement réutilisable.

Deux réflexes à garder : après un changement, un kubectl rollout restart si vous passez par des variables d’environnement ; et jamais de secret dans un ConfigMap.

Pour situer le ConfigMap parmi les autres objets, voyez Docker et Kubernetes : qui fait quoi. Pour l’objet qui consomme cette configuration, le Deployment. Et pour tout ce qui ne doit pas s’y trouver, le Secret.

Ce sujet fait partie d’un cours complet

Développement et déploiement de solutions de données — les premiers modules sont en accès libre.

Voir le plan du cours

Continuer sur le même sujet