E-NO
DevOps 10 min de lecture

Optimisation des performances des volumes Docker : guide pratique avec exemples concrets

calendar_today Publié : 2026-09-14
update Dernière mise à jour : 2026-09-14
analytics Efficacité SEO : 100%
Illustration du guide technique pour « Optimisation des performances des volumes Docker : guide pratique avec exemples concrets ».

Introduction

Des requêtes de base de données lentes, des téléversements de fichiers retardés ou des journaux applicatifs à la traîne pointent souvent vers une couche négligée : le stockage Docker. Les volumes sont le moyen standard de persister les données hors des conteneurs, mais une configuration par défaut fournit rarement le débit ou la latence exigés par votre charge de travail. Ce guide vous donne un processus reproductible pour passer de « quelque chose semble lent » à une amélioration mesurée et vérifiable.

Nous couvrirons comment évaluer les chemins de lecture et d'écriture, identifier quel type de montage convient à votre charge de travail, ajuster les options du système de fichiers et du pilote de stockage, et éviter les erreurs les plus courantes qui dégradent silencieusement les performances. Chaque recommandation inclut une commande concrète avec la sortie attendue et un chemin de récupération si le changement n'aide pas. L'objectif est la sécurité opérationnelle : observer avant de changer, limiter le rayon d'impact, protéger les données et vérifier les résultats avec des chiffres, pas des impressions.

Inventaire des versions et de l'environnement

Avant de régler quoi que ce soit, sachez exactement ce que vous exécutez. Le comportement des performances change entre les versions du moteur Docker, les pilotes de stockage et les systèmes de fichiers. Un réglage qui fonctionne sur ext4 avec overlay2 peut être sans effet sur XFS ou ZFS.

Exécutez cet inventaire en lecture seule et enregistrez la sortie pour votre journal des modifications :

docker version --format '{{.Server.Version}}'          # ex. 24.0.7
docker info --format 'Driver: {{.Driver}}'             # ex. Driver: overlay2
uname -r                                               # noyau hôte, ex. 5.15.0-91-generic

Si vous utilisez Docker Compose, confirmez le nom du projet et les services en cours d'exécution :

docker compose ls
# NAME                STATUS              CONFIG FILES
# myapp               running(3)          /opt/myapp/docker-compose.yml

Ensuite, identifiez quels conteneurs utilisent des volumes et où ces volumes se trouvent sur l'hôte :

docker ps --format 'table {{.Names}}\t{{.Mounts}}'
docker volume ls
# DRIVER    VOLUME NAME
# local     myapp_postgres_data

Inspectez un volume spécifique pour voir son point de montage et ses options :

docker volume inspect myapp_postgres_data
# [
#   {
#     "CreatedAt": "2024-01-15T10:23:45Z",
#     "Driver": "local",
#     "Labels": null,
#     "Mountpoint": "/var/lib/docker/volumes/myapp_postgres_data/_data",
#     "Name": "myapp_postgres_data",
#     "Options": null,
#     "Scope": "local"
#   }
# ]

Enregistrez l'état actuel avant toute modification. Un simple df -hT /var/lib/docker/volumes/myapp_postgres_data/_data montre le type de système de fichiers hôte et l'espace disponible. Si vous êtes sur le point de déplacer des données vers un autre disque, prenez d'abord un instantané (par exemple, rsync -aHAX --progress /var/lib/docker/volumes/myapp_postgres_data/_data/ /mnt/fast-nvme/myapp_postgres_data_backup/).

Un test de redémarrage de type production est la première intervention sûre : arrêtez le conteneur, recréez-le à partir de la même image et du même volume, et confirmez que l'application voit toujours ses données. Si les fichiers disparaissent après la recréation, l'application écrivait dans la couche du conteneur au lieu du volume. C'est un bug de perte de données en attente de se produire, pas un problème de réglage.

Comprendre le stockage Docker : volumes nommés vs montages bind vs tmpfs

Les problèmes de performance commencent souvent par le mauvais type de montage. Les trois principales options se comportent différemment sous charge :

