## Intro

Les montages bind Docker permettent aux conteneurs de lire et d'écrire des fichiers directement sur le système de fichiers hôte. Ils sont simples à configurer et utiles pour le développement, mais ils introduisent aussi des dépendances au niveau de l'hôte qui peuvent échouer silencieusement : répertoires manquants, dérive des permissions, épuisement du disque et suppression accidentelle. Surveiller les montages bind signifie observer à la fois le conteneur et le chemin hôte dont il dépend, puis transformer ces observations en métriques, alertes et procédures exploitables.

Ce guide s'adresse aux développeurs, consultants DevOps et équipes techniques de startups qui utilisent déjà Docker et ont besoin d'une approche pratique pour la surveillance des montages bind. Vous apprendrez à inventorier votre environnement, inspecter les montages bind, collecter des métriques pertinentes, définir des seuils d'alerte et répondre aux modes de défaillance courants tels que les erreurs de permission, les fichiers obsolètes et la pression sur le disque. Chaque section comprend des commandes concrètes, les résultats attendus et les étapes de récupération.

L'objectif est la sécurité opérationnelle : observer avant de modifier, limiter le rayon d'impact, utiliser des paramètres fictifs au lieu de secrets, vérifier le résultat et documenter comment récupérer si l'état attendu n'est pas atteint.

## Inventaire de version et d'environnement

Avant de pouvoir surveiller les montages bind, vous devez savoir exactement ce qui est en cours d'exécution. Commencez par un inventaire en lecture seule de votre environnement Docker et des montages qu'il utilise.

**Vérifier la version de Docker et le runtime**

```bash
docker version --format '{{.Server.Version}}'
```

Résultat attendu : une chaîne de version comme `24.0.7`. Le comportement des montages bind est stable dans les versions Docker récentes, mais la gestion des permissions peut différer entre les configurations rootless et rootful, notez donc le modèle de sécurité.

```bash
docker info --format '{{.SecurityOptions}}'
```

Si vous voyez `name=rootless`, vos conteneurs tournent avec des restrictions d'espace de noms utilisateur qui affectent les permissions des montages bind.

**Lister les conteneurs en cours d'exécution et leur statut**

```bash
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
```

Capturez cette sortie avant d'effectuer tout changement. Elle vous indique quels services sont actifs et quels ports ils exposent.

**Inspecter les montages d'un conteneur**

```bash
docker inspect <nom_conteneur> --format '{{ json .Mounts }}'
```

La sortie est un tableau JSON. Pour un montage bind, il ressemble à :

```json
[
  {
    "Type": "bind",
    "Source": "/host/data",
    "Destination": "/app/data",
    "Mode": "rw",
    "RW": true,
    "Propagation": "rprivate"
  }
]
```

Champs clés à surveiller :

- `Source` : le chemin hôte. Il doit exister, être accessible en lecture/écriture par l'utilisateur du conteneur et disposer d'assez d'espace libre.
- `Destination` : le chemin à l'intérieur du conteneur.
- `Mode` / `RW` : indique si le montage est en lecture-écriture ou en lecture seule. Les montages en lecture seule empêchent les écritures accidentelles mais peuvent casser l'application.
- `Propagation` : normalement `rprivate`, mais la propagation partagée (`rshared`, `rslave`) est nécessaire si le répertoire hôte est lui-même un point de montage et que les changements doivent se propager.

**Identifier les montages bind par rapport aux volumes nommés**

Un volume nommé est géré par Docker et stocké sous `/var/lib/docker/volumes/`. Un montage bind référence un chemin hôte arbitraire. Vous pouvez lister les volumes et comparer :

```bash
docker volume ls
```

Pour les projets Compose, `docker compose config` affiche la configuration de montage effective :

```bash
docker compose config --format json
```

Vérifiez la section `volumes` pour la syntaxe des montages bind (`./chemin/hote:/chemin/conteneur`) par rapport à la syntaxe des volumes nommés (`nom_volume:/chemin/conteneur`).

**Test de redémarrage pour valider la persistance**

Un moyen rapide de confirmer que les données survivent réellement sur l'hôte est un test de redémarrage. Faites-le dans un environnement de préproduction, pas en production.

