## Introduction

Les ConfigMaps Kubernetes permettent de séparer la configuration du code applicatif. Un laboratoire local vous offre un espace sûr pour apprendre le comportement des ConfigMaps, tester des modifications et déboguer des problèmes sans toucher à un cluster partagé. Ce guide présente une configuration locale complète avec Minikube ou kind, puis montre des exemples pratiques pour monter des ConfigMaps en tant que variables d'environnement, fichiers et arguments de ligne de commande. Vous apprendrez également à vérifier les changements, observer le comportement des pods et vous remettre des erreurs courantes.

L'objectif est la sécurité opérationnelle : observez avant de modifier, limitez le rayon d'action, utilisez des valeurs fictives plutôt que des secrets, vérifiez le résultat et documentez la procédure de récupération si l'état attendu n'est pas atteint.

## Prérequis

Avant de commencer, assurez-vous de disposer de :

- Un cluster Kubernetes local en cours d'exécution (Minikube, kind ou Docker Desktop avec Kubernetes).
- `kubectl` installé et configuré pour pointer vers votre cluster local.
- Une familiarité de base avec `kubectl get`, `kubectl describe` et l'application de fichiers YAML.

Vérifiez que votre cluster est prêt :

```bash
kubectl cluster-info
kubectl get nodes
```

La sortie attendue montre un nœud à l'état `Ready` :

```
NAME       STATUS   ROLES           AGE   VERSION
minikube   Ready    control-plane   10m   v1.28.0
```

## Inventaire de la version et de l'environnement

Connaissez toujours votre environnement avant d'effectuer des modifications. Vérifiez la version du serveur Kubernetes et du client, car des fonctionnalités de ConfigMap comme `immutable` nécessitent Kubernetes 1.19 ou plus récent.

```bash
kubectl version --short
```

Exemple de sortie :

```
Client Version: v1.28.0
Kustomize Version: v5.0.1
Server Version: v1.28.0
```

Listez les espaces de noms et confirmez que vous travaillez dans celui prévu (par défaut pour ce laboratoire) :

```bash
kubectl get namespaces
kubectl config get-contexts
```

Le contexte actuel indique le cluster et l'espace de noms. Si vous n'êtes pas dans le bon contexte, changez avec `kubectl config use-context`.

Pour les ConfigMaps, vérifiez que la ressource API existe :

```bash
kubectl api-resources | grep configmap
```

Sortie attendue :

```
configmaps                cm           v1                                     true         ConfigMap
```

Enregistrez ces détails avant toute modification. Ils vous aideront si vous demandez de l'aide ou devez revenir en arrière.

## Création de votre première ConfigMap

Créez une ConfigMap simple à partir d'un fichier YAML. Enregistrez le texte suivant sous le nom `app-config.yaml` :

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
  namespace: default
data:
  APP_COLOR: "blue"
  APP_MODE: "development"
  app.properties: |
    key1=value1
    key2=value2
  nginx.conf: |
    server {
      listen 80;
      server_name localhost;
      location / {
        root /usr/share/nginx/html;
      }
    }
```

Appliquez-la :

```bash
kubectl apply -f app-config.yaml
```

Vérifiez que la ConfigMap a été créée :

```bash
kubectl get configmap app-config -o yaml
```

Ou affichez une version résumée :

```bash
kubectl describe configmap app-config
```

La sortie attendue montre `Name : app-config`, `Namespace : default` et les entrées de données.

Vous pouvez également créer une ConfigMap à partir de littéraux en ligne de commande :

```bash
kubectl create configmap game-config --from-literal=GAME_MODE=classic --from-literal=PLAYER_COUNT=4
```

Vérifiez avec :

```bash
kubectl get configmap game-config -o yaml
```

## Utilisation des ConfigMaps dans un pod

Montez maintenant la ConfigMap dans un pod en tant que variables d'environnement et fichiers. Enregistrez le texte suivant sous `pod-using-configmap.yaml` :

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: configmap-demo-pod
spec:
  containers:
  - name: demo-container
    image: busybox:1.36
    command: ["/bin/sh", "-c", "echo APP_COLOR=$APP_COLOR; echo APP_MODE=$APP_MODE; cat /etc/config/app.properties; sleep 3600"]
    env:
    - name: APP_COLOR
      valueFrom:
        configMapKeyRef:
          name: app-config
          key: APP_COLOR
    - name: APP_MODE
      valueFrom:
        configMapKeyRef:
          name: app-config
          key: APP_MODE
    volumeMounts:
    - name: config-volume
      mountPath: /etc/config
  volumes:
  - name: config-volume
    configMap:
      name: app-config
```

Appliquez et attendez que le pod soit en cours d'exécution :

```bash
kubectl apply -f pod-using-configmap.yaml
kubectl wait --for=condition=Ready pod/configmap-demo-pod --timeout=60s
```