Type de montageEmplacement des donnéesGéré par DockerProfil de performance typiqueIdéal pour
Volume nomméRépertoire hôte sous /var/lib/docker/volumes/ (par défaut)OuiBon pour la plupart des charges de travail ; réglage spécifique au pilote disponibleDonnées applicatives persistantes, bases de données, caches
Montage bindChemin hôte arbitraireNonLes performances dépendent entièrement du système de fichiers hôte ; souvent plus rapide que les volumes nommés par défaut s'il est placé sur un disque rapideDéveloppement, injection de configuration, rechargement à chaud
Montage tmpfsRAM hôte uniquementOuiDébit très élevé, latence quasi nulle, mais données perdues à l'arrêt du conteneurDonnées transitoires, secrets, espace de travail avec écriture intensive

Exécutez un benchmark rapide pour comparer le volume nommé et le montage bind sur votre propre hôte. Créez un conteneur temporaire qui écrit 1 Go de données aléatoires à l'aide de dd et mesure le temps :

# Test de volume nommé
docker run --rm --mount type=volume,src=test_vol,dst=/data alpine sh -c \
  "dd if=/dev/zero of=/data/testfile bs=1M count=1024 oflag=direct 2>&1 | tail -1"
# 1073741824 bytes (1.1 GB) copied, 5.024 s, 214 MB/s

# Test de montage bind (utilisez un répertoire sur le système de fichiers que vous prévoyez d'utiliser)
mkdir -p /tmp/bindtest
docker run --rm -v /tmp/bindtest:/data alpine sh -c \
  "dd if=/dev/zero of=/data/testfile bs=1M count=1024 oflag=direct 2>&1 | tail -1"
# 1073741824 bytes (1.1 GB) copied, 4.215 s, 255 MB/s

Dans cet exemple, le montage bind est environ 19 % plus rapide pour les écritures séquentielles sur le même disque. La différence peut être plus grande sur les systèmes de fichiers avec une surcharge de métadonnées importante. Si vous avez besoin de performances maximales pour une base de données à forte intensité d'écriture, un montage bind sur une partition NVMe dédiée peut surpasser le chemin du volume nommé par défaut. Mais vous perdez la gestion du cycle de vie des volumes de Docker, alors pesez soigneusement le compromis.

Un montage tmpfs donne souvent un débit 5 à 10 fois supérieur pour les petites écritures car il contourne entièrement le disque. Testez-le avec une limite de taille :

docker run --rm --tmpfs /data:rw,size=512m alpine sh -c \
  "dd if=/dev/zero of=/data/testfile bs=1M count=256 oflag=direct 2>&1 | tail -1"
# 268435456 bytes (268 MB) copied, 0.874 s, 307 MB/s

C'est plus lent que prévu ici car le CPU du conteneur est le goulot d'étranglement, pas le tmpfs. Pour les charges de travail réelles, le tmpfs n'est sûr que pour les données que vous pouvez vous permettre de perdre.

Question rapide 1 sur 2

Selon le passage de référence, pourquoi les applications intensives en écriture comme les bases de données subissent-elles une surcharge de performances lorsqu'elles utilisent des drivers de stockage ?

Le passage indique que les applications intensives en écriture subissent une surcharge de performances, en particulier si des données préexistantes se trouvent dans la couche en lecture seule, en raison du système de fichiers copy-on-write utilisé par les drivers de stockage.

Évaluation comparative des performances en lecture et écriture

Avant de modifier un réglage, établissez une base de référence. Utilisez un outil qui imite votre modèle de charge de travail réel. fio est la norme pour les benchmarks d'E/S flexibles. Exécutez-le dans un conteneur avec le volume monté, puis comparez après le réglage.

Commencez par un conteneur rapide pour le benchmarking :

docker run --rm -it -v test_vol:/data alpine sh
# Dans le conteneur, installez fio si nécessaire (alpine : apk add fio)

Écrivez un fichier de travail pour des lectures/écritures aléatoires mixtes avec une taille de bloc de 4 Ko, ce qui simule l'accès aux pages de base de données :