1. Arrêtez le conteneur : `docker stop <nom_conteneur>`
2. Recréez-le avec le même montage : `docker start <nom_conteneur>` ou `docker compose up -d`
3. Exécutez une commande dans le conteneur et vérifiez que le fichier existe : `docker exec <nom_conteneur> ls -l /app/data/important.txt`

Si le fichier est manquant après la recréation, l'application écrivait probablement sur le système de fichiers du conteneur au lieu du montage bind.

## Chemin de configuration sûr

Une fois que vous savez ce qui tourne, vous pouvez ajuster la configuration liée à la surveillance sans risquer l'application. Le chemin sûr suit un modèle : observer, capturer l'état, faire un changement limité, vérifier et revenir en arrière si nécessaire.

**Commandes d'observation en lecture seule**

Utilisez ces commandes pour collecter des informations sans rien changer :

- `docker ps -a` - voir tous les conteneurs, y compris ceux arrêtés.
- `docker logs <conteneur> --tail 100` - lire les journaux récents de l'application pour les erreurs liées aux montages.
- `docker inspect <conteneur>` - configuration JSON complète, y compris les montages, variables d'environnement et état de santé.
- `docker stats --no-stream` - aperçu rapide du CPU, de la mémoire et des E/S. Des E/S élevées peuvent indiquer une activité sur les montages bind.

**Vérifier les permissions et la propriété du montage bind**

Les problèmes de permission sont une cause fréquente de défaillance des montages bind. Exécutez ceci sur l'hôte :

```bash
ls -ld /host/data
stat -c '%U %G %a' /host/data
```

Comparez avec l'utilisateur sous lequel le conteneur s'exécute. Par défaut, de nombreux conteneurs s'exécutent en tant que root (UID 0), mais il est recommandé d'utiliser un utilisateur non root. Si le répertoire hôte appartient à `root:root` avec le mode `755`, un utilisateur de conteneur avec UID 1000 peut ne pas pouvoir écrire.

Pour voir l'utilisateur effectif du conteneur :

```bash
docker exec <nom_conteneur> id
```

Si vous devez changer l'utilisateur, faites-le dans la configuration du conteneur, pas en modifiant globalement les permissions du répertoire hôte. Par exemple, dans Docker Compose :

```yaml
services:
  app:
    image: myapp:latest
    user: "1000:1000"
    volumes:
      - ./data:/app/data
```

Puis redémarrez le service et vérifiez l'accès en écriture :

```bash
docker compose exec app touch /app/data/test.txt && echo "write ok"
```

**Surveiller l'espace disque sur le chemin hôte**

Les montages bind consomment de l'espace disque hôte. Vérifiez l'espace libre avec :

```bash
df -h /host/data
```

La sortie inclut une colonne `Use%`. Définissez une alerte lorsque l'utilisation dépasse 80% pour le système de fichiers contenant le montage bind.

**Configurer des montages bind en lecture seule lorsque possible**

Si le conteneur n'a besoin que de lire des fichiers, montez en lecture seule pour réduire les risques :

```yaml
volumes:
  - ./config:/app/config:ro
```

Vérifiez avec `docker inspect` que `"RW": false` apparaît pour ce montage. Cela empêche la suppression ou la corruption accidentelle des données hôte.

## Vérification et diagnostic

Pour surveiller efficacement les montages bind, vous avez besoin de métriques continues et de vérifications périodiques, pas seulement d'une inspection ponctuelle. Cette section montre comment collecter des métriques pertinentes et diagnostiquer les problèmes.

**Collecter les métriques des montages bind avec cadvisor**

cadvisor est un outil de surveillance de conteneurs qui peut exporter des métriques incluant l'utilisation du système de fichiers. Exécutez-le en tant que conteneur privilégié :

```bash
docker run -d \
  --name cadvisor \
  -p 8080:8080 \
  -v /:/rootfs:ro \
  -v /var/run:/var/run:ro \
  -v /sys:/sys:ro \
  -v /var/lib/docker/:/var/lib/docker:ro \
  -v /dev/disk/:/dev/disk:ro \
  gcr.io/cadvisor/cadvisor:v0.47.0
```