Consultez les journaux du pod pour voir les valeurs :

```bash
kubectl logs configmap-demo-pod
```

Sortie attendue :

```
APP_COLOR=blue
APP_MODE=development
key1=value1
key2=value2
```

Pour inspecter les fichiers montés dans le conteneur :

```bash
kubectl exec configmap-demo-pod -- ls /etc/config
kubectl exec configmap-demo-pod -- cat /etc/config/app.properties
```

## Passage des valeurs de ConfigMap en arguments de ligne de commande

Vous pouvez utiliser des clés de ConfigMap dans les arguments de la commande du conteneur. Modifiez la spécification du pod pour inclure des arguments référençant la ConfigMap. Enregistrez sous `pod-with-args.yaml` :

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: configmap-arg-pod
spec:
  containers:
  - name: arg-container
    image: busybox:1.36
    command: ["/bin/sh", "-c"]
    args:
    - "echo Démarrage en mode $GAME_MODE avec $PLAYER_COUNT joueurs; sleep 3600"
    env:
    - name: GAME_MODE
      valueFrom:
        configMapKeyRef:
          name: game-config
          key: GAME_MODE
    - name: PLAYER_COUNT
      valueFrom:
        configMapKeyRef:
          name: game-config
          key: PLAYER_COUNT
```

Appliquez et consultez les journaux :

```bash
kubectl apply -f pod-with-args.yaml
kubectl logs configmap-arg-pod
```

Sortie attendue :

```
Démarrage en mode classic avec 4 joueurs
```

## Mise à jour des ConfigMaps et délai de propagation

Les ConfigMaps sont mises à jour indépendamment des pods. Lorsque vous mettez à jour une ConfigMap, les pods qui l'utilisent comme variables d'environnement ne voient pas automatiquement la nouvelle valeur ; les pods qui l'utilisent comme volume monté peuvent voir les changements après un délai (généralement jusqu'à une minute, selon la période de synchronisation du kubelet).

Mettez à jour `app-config` pour changer la couleur :

```bash
kubectl patch configmap app-config --type merge -p '{"data":{"APP_COLOR":"green"}}'
```

Vérifiez la variable d'environnement du pod en cours (elle reste bleue) :

```bash
kubectl exec configmap-demo-pod -- sh -c 'echo $APP_COLOR'
```

Sortie : `blue`

Vérifiez le fichier monté (peut montrer l'ancienne ou la nouvelle valeur selon le moment) :

```bash
kubectl exec configmap-demo-pod -- cat /etc/config/app.properties
```

Pour forcer un pod à prendre en compte les variables d'environnement mises à jour, vous devez redémarrer le pod :

```bash
kubectl delete pod configmap-demo-pod
kubectl apply -f pod-using-configmap.yaml
kubectl wait --for=condition=Ready pod/configmap-demo-pod --timeout=60s
kubectl logs configmap-demo-pod
```

Maintenant, la sortie montre `APP_COLOR=green`.

## Utilisation de ConfigMaps immuables

Si votre configuration ne change jamais, marquez la ConfigMap comme immuable pour la protéger et améliorer les performances. Pour créer une ConfigMap immuable :

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: immutable-config
immutable: true
data:
  STATIC_SETTING: "ne change jamais"
```

Appliquez et essayez de la modifier :

```bash
kubectl apply -f immutable-config.yaml
kubectl patch configmap immutable-config --type merge -p '{"data":{"STATIC_SETTING":"nouvelle-valeur"}}'
```

Erreur attendue :

```
configmap « immutable-config » est immuable
```

Cela est utile pour éviter les modifications accidentelles.

## Vérification des montages de ConfigMap et des variables d'environnement

Vérifiez toujours que votre pod voit la configuration attendue. Utilisez `kubectl exec` pour inspecter depuis l'intérieur du conteneur.

Vérifiez les variables d'environnement :

```bash
kubectl exec configmap-demo-pod -- env | grep APP_
```

Vérifiez le contenu et les permissions des fichiers montés :

```bash
kubectl exec configmap-demo-pod -- ls -l /etc/config
```

La sortie attendue montre les fichiers avec les permissions par défaut (généralement 0644). Vous pouvez modifier les permissions en utilisant `defaultMode` dans la spécification du volume :

```yaml
volumes:
- name: config-volume
  configMap:
    name: app-config
    defaultMode: 0440
```

Vérifiez également que seules les clés attendues sont présentes. Si vous montez toute la ConfigMap en volume, toutes les clés deviennent des fichiers. Pour ne monter que des clés spécifiques, utilisez `items` :

```yaml
volumes:
- name: config-volume
  configMap:
    name: app-config
    items:
    - key: app.properties
      path: my-app.properties
```

Maintenant `/etc/config` ne contient que `my-app.properties`.

## Débogage des problèmes courants

