Gérer les configurations avec les configMaps Kubernetes
Mise à jour :
Dans un environnement Kubernetes, il est essentiel de séparer la configuration du code pour éviter de modifier l’image des conteneurs à chaque changement de paramètre. Sans cette séparation, les mises à jour deviennent complexes et peu flexibles.
Les configMaps résolvent ce problème en permettant de stocker et gérer des données de configuration indépendamment des applications. Ils offrent une solution efficace pour injecter des valeurs dynamiques dans les pods, que ce soit via des variables d’environnement ou en montant des fichiers de configuration. Grâce aux configMaps, il devient plus simple d’adapter les applications aux différents environnements (développement, test, production) sans modifier leur déploiement.
Comment créer un configMap ?
Un configMap est une ressource Kubernetes qui stocke des paires
clé-valeur utilisées pour configurer une application sans modifier son code ou
son image. Il peut être créé de plusieurs manières : en définissant les valeurs
dans un fichier YAML ou directement via kubectl
.
Créer un configMap directement avec kubectl
Il est possible de créer un configMap en ligne de commande sans passer par un fichier YAML :
kubectl create configMap demo-config \ --from-literal=MESSAGE="Hello from configMap" \ --from-literal=APP_MODE="production"
Listez les configMaps disponibles :
kubectl get configMaps
Affichez le contenu du configMap :
kubectl describe configMap demo-config
Créer un configMap avec un manifest Kubernetes
L’approche la plus courante consiste à définir un configMap dans un manifest Kubernetes au format YAML. Voici un exemple simple :
apiVersion: v1kind: configMapmetadata: name: demo-configdata: MESSAGE: "Hello from configMap" APP_MODE: "production"
Dans cet exemple, MESSAGE
et APP_MODE
sont des variables qui pourront être
utilisées par les pods.
Appliquez la configuration avec :
kubectl apply -f demo-configMap.yaml
Vérifiez que le configMap a bien été créé :
kubectl get configMap demo-config -o yaml
Créer un configMap à partir d’un fichier de configuration
Si l’application nécessite un fichier de configuration complet, Kubernetes permet de générer un configMap à partir d’un fichier existant.
Exemple avec un fichier config.properties
:
app.name=DemoAppapp.version=1.0.0log.level=info
Créez un configMap à partir de ce fichier :
kubectl create configmap app-config --from-file=config.properties
Vérifiez son contenu :
kubectl get configmap app-config -o yaml
Dans cet exemple, Kubernetes stocke le fichier en tant que clé avec son contenu en valeur.
Utilisation des configMaps dans un pod
Une fois un configMap créé, il peut être injecté dans un pod de différentes manières :
- En tant que variable d’environnement
- En tant que fichier monté dans un volume
Cela permet de configurer une application de manière flexible, sans modifier son image.
Injection des valeurs sous forme de variables d’environnement
L’une des méthodes les plus simples consiste à utiliser un configMap pour définir des variables d’environnement dans un pod.
Exemple d’un Deployment utilisant le configMap demo-config
:
apiVersion: apps/v1kind: Deploymentmetadata: name: demo-appspec: replicas: 1 selector: matchLabels: app: demo template: metadata: labels: app: demo spec: containers: - name: demo-container image: hashicorp/http-echo:0.2.3 args: - "-text=$(MESSAGE)" env: - name: MESSAGE valueFrom: configMapKeyRef: name: demo-config key: MESSAGE
Dans cet exemple :
- La variable MESSAGE est récupérée depuis le configMap
demo-config
. - Elle est utilisée comme argument de l’application grâce à
$(MESSAGE)
.
Appliquer la configuration :
kubectl apply -f demo-deployment.yaml
Utilisation d’un configMap avec envFrom
Si l’application utilise plusieurs variables d’environnement, il est plus simple d’injecter toutes les valeurs d’un configMap en une seule commande :
envFrom: - configMapRef: name: demo-config
Exemple avec un Deployment :
apiVersion: apps/v1kind: Deploymentmetadata: name: demo-appspec: replicas: 1 selector: matchLabels: app: demo template: metadata: labels: app: demo spec: containers: - name: demo-container image: hashicorp/http-echo:0.2.3 args: - "-text=$(MESSAGE)" envFrom: - configMapRef: name: demo-config
Tous les paramètres définis dans demo-config
seront accessibles sous forme de
variables d’environnement dans le conteneur.
Monter un configMap en tant que fichier dans un volume
Si l’application nécessite des fichiers de configuration, Kubernetes permet de monter un configMap sous forme de fichier dans un volume.
Exemple de configMap contenant un fichier de configuration :
apiVersion: v1kind: configMapmetadata: name: app-configdata: config.properties: | app.name=DemoApp app.version=1.0.0 log.level=info
Ensuite, ce configMap peut être monté dans un volume accessible par l’application :
apiVersion: apps/v1kind: Deploymentmetadata: name: demo-appspec: replicas: 1 selector: matchLabels: app: demo template: metadata: labels: app: demo spec: containers: - name: demo-container image: hashicorp/http-echo:0.2.3 volumeMounts: - name: config-volume mountPath: /etc/config volumes: - name: config-volume configMap: name: app-config
Dans cet exemple :
- Le configMap
app-config
est monté dans le dossier/etc/config
du conteneur. - Un fichier
/etc/config/config.properties
est disponible dans le pod avec son contenu issu du configMap.
Exemple concret
Dans cet exemple, nous allons voir comment séparer la configuration d’une
application et gérer deux versions d’un même déploiement en utilisant un
configMap, deux Deployments (blue
et green
), et un Service
permettant de basculer entre eux.
Présentation du scénario
Nous avons une application basée sur hashicorp/http-echo
, un serveur HTTP
minimaliste qui affiche un message.
- Le déploiement
blue
affiche un message fixe défini dans le manifeste Kubernetes. - Le déploiement
green
affiche un message récupéré dynamiquement depuis un configMap. - Le Service
demo-service
permet de rediriger le trafic vers l’un des deux déploiements en fonction du label sélectionné (blue
ougreen
).
Cela permet de changer dynamiquement la version active sans redéployer l’application.
Déploiement du configMap
Le configMap demo-config
stocke la configuration du déploiement green,
notamment le message affiché par le serveur.
apiVersion: v1kind: configMapmetadata: name: demo-configdata: MESSAGE: "Hello from configMap" APP_MODE: "production"
Commande pour appliquer le configMap :
kubectl apply -f demo-config.yml
Déploiement des applications (Blue & Green)
Les deux Deployments utilisent l’image hashicorp/http-echo
, qui nécessite un
argument -text
pour afficher un message.
Le blue-deployment utilise un message fixe défini directement dans le YAML :
apiVersion: apps/v1kind: Deploymentmetadata: name: blue-deploymentspec: replicas: 3 selector: matchLabels: app: demo version: blue template: metadata: labels: app: demo version: blue spec: containers: - name: demo-container image: hashicorp/http-echo:0.2.3 args: - "-text=Hello from Kubernetes" ports: - containerPort: 5678
Commande pour déployer la version Blue :
kubectl apply -f blue-deployment.yml
Le green-deployment récupère le message depuis le configMap
demo-config
au lieu d’un texte fixe.
apiVersion: apps/v1kind: Deploymentmetadata: name: green-deploymentspec: replicas: 3 selector: matchLabels: app: demo version: green template: metadata: labels: app: demo version: green spec: containers: - name: demo-container image: hashicorp/http-echo:1.0.0 args: - "-text=$(MESSAGE)" env: - name: MESSAGE valueFrom: configMapKeyRef: name: demo-config key: MESSAGE ports: - containerPort: 5678
Commande pour déployer la version Green :
kubectl apply -f green-deployment.yml
Mise en place du Service
Le Service demo-service
dirige le trafic vers l’un des deux Deployments en
fonction du label sélectionné (blue
ou green
).
apiVersion: v1kind: Servicemetadata: name: demo-servicespec: selector: app: demo version: green # Modifier ici pour basculer entre "blue" et "green" ports: - protocol: TCP port: 80 targetPort: 5678
Commande pour déployer le Service :
kubectl apply -f demo-service.yml
Tester l’application
kubectl get pods
NAME READY STATUS RESTARTS AGEblue-deployment-6c84db459d-6zmsv 1/1 Running 0 2mblue-deployment-6c84db459d-fghij 1/1 Running 0 2mgreen-deployment-7d9f8a9cba-xzylo 1/1 Running 0 2mgreen-deployment-7d9f8a9cba-wabcd 1/1 Running 0 2m
Comme le service est de type ClusterIP, il est accessible uniquement depuis un pod interne.
Créez un pod temporaire pour tester l’accès :
kubectl run test-pod --rm -it --image=curlimages/curl -- sh
Depuis le shell du pod, exécutez :
curl http://demo-service
Si version: green
est sélectionné dans le Service, vous verrez :
Hello from configMap
Si vous voulez tester la version blue, modifiez le selector du Service :
selector: app: demo version: blue
Appliquez la modification :
kubectl apply -f demo-service.yml
Puis relancez curl http://demo-service
pour voir le changement.
Comment mettre à jour un configMap ?
Lorsque vous mettez à jour un configMap, les pods existants ne sont pas automatiquement mis à jour. Pour appliquer les nouvelles valeurs, vous devez redémarrer les pods.
Modifier un configMap :
kubectl edit configMap demo-config
Redémarrer les pods pour prendre en compte les changements :
kubectl rollout restart deployment demo-app
Bonnes pratiques avec les configMaps
L’utilisation des configMaps dans Kubernetes offre une gestion flexible et modulaire de la configuration des applications. Cependant, pour garantir leur efficacité et éviter les erreurs, il est essentiel de respecter certaines bonnes pratiques.
Séparer les configMaps des Secrets
Les configMaps ne sont pas chiffrés et sont stockés en clair dans l’API Kubernetes. Ne jamais y stocker des informations sensibles comme des mots de passe, des clés API ou des certificats. Utiliser un Secret pour les données sensibles.
Nommer les configMaps de manière explicite
Un nom clair permet d’identifier rapidement l’usage du configMap.
Bon exemple :
app-confignginx-configdatabase-config
Mauvais exemple :
config1test-configrandom-settings
Organiser les configMaps par namespace
Si vous utilisez plusieurs applications ou environnements (dev, staging, prod), il est préférable d’organiser les configMaps parnamespace pour éviter les conflits.
Créer un namespace spécifique :
kubectl create namespace dev
Puis créer un configMap dans ce namespace :
kubectl create configMap app-config --from-literal=APP_MODE=development -n dev
Lister les configMaps d’un namespace :
kubectl get configMaps -n dev
Éviter les configMaps trop volumineux
Un configMap ne doit pas dépasser 1 Mo. Si vous avez de nombreux
fichiers de configuration volumineux, envisagez d’utiliser un volume
persistant (PersistentVolume
) plutôt qu’un configMap.
Surveiller les configMaps utilisés
Il est recommandé de surveiller quels configMaps sont réellement utilisés pour éviter l’accumulation de configurations obsolètes.
Lister les pods utilisant un configMap :
kubectl get pods --all-namespaces -o json | jq '.items[] | select(.spec.volumes[].configMap.name=="demo-config") | .metadata.name'
Supprimer les configMaps inutilisés :
kubectl delete configMap old-config
Conclusion
Les configMaps permettent de gérer la configuration des applications Kubernetes de manière souple et modulaire, sans modifier le code ou l’image des conteneurs. En les combinant avec de bonnes pratiques comme la séparation des environnements, la surveillance et la gestion des mises à jour, ils garantissent une infrastructure plus efficace et maintenable.
Cependant, les configMaps ne sont pas sécurisés et ne doivent pas contenir d’informations sensibles. Pour cela, Kubernetes propose les Secrets, une ressource dédiée au stockage sécurisé des mots de passe, clés API et autres données confidentielles.
Pour aller plus loin, consultez notre guide sur les Secrets Kubernetes (En cours d’écriture).