Accédez à l'interface web à `http://localhost:8080` ou interrogez l'API. Par exemple, pour voir les métriques du système de fichiers d'un conteneur avec montages bind :

```bash
curl http://localhost:8080/api/v1.3/docker/<nom_conteneur> | jq '.stats[0].filesystem'
```

La sortie comprend des entrées avec `device` défini sur le périphérique hôte soutenant le montage bind et `usage` en octets. Comparez l'utilisation dans le temps pour détecter la croissance.

**Surveiller les E/S disque de l'hôte avec iostat**

Si le montage bind est sur un disque local, `iostat` montre l'activité de lecture/écriture :

```bash
iostat -x 5 /dev/sda
```

Surveillez un `%util` élevé (proche de 100%) ou des temps `await` longs, qui indiquent une saturation du disque pouvant ralentir les conteneurs lisant/écrivant sur les montages bind.

**Diagnostiquer un échec d'écriture de fichier spécifique**

Si une application signale « Permission denied » lors de l'écriture sur un montage bind, reproduisez l'écriture en tant qu'utilisateur du conteneur :

```bash
docker exec -u 1000 <nom_conteneur> sh -c 'echo test > /app/data/test.txt'
```

Si cela échoue, vérifiez les permissions et la propriété du répertoire hôte. Si cela réussit, le problème peut être spécifique à l'application (par exemple, les politiques SELinux ou AppArmor). Vérifiez le statut SELinux :

```bash
getenforce
```

S'il est en mode enforcing, vous devrez peut-être ajouter l'étiquette `:z` ou `:Z` au montage bind dans Docker :

```yaml
volumes:
  - ./data:/app/data:z
```

Puis vérifiez à nouveau l'accès.

**Vérifier la propagation du montage bind**

Si un montage bind doit voir les changements effectués dans un sous-répertoire monté sur l'hôte, la propagation compte. Par exemple, si `/host/data` est lui-même un point de montage et que vous le montez dans un conteneur, le conteneur peut ne pas voir les sous-montages à moins de définir la propagation sur `rshared`.

Inspectez la propagation actuelle :

```bash
docker inspect <nom_conteneur> --format '{{ range .Mounts }}{{ .Source }} {{ .Propagation }}{{ end }}'
```

Si c'est `rprivate` et que vous avez besoin d'une propagation partagée, recréez le conteneur avec `--mount type=bind,source=/host/data,target=/app/data,bind-propagation=rshared`. Testez en créant un sous-montage sur l'hôte et en vérifiant s'il apparaît dans le conteneur.

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

Les montages bind échouent pour des raisons prévisibles : chemins hôte manquants, changements de permission, épuisement du disque et suppression accidentelle. Cette section décrit chaque mode de défaillance, comment le détecter et comment récupérer.

**Défaillance : répertoire hôte manquant ou renommé**

Si le répertoire spécifié comme source du montage bind n'existe pas au démarrage du conteneur, Docker le crée comme un répertoire vide appartenant à root. Cela peut entraîner un comportement déroutant : le conteneur démarre, mais l'application ne voit aucune donnée.

Détection :
- Vérifiez le répertoire hôte : `ls -ld /host/data`
- Inspectez les montages du conteneur : `docker inspect <nom_conteneur>` montre le chemin source.
- Recherchez des erreurs d'application comme « directory not found » ou « empty data set ».

Récupération :
1. Arrêtez le conteneur.
2. Restaurez ou recréez le répertoire correct sur l'hôte avec la propriété et les permissions appropriées.
3. Démarrez le conteneur et vérifiez que l'application peut lire ses données : `docker logs <nom_conteneur> --tail 50` devrait montrer un démarrage réussi.

Prévention :
- Utilisez un outil de gestion de configuration pour garantir que le répertoire hôte existe avant de démarrer le conteneur.
- Dans Compose, ajoutez un healthcheck qui teste l'accès aux fichiers du montage.

**Défaillance : permission refusée à l'écriture**

Les conteneurs s'exécutent souvent en tant qu'utilisateur non root (UID 1000 ou similaire), mais le répertoire hôte peut appartenir à un autre utilisateur ou à root avec des permissions restrictives.