[global]
ioengine=libaio
direct=1
size=2G
runtime=60
time_based
rw=randrw
rwmixread=70
bs=4k
numjobs=4
group_reporting

[volume-test]
directory=/data

Exécutez-le :

fio /tmp/fio-job.ini
# ...
#   read: IOPS=18.2k, BW=71.2MiB/s (74.6MB/s)(4272MiB/60001msec)
#   write: IOPS=7812, BW=30.5MiB/s (32.0MB/s)(1831MiB/60001msec)

Enregistrez ces chiffres. Maintenant, appliquez un changement de réglage (comme déplacer le volume vers un disque plus rapide, modifier les options de montage du système de fichiers ou ajuster le pilote de stockage) et réexécutez exactement le même travail fio. Une amélioration significative devrait être d'au moins 10 à 15 % en IOPS ou en latence. Sinon, annulez le changement.

Pour les charges de travail spécifiques aux bases de données, utilisez l'outil de benchmark intégré de votre base de données. Pour PostgreSQL, pgbench donne une charge de lecture/écriture mixte réaliste :

docker run --rm -e PGPASSWORD=secret postgres:16 pgbench -h dbhost -U postgres -c 10 -j 2 -T 60 mydb
# starting vacuum...end.
# transaction type: <builtin: TPC-B (sort of)>
# scaling factor: 10
# query mode: simple
# number of clients: 10
# number of threads: 2
# duration: 60 s
# number of transactions actually processed: 48421
# latency average = 12.392 ms
# tps = 807.016643 (including connections establishing)

Cela vous indique que la base de données peut gérer environ 807 transactions par seconde avec la configuration de volume actuelle. Si vous ajoutez un cache ou déplacez vers un disque plus rapide, le tps devrait augmenter et la latence moyenne devrait baisser.

Réglage des pilotes de volumes Docker et des systèmes de fichiers

Le pilote de volume local par défaut stocke les données sous /var/lib/docker/volumes/ sur le système de fichiers de la racine de l'hôte, quel qu'il soit. Vous pouvez souvent obtenir de meilleures performances en déplaçant les volumes vers un autre système de fichiers ou point de montage avec de meilleures options.

Vérifiez votre système de fichiers actuel et les options de montage :

mount | grep ' /var/lib/docker '
# /dev/sda1 on /var/lib/docker type ext4 (rw,relatime,errors=remount-ro)

L'option relatime réduit les écritures de métadonnées par rapport à strictatime, ce qui est généralement bon. Mais pour les bases de données, vous pouvez vouloir désactiver complètement les mises à jour de temps d'accès avec noatime et activer nobarrier si le disque dispose d'un cache sauvegardé par batterie. Ce sont des options de montage sur le système de fichiers hôte. Pour les modifier, vous devez éditer /etc/fstab et remonter, ce qui nécessite un accès root et une fenêtre de maintenance.

Exemple d'entrée fstab pour un disque de volume de base de données dédié :

UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx /mnt/fastdata ext4 defaults,noatime,nodiratime,nobarrier 0 2

Ensuite, créez un montage bind depuis cet emplacement vers les conteneurs :

services:
  db:
    image: postgres:16
    volumes:
      - type: bind
        source: /mnt/fastdata/postgres
        target: /var/lib/postgresql/data

Utilisation d'un pilote de volume différent :

Pour le stockage en réseau ou les périphériques de bloc cloud, utilisez un plugin comme rexray/ebs pour AWS EBS, google/cloud pour GCE PD, ou nfs pour le stockage partagé. Ces pilotes peuvent offrir de meilleures performances ou une meilleure résilience. Installez le plugin et créez un volume avec des options de pilote :

docker plugin install rexray/ebs EBS_ACCESSKEY=xxx EBS_SECRETKEY=yyy
docker volume create --driver rexray/ebs --opt size=100 --opt volumetype=gp3 --opt iops=3000 --opt throughput=125 mydbdata

Ensuite, utilisez --mount source=mydbdata,target=/var/lib/postgresql/data lors de l'exécution du conteneur. Le volume est maintenant sur un volume EBS gp3 provisionné avec 3000 IOPS et 125 Mo/s de débit, ce qui peut être plus rapide ou plus cohérent que le disque local de l'instance.

