
ConfigMaps : Gérer la configuration non sensible
Apprenez à utiliser les ConfigMaps Kubernetes pour découpler et gérer efficacement les données de configuration non sensibles de vos applications.
Externaliser la configuration : voici les ConfigMaps
Comme nous l'avons vu, coder en dur la configuration dans les images de conteneurs ou même directement dans les manifestes de Pods via des variables d'environnement ou des arguments n'est pas idéal, surtout lorsque la configuration change ou devient complexe. Pour résoudre ce problème de manière élégante, Kubernetes propose un objet API dédié au stockage des données de configuration non sensibles : le ConfigMap.
Un ConfigMap vous permet de découpler la configuration de la définition de vos Pods. Vous stockez vos paramètres, fichiers de configuration ou autres données non confidentielles dans un objet ConfigMap distinct, puis vous référencez ce ConfigMap depuis vos Pods pour injecter ces données là où elles sont nécessaires (variables d'environnement, fichiers montés en volume).
Cette approche rend vos images de conteneurs plus génériques et réutilisables, facilite la gestion des configurations pour différents environnements (développement, staging, production) en utilisant différents ConfigMaps, et permet de mettre à jour la configuration sans avoir à reconstruire les images.
Structure et contenu d'un ConfigMap
Un ConfigMap stocke les données sous forme de paires clé-valeur. Les valeurs peuvent être de simples chaînes de caractères ou le contenu de fichiers entiers.
La structure d'un manifeste YAML pour un ConfigMap est simple :
apiVersion: v1
kind: ConfigMap
metadata:
name: mon-app-config # Nom du ConfigMap
namespace: production # Les ConfigMaps sont namespacés
data: # Stocke les données sous forme de chaînes UTF-8
# Clé-valeur simple
database.url: "jdbc:mysql://mysql.production.svc.cluster.local:3306/mydb"
log.level: "WARN"
# Contenu d'un fichier de configuration via une clé multiligne
nginx.conf: |
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
# Autre fichier
ui.properties: |
color.good=purple
color.bad=yellow
allow.textmode=true
# binaryData: # Stocke les données binaires encodées en base64
# clave.jks: "[BASE64_ENCODED_DATA]"Points clés :
- `metadata.name` : Le nom utilisé pour référencer le ConfigMap.
- `data` : Un dictionnaire où les clés sont les noms des entrées de configuration et les valeurs sont les données correspondantes sous forme de chaînes de caractères (UTF-8). C'est la section la plus couramment utilisée.
- `binaryData` : Permet de stocker des données binaires. Les valeurs doivent être encodées en base64. Si une clé existe à la fois dans `data` et `binaryData`, `binaryData` a la priorité.
Créer des ConfigMaps
Vous pouvez créer des ConfigMaps de plusieurs manières :
- A partir de fichiers YAML (méthode déclarative) : Ecrivez le manifeste YAML comme ci-dessus et appliquez-le avec `kubectl apply -f mon-configmap.yaml`.
- A partir de valeurs littérales avec `kubectl` :
kubectl create configmap mon-config-literal \ --from-literal=database.host=mysql \ --from-literal=log.level=info \ -n mon-namespace - A partir d'un fichier individuel avec `kubectl` : Le nom du fichier devient la clé, et le contenu du fichier devient la valeur.
Le ConfigMap contiendra une clé `nginx.conf` avec le contenu du fichier. Vous pouvez spécifier une clé différente avec `--from-file=ma-cle=chemin/vers/fichier`.kubectl create configmap config-depuis-fichier \ --from-file=chemin/vers/mon/nginx.conf \ -n mon-namespace - A partir d'un répertoire avec `kubectl` : Chaque fichier dans le répertoire spécifié devient une entrée dans le ConfigMap, avec le nom de fichier comme clé et le contenu comme valeur.
kubectl create configmap config-depuis-dossier \ --from-file=chemin/vers/mon/dossier/config/ \ -n mon-namespace
La méthode déclarative (fichier YAML) est généralement préférée pour la gestion via Git (GitOps), tandis que les commandes `kubectl create` sont pratiques pour une création rapide ou à partir de fichiers existants.
Utiliser les ConfigMaps dans les Pods
Une fois un ConfigMap créé, vous pouvez injecter ses données dans les conteneurs de vos Pods de deux manières principales :
- Comme Variables d'Environnement :
- Injecter une clé spécifique : Utilisez `env.valueFrom.configMapKeyRef`.
La variable `LOG_LEVEL_APP` dans le conteneur aura la valeur associée à la clé `log.level` dans `mon-app-config`.spec: containers: - name: mon-conteneur image: mon-image env: - name: LOG_LEVEL_APP # Nom de la variable dans le conteneur valueFrom: configMapKeyRef: name: mon-app-config # Nom du ConfigMap key: log.level # Clé à récupérer dans le ConfigMap
- Injecter toutes les clés comme variables : Utilisez `envFrom.configMapRef`. Chaque clé du ConfigMap devient le nom d'une variable d'environnement dans le conteneur.
Si `mon-app-config` a les clés `database.url` et `log.level`, le conteneur aura les variables `database.url` et `log.level`. (Attention aux noms de clés non valides pour les variables d'env, K8s les ignorera).spec: containers: - name: mon-conteneur image: mon-image envFrom: - configMapRef: name: mon-app-config # Nom du ConfigMap - Comme Fichiers dans un Volume : Montez le ConfigMap comme un type de volume spécial.
- Monter toutes les clés comme fichiers : Chaque clé du ConfigMap devient un fichier dans le répertoire de montage (`mountPath`), où le nom du fichier est la clé et le contenu du fichier est la valeur.
Le répertoire `/etc/config` contiendra les fichiers `database.url`, `log.level`, `nginx.conf`, etc.spec: containers: - name: mon-conteneur image: mon-image volumeMounts: - name: config-volume # Nom du montage mountPath: /etc/config # Répertoire de montage dans le conteneur volumes: - name: config-volume # Nom du volume, doit correspondre au volumeMount configMap: name: mon-app-config # Nom du ConfigMap à monter
- Monter des clés spécifiques comme fichiers (projection) : Vous pouvez choisir quelles clés monter et leur donner des noms de fichier spécifiques.
Ici, seul le contenu de la clé `nginx.conf` du ConfigMap est monté comme fichier `nginx_config` dans `/etc/nginx/conf.d` à l'intérieur du conteneur.spec: containers: - name: mon-conteneur image: mon-image volumeMounts: - name: config-volume mountPath: /etc/nginx/conf.d # Monter un fichier spécifique ici subPath: nginx_config # Nom du fichier dans le conteneur (si différent de la clé) # readOnly: true (souvent une bonne idée) volumes: - name: config-volume configMap: name: mon-app-config items: - key: nginx.conf # Clé du ConfigMap path: nginx_config # Nom du fichier dans le volume (qui sera monté via subPath)
Le montage en volume est souvent préféré pour les fichiers de configuration complets, tandis que les variables d'environnement conviennent mieux aux paramètres simples.
Mises à jour et remarques importantes
Quelques points importants concernant les ConfigMaps :
- Non-sensibilité : Rappelez-vous que les ConfigMaps sont destinés à des données non sensibles. N'y stockez jamais de mots de passe, tokens ou clés API. Utilisez les Secrets pour cela.
- Mises à jour : Si vous mettez à jour un ConfigMap, les Pods qui l'utilisent ne verront pas automatiquement les changements :
- Les variables d'environnement sont injectées au démarrage du conteneur et ne sont pas mises à jour dynamiquement. Vous devez redémarrer les Pods (par exemple, via `kubectl rollout restart deployment/...`) pour qu'ils prennent en compte les nouvelles valeurs.
- Les volumes ConfigMap sont montés et les fichiers sont créés. Par défaut, les fichiers montés via un volume ConfigMap sont mis à jour périodiquement par le Kubelet (environ toutes les minutes), mais l'application à l'intérieur du conteneur doit être capable de détecter et de recharger ces fichiers modifiés pour que la mise à jour soit effective sans redémarrage du Pod. Si vous utilisez `subPath` dans le `volumeMount`, la mise à jour dynamique ne fonctionne généralement pas.
- Taille limitée : Les ConfigMaps (comme les Secrets) sont stockés dans etcd et ne sont pas conçus pour contenir de très grandes quantités de données (la limite par objet est généralement de 1 Mo).
- Immutabilité (optionnelle) : Vous pouvez rendre un ConfigMap immuable en définissant `immutable: true` dans son manifeste. Cela empêche toute modification ultérieure et peut être utile pour garantir la stabilité de la configuration pour certains Pods.
Gérer les ConfigMaps avec `kubectl`
- Lister les ConfigMaps : `kubectl get configmaps` (ou `kubectl get cm`) [-n namespace]
- Afficher le contenu : `kubectl describe configmap [NOM_CONFIGMAP]` [-n namespace] (affiche les clés et un aperçu des valeurs)
- Afficher le contenu complet (YAML) : `kubectl get configmap [NOM_CONFIGMAP] -o yaml` [-n namespace]
- Supprimer un ConfigMap : `kubectl delete configmap [NOM_CONFIGMAP]` [-n namespace]
Conclusion : une gestion propre de la configuration
Les ConfigMaps sont un outil essentiel dans l'arsenal Kubernetes pour gérer la configuration des applications de manière découplée et organisée. En externalisant les paramètres non sensibles dans des objets ConfigMap dédiés et en les injectant dans les Pods via des variables d'environnement ou des volumes, vous rendez vos applications plus portables, plus faciles à gérer et à adapter à différents environnements.
Cependant, leur utilisation est strictement réservée aux données non confidentielles. Pour les informations sensibles, nous devons nous tourner vers leur contrepartie sécurisée : les Secrets.