Détection :
- Les journaux d'application montrent `PermissionError: [Errno 13] Permission denied: '/app/data/file.txt'`.
- Les permissions du répertoire hôte : `ls -ld /host/data` montre `drwxr-xr-x root root`, ce qui ne permet pas les écritures pour UID 1000.

Récupération :
1. Changez la propriété du répertoire hôte vers l'UID/GID de l'utilisateur du conteneur, ou ajoutez une ACL si nécessaire.
   - `sudo chown -R 1000:1000 /host/data` (ajustez UID/GID pour correspondre à l'utilisateur du conteneur).
2. Redémarrez le conteneur et testez l'accès en écriture :
   - `docker exec -u 1000 <nom_conteneur> touch /app/data/test.txt`
3. Supprimez le fichier de test après vérification.

Prévention :
- Définissez un utilisateur cohérent dans le Dockerfile ou le fichier Compose.
- Documentez les permissions hôte requises dans le README du projet.

**Défaillance : espace disque épuisé**

Les montages bind vivent sur les systèmes de fichiers hôte, qui peuvent se remplir en raison de journaux, de téléchargements volumineux ou d'une croissance non contrôlée des données.

Détection :
- `df -h /host/data` montre `Use%` à 100%.
- Les journaux système peuvent montrer `No space left on device`.
- Les applications peuvent échouer à écrire ou planter.

Récupération :
1. Identifiez les gros fichiers sur le montage bind : `du -sh /host/data/* | sort -rh | head -n 10`
2. Supprimez ou archivez les fichiers inutiles après avoir confirmé qu'ils ne sont pas nécessaires.
3. Étendez le système de fichiers ou déplacez le montage bind vers un disque plus grand si nécessaire.
4. Redémarrez les conteneurs affectés et vérifiez que les écritures réussissent.

Prévention :
- Configurez des alertes d'utilisation du disque à 80% de capacité.
- Utilisez la rotation des journaux dans les conteneurs pour que les journaux ne consomment pas l'espace hôte.
- Envisagez de déplacer les données volumineuses vers un montage dédié ou un stockage objet.

**Défaillance : suppression accidentelle de fichiers hôte**

Parce que les montages bind sont simplement des répertoires hôte, un utilisateur ou un autre processus peut supprimer des fichiers en dehors de Docker, et le conteneur les verra disparaître immédiatement.

Détection :
- Les journaux d'application montrent des erreurs « file not found ».
- Le répertoire hôte a des fichiers ou répertoires manquants.

Récupération :
- Restaurez à partir des sauvegardes. S'il n'y a pas de sauvegarde, vous pourrez peut-être récupérer les fichiers supprimés à l'aide d'outils de système de fichiers uniquement si le système de fichiers le permet (par exemple, extundelete sur ext4, mais le succès n'est pas garanti).
- Pour prévenir, utilisez des montages bind en lecture seule lorsque possible et limitez l'accès hôte au répertoire.

**Défaillance : SELinux ou AppArmor bloquant l'accès**

Sur les systèmes avec contrôle d'accès obligatoire activé, les conteneurs peuvent se voir refuser l'accès aux montages bind même lorsque les permissions semblent correctes.

Détection :
- Journaux d'audit : `ausearch -m avc -ts recent` sur RHEL/CentOS montre des entrées `denied` pour le conteneur essayant d'accéder au montage.
- Le conteneur peut ne pas démarrer ou montrer des erreurs de permission.

Récupération :
- Pour SELinux, ajoutez l'étiquette `:z` ou `:Z` au montage bind dans la commande run ou le fichier Compose :
  - `docker run -v /host/data:/app/data:z ...`
  - Ou `-v /host/data:/app/data:Z` si le montage est exclusif à ce conteneur.
- Pour AppArmor, vérifiez le profil appliqué et ajustez si nécessaire, ou utilisez un profil non confiné uniquement pour les tests.
- Redémarrez le conteneur et vérifiez l'accès.

**Défaillance : épuisement des inodes**

Même si l'espace disque est disponible, un système de fichiers peut manquer d'inodes si l'application crée de nombreux petits fichiers.

Détection :
- `df -i /host/data` montre `IFree` proche de 0.
- La création d'un nouveau fichier échoue avec « No space left on device » même si `df -h` montre de l'espace disponible.

Récupération :
- Trouvez les répertoires avec de nombreux fichiers : `find /host/data -type f | wc -l`, puis inspectez les sous-répertoires.
- Supprimez les petits fichiers inutiles ou déplacez le répertoire vers un système de fichiers avec plus d'inodes.
- Prévenez en définissant des limites sur la création de fichiers dans l'application.

## Liste de contrôle opérationnelle

Utilisez cette liste de contrôle pour garder les montages bind sains. Exécutez-la manuellement ou automatisez-la avec cron ou CI.

**Vérifications quotidiennes**

- [ ] Vérifiez que tous les conteneurs avec montages bind sont en cours d'exécution : `docker ps -a --filter "status=exited"` ne doit pas lister les conteneurs censés être en cours d'exécution.
- [ ] Vérifiez l'espace disque sur les systèmes de fichiers des montages bind : `df -h /host/data` pour chaque chemin hôte.
- [ ] Vérifiez les journaux d'application pour les erreurs liées aux montages : `docker logs <nom_conteneur> --since 24h | grep -i "permission\|no space\|not found"`

**Vérifications hebdomadaires**

- [ ] Confirmez que les sources des montages bind existent et que les permissions sont correctes : `ls -ld /host/data` et `stat -c '%U %G %a' /host/data`.
- [ ] Vérifiez les montages bind orphelins (montages dont les répertoires n'existent plus) : comparez la liste des montages de `docker inspect` avec les répertoires hôte réels.
- [ ] Examinez les métriques d'E/S disque de cadvisor ou iostat pour une activité inhabituelle.

**Tâches proactives mensuelles**

- [ ] Testez la restauration à partir de la sauvegarde des données critiques des montages bind.
- [ ] Effectuez un test en lecture seule : montez une copie des données en lecture seule et confirmez que l'application fonctionne toujours.
- [ ] Passez en revue les besoins de propagation des montages bind : si les répertoires hôte sont eux-mêmes des montages, assurez-vous que la propagation du conteneur est correctement définie.

**Avant tout changement de conteneur**

- [ ] Enregistrez l'état actuel : `docker ps -a`, `docker inspect --format '{{ json .Mounts }}' <conteneur>`, `df -h`, `du -sh /host/data`.
- [ ] Effectuez un changement limité à la fois.
- [ ] Vérifiez le changement avec une commande spécifique et un résultat attendu.
- [ ] Ayez un plan de retour en arrière : conservez l'ancienne configuration du conteneur ou la version du fichier Compose.

**Référence rapide de réponse aux incidents**

- [ ] Le conteneur ne peut pas écrire : vérifiez les permissions, SELinux/AppArmor, l'espace disque, le drapeau lecture seule.
- [ ] Données manquantes : vérifiez si le répertoire hôte a été renommé ou supprimé, restaurez à partir de la sauvegarde.
- [ ] Dégradation des performances : vérifiez les E/S disque, le nombre de petits fichiers et l'utilisation des inodes.

## Conclusion

Surveiller les montages bind Docker consiste à comprendre la relation hôte-conteneur et à la transformer en vérifications et alertes de routine. En inventoriant votre environnement, en collectant des métriques pertinentes et en vous préparant aux défaillances courantes, vous réduisez les temps d'arrêt et les pertes de données.

Commencez par une vérification à faible risque de ce guide : exécutez `docker inspect` sur un conteneur utilisant un montage bind, vérifiez les permissions du répertoire hôte et effectuez un test de redémarrage pour confirmer la persistance. Documentez les résultats et configurez une alerte de base sur l'espace disque. Ensuite, étendez pour inclure les métriques cadvisor et des vérifications de permissions automatisées.

Rappelez-vous : les montages bind sont puissants mais fragiles. Observez avant de modifier, limitez les changements à un seul élément, vérifiez toujours le résultat et conservez des sauvegardes des données hôte critiques.