Réglage du pilote de stockage :

Le pilote de stockage affecte plus les couches d'image du conteneur que les volumes, mais il compte toujours pour les volumes à forte intensité d'écriture si le pilote utilise un système de fichiers à copie sur écriture. Overlay2 sur ext4 ou xfs est le défaut actuel et fonctionne bien. Évitez devicemapper en mode loopback ; il est très lent. Vérifiez votre pilote et migrez si nécessaire :

docker info --format '{{.Driver}} {{.DriverStatus}}'

Si vous voyez devicemapper avec loopback, planifiez une migration vers overlay2. Cela nécessite de recréer les conteneurs et idéalement de sauvegarder d'abord les volumes.

Pièges courants et comment les éviter

De nombreux problèmes de performance proviennent d'erreurs de configuration plutôt que de limites matérielles. Voici les plus fréquents :

Piège 1 : Utiliser la couche inscriptible du conteneur au lieu d'un volume

Ce qui se passe : L'application écrit dans /var/lib/data mais aucun volume n'est monté à ce chemin. Docker stocke ces écritures dans la couche de copie sur écriture du conteneur, qui est plus lente et disparaît lorsque le conteneur est supprimé.

Pourquoi cela arrive : Les développeurs oublient de définir des volumes dans le Dockerfile ou Compose, ou ils utilisent docker run sans -v.

Comment éviter : Montez toujours un volume ou un montage bind pour toute donnée qui doit persister. Utilisez docker inspect <conteneur> et vérifiez "Mounts". Si le chemin cible est manquant, corrigez-le.

Récupération : Si vous réalisez qu'un conteneur écrivait dans sa couche, copiez les données avec docker cp avant la suppression du conteneur, puis recréez avec un volume.

Piège 2 : Utiliser un montage bind depuis un système de fichiers lent ou distant

Ce qui se passe : Vous montez /mnt/network-share/data comme montage bind. Chaque lecture/écriture passe par le réseau vers un NAS ou un autre serveur, ajoutant des dizaines de millisecondes de latence.

Pourquoi cela arrive : La commodité ou le désir de partager des données entre hôtes sans mettre en place une réplication appropriée.

Comment éviter : Utilisez un disque local avec des IOPS adéquates pour les données critiques en performance. Si vous avez besoin de stockage partagé, utilisez un plugin de volume qui prend en charge la mise en cache ou la réplication synchrone, et benchmarkez-le.

Récupération : Migrez les données vers un volume local ou un stockage réseau plus rapide, puis mettez à jour le montage du volume.

Piège 3 : Ignorer les options de montage du système de fichiers

Ce qui se passe : Le système de fichiers hôte utilise l'option de montage sync pour un ordinateur portable de développement afin d'éviter la perte de données en cas de coupure de courant soudaine. Chaque écriture attend le disque physique, réduisant le débit de 5 à 10 fois.

Pourquoi cela arrive : L'option sync est parfois définie par défaut sur les lecteurs USB externes ou par des politiques de sécurité.

Comment éviter : Vérifiez la sortie de mount. Pour les volumes de données de conteneurs, préférez async ou les options par défaut à moins d'avoir une exigence de durabilité spécifique.

Récupération : Remontez avec async (ou mieux, déplacez le volume vers un disque interne) et réexécutez les benchmarks.

Piège 4 : Exécuter trop de conteneurs sur le même disque sans limites d'E/S

Ce qui se passe : Un conteneur voisin bruyant sature la bande passante du disque ou les IOPS, provoquant des pics de latence pour tous les autres conteneurs sur le même hôte.

Pourquoi cela arrive : Docker ne définit pas de limites d'E/S par défaut. Un travail en arrière-plan comme le traitement des journaux ou un vacuum de base de données peut consommer toute l'E/S disponible.

Comment éviter : Utilisez les drapeaux --device-read-bps, --device-write-bps, --device-read-iops, et --device-write-iops dans Docker 20.10+ pour limiter l'accès au périphérique bloc.