### Pod bloqué en CrashLoopBackOff

Si votre pod plante, inspectez les journaux et les événements :

```bash
kubectl logs configmap-demo-pod --previous
kubectl describe pod configmap-demo-pod
```

Causes fréquentes :

- La clé de ConfigMap référencée dans `env` n'existe pas. La création du pod échoue avec `Invalid value : « ... » : key not found in ConfigMap`.
- Le chemin du fichier monté est incorrect ou entre en conflit avec un fichier existant.
- Erreur de syntaxe de la commande due à une variable d'environnement manquante.

Corrigez en rectifiant la ConfigMap ou la spécification du pod, puis supprimez le pod et réappliquez.

### ConfigMap introuvable

Si `kubectl apply` renvoie une erreur indiquant que la ConfigMap n'existe pas, assurez-vous de l'avoir créée dans le même espace de noms que le pod. Les ConfigMaps sont délimitées par espace de noms. Vérifiez avec `kubectl get configmap -n <namespace>`.

### Le pod ne peut pas accéder aux fichiers montés

Vérifiez le chemin `volumeMount` et assurez-vous que le conteneur ne s'exécute pas en tant qu'utilisateur non root sans permissions. Utilisez `securityContext` pour ajuster si nécessaire.

## Modes de défaillance et récupération

Les ConfigMaps sont simples mais peuvent causer des problèmes subtils si elles ne sont pas gérées avec soin.

**Défaillance 1 : référence de clé manquante.** Si un pod référence une clé de ConfigMap qui n'existe pas, le pod ne démarre pas avec un événement `CreateContainerConfigError`. Récupérez en ajoutant la clé à la ConfigMap ou en corrigeant la référence, puis supprimez le pod pour le redémarrer.

**Défaillance 2 : ConfigMap trop volumineuse.** Les ConfigMaps sont limitées à 1 Mio (à partir de Kubernetes 1.28). Dépasser cette limite provoque une erreur lors de la création de la ConfigMap. Divisez les grandes configurations en plusieurs ConfigMaps ou utilisez un volume provenant d'un secret ou d'un stockage externe.

**Défaillance 3 : suppression accidentelle.** Si une ConfigMap est supprimée alors que des pods l'utilisent, les pods existants continuent de fonctionner, mais les nouveaux pods ou conteneurs redémarrés échouent à monter la ConfigMap. Récupérez en restaurant la ConfigMap depuis votre contrôle de version ou sauvegarde, puis supprimez les pods affectés pour forcer leur recréation.

**Défaillance 4 : modification d'une ConfigMap immuable.** Comme montré précédemment, les ConfigMaps immuables ne peuvent pas être modifiées. Si vous devez modifier, créez une nouvelle ConfigMap et mettez à jour les références des pods.

## Liste de contrôle des opérations

Utilisez cette liste avant et après avoir apporté des modifications de ConfigMap dans un environnement de type production :

- [ ] Confirmer la version du cluster et l'espace de noms : `kubectl version --short && kubectl config view --minify`
- [ ] Lister les ConfigMaps existantes : `kubectl get configmaps -n <namespace>`
- [ ] Sauvegarder la ConfigMap actuelle : `kubectl get configmap <name> -o yaml > configmap-backup.yaml`
- [ ] Appliquer les modifications : `kubectl apply -f <file>`
- [ ] Vérifier le contenu de la ConfigMap : `kubectl describe configmap <name>`
- [ ] Redémarrer les pods dépendants : `kubectl rollout restart deployment/<deployment-name>` si vous utilisez des déploiements
- [ ] Vérifier les journaux des pods pour les erreurs de démarrage : `kubectl logs <pod-name>`
- [ ] Confirmer les variables d'environnement : `kubectl exec <pod-name> -- env | grep <key>`
- [ ] Confirmer les fichiers montés : `kubectl exec <pod-name> -- cat /path/to/file`
- [ ] Surveiller jusqu'à 5 minutes pour s'assurer qu'aucun problème différé ne survient

## Conclusion

Un laboratoire local de ConfigMaps Kubernetes vous donne la confiance nécessaire pour gérer les changements de configuration en toute sécurité. En suivant les exemples et les étapes de vérification de ce guide, vous pouvez isoler les problèmes, comprendre le comportement de propagation et récupérer rapidement des défaillances. Entraînez-vous avec différents montages de volume, références de variables d'environnement et ConfigMaps immuables pour approfondir vos connaissances opérationnelles.

Comme prochaine étape, choisissez une vérification à faible risque pour votre propre application, enregistrez l'état actuel, appliquez un changement de ConfigMap et observez comment vos pods se comportent. Documentez votre propre liste de contrôle pour les incidents futurs. Avec des ConfigMaps gérées correctement, vos déploiements deviennent plus faciles à maintenir et moins sujets aux erreurs.