Exemple : Limitez un processeur de journaux à 50 Mo/s d'écriture et 1000 IOPS :

docker run --device-write-bps /dev/sda:50mb --device-write-iops /dev/sda:1000 mylogprocessor

Récupération : Identifiez le coupable avec iotop sur l'hôte ou docker stats --format '{{.Name}} BlockIO: {{.BlockIO}}', puis appliquez des limites ou replanifiez la charge de travail.

Piège 5 : Négliger la sauvegarde et la restauration des volumes

Ce qui se passe : En cas d'urgence, vous devez restaurer des données mais découvrez que le volume n'a jamais été sauvegardé, ou que la sauvegarde est incohérente car elle a été prise pendant que la base de données fonctionnait.

Pourquoi cela arrive : La sauvegarde est traitée comme une réflexion après coup ; aucun calendrier régulier ou validation n'existe.

Comment éviter : Utilisez une méthode de sauvegarde cohérente. Pour les bases de données, utilisez l'outil de dump propre à la base ou un instantané de système de fichiers avec quiescence. Planifiez des sauvegardes quotidiennes ou horaires et testez régulièrement les restaurations.

Exemple de sauvegarde PostgreSQL :

docker exec -t mydb pg_dump -U postgres mydb | gzip > backup_$(date +%Y%m%d).sql.gz

Stockez la sauvegarde en dehors de l'hôte Docker. Testez périodiquement la restauration dans un volume frais.

Récupération : Gardez un runbook pour la restauration depuis la sauvegarde. Documentez les commandes exactes et vérifiez-les dans un environnement de staging.

Question rapide 2 sur 2

Selon le passage de référence, quel est un avantage des volumes Docker par rapport aux montages bind ?

Le passage indique que les volumes sont plus faciles à sauvegarder ou à migrer que les montages bind comme l'un de leurs avantages.

Réglage avancé : QoS du stockage et mise en cache

Pour les charges de travail avec des exigences de latence strictes, appliquez des limites d'E/S de bloc et des politiques de mise en cache.

Limites d'E/S de bloc

Docker prend en charge --device-read-bps, --device-write-bps, --device-read-iops, --device-write-iops pour limiter l'utilisation du disque d'un conteneur. C'est utile pour empêcher un seul conteneur d'affamer les autres. La syntaxe nécessite le chemin du périphérique sur l'hôte. Trouvez le périphérique pour votre montage de volume avec df ou lsblk.

Exemple : Limitez les écritures d'un conteneur de base de données à 200 Mo/s :

docker run -d --name db --device-write-bps /dev/nvme0n1:200mb -v mydbdata:/var/lib/postgresql/data postgres:16

Vérifiez que la limite est appliquée en consultant docker inspect db sous HostConfig.DeviceWriteBps.

Cache de pages et O_DIRECT

Les bases de données contournent souvent le cache de pages du système d'exploitation en utilisant O_DIRECT pour éviter la double mise en mémoire tampon. Certains pilotes de volume et systèmes de fichiers gèrent mal O_DIRECT. Si votre base de données le prend en charge, testez avec et sans O_DIRECT pour voir la différence. Pour PostgreSQL, le paramètre est wal_sync_method et full_page_writes ; pour MySQL, innodb_flush_method.

tmpfs pour les données temporaires à haute vitesse

Si une charge de travail nécessite un espace de travail extrêmement rapide et peut tolérer la perte de données, utilisez des montages tmpfs. Exemple :

services:
  analytics:
    image: myapp
    tmpfs:
      - /scratch:size=4g,mode=1777

Cela donne au conteneur un disque RAM de 4 Go pour les fichiers temporaires. Des opérations comme le tri de grands ensembles de données ou la compilation de code peuvent voir une accélération >10x.

Surveillance et alertes pour les performances des volumes

Le réglage n'est pas une tâche ponctuelle. Vous avez besoin d'une visibilité continue pour détecter la dégradation avant que les utilisateurs ne se plaignent.

Surveillance au niveau de l'hôte :

  • Utilisation du disque et IOPS : iostat -x 5
  • E/S par processus : iotop -oP
  • Latence du système de fichiers : fio --rw=read --bs=4k --size=1G --ioengine=libaio --direct=1 --runtime=30 --time_based --name=latencytest --output-format=json et regardez les percentiles lat_ns.

Surveillance au niveau du conteneur :

Docker stats montre les E/S de bloc par conteneur :

docker stats --no-stream --format 'table {{.Name}}\t{{.BlockIO}}'
# NAME                BLOCK I/O
# db                  42.5MB / 1.2GB
# web                 10.2MB / 0.8GB

Pour l'analyse des tendances à long terme, exportez les métriques vers Prometheus. Le démon Docker expose des métriques à /metrics si vous activez les fonctionnalités expérimentales, mais le conteneur cAdvisor est plus courant :

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 \
  gcr.io/cadvisor/cadvisor:latest

Ensuite, scrapez http://localhost:8080/metrics pour les métriques container_fs_*. Définissez des alertes pour une latence élevée (par exemple, 99e percentile > 20 ms pour le volume de base de données) et un faible débit.

Liste de contrôle opérationnelle pour les performances des volumes

Utilisez cette liste de contrôle lorsque vous démarrez une session de réglage. Chaque élément a un propriétaire et une fréquence de révision pour garder la responsabilité claire.

#TâcheCommande / VérificationPropriétaireFréquence
1Enregistrer la version de Docker, le pilote de stockage, le système de fichiersdocker version, docker info, mountIngénieur plateformeAvant chaque changement et après les mises à niveau majeures
2Identifier tous les volumes et montages pour les conteneurs critiquesdocker inspect <conteneur> --format '{{json .Mounts}}'Propriétaire de l'applicationMensuel
3Exécuter un benchmark de base (fio, pgbench, etc.)Voir la section benchmarkIngénieur performanceInitial et après tout changement
4Vérifier les pièges courants (couche inscriptible, montages bind distants, montage sync)docker inspect + mountIngénieur DevOpsMensuel
5Examiner les limites d'E/S et ajuster si nécessairedocker inspect <conteneur> --format '{{.HostConfig.DeviceWriteBps}}'Ingénieur plateformeTrimestriel ou lors d'un changement de charge de travail
6Vérifier la procédure de sauvegarde et de restaurationExécuter un test de restauration en stagingAdministrateur de base de donnéesMensuel
7Surveiller les tendances de latence et de débit du disqueiostat, alertes PrometheusSRE / Équipe de surveillanceContinu
8Documenter tout changement de réglage et son effet mesuréJournal des modifications avec chiffres avant/aprèsIngénieur plateformeÀ chaque changement

Conclusion

L'optimisation des performances des volumes Docker est une discipline, pas une correction ponctuelle. Commencez par un inventaire complet de votre environnement, choisissez le bon type de montage pour chaque charge de travail, benchmarkez avant et après chaque changement, et évitez les pièges courants qui tuent silencieusement les performances. Ensuite, mettez en place une surveillance et un processus de révision régulier pour garder les volumes rapides à mesure que vos charges de travail évoluent.

Utilisez les commandes et les exemples de ce guide comme point de départ, mais vérifiez toujours sur votre propre matériel et charge de travail. L'objectif n'est pas d'appliquer tous les réglages possibles, mais de comprendre les compromis et de faire des améliorations mesurées.

Commencez par un changement à faible risque : exécutez un benchmark sur un volume de développement, déplacez-le de l'emplacement par défaut vers un disque plus rapide, et voyez si les chiffres s'améliorent. Si c'est le cas, répliquez le changement en staging, puis en production avec un plan de rollback. Sinon, annulez et essayez un autre levier.

Un flux de travail de réglage fiable rend les échecs visibles, protège l'intégrité des données et transforme les performances du stockage de suppositions en ingénierie.

Recherches connexes

Score de qualité de l’article

Utilité pour le lecteur 100%
  • check_circle Guide prêt à lire
  • check_circle Exemples pratiques inclus
  • check_circle URL d’article optimisée pour le SEO