⚠️ Traduction non officielle - Cette documentation est une traduction communautaire non officielle de Docker.

Pilote de stockage Device Mapper (déprécié)

Déprécié

Le pilote Device Mapper a été déprécié, et est supprimé dans Docker Engine v25.0. Si vous utilisez Device Mapper, vous devez migrer vers un pilote de stockage supporté avant de mettre à niveau vers Docker Engine v25.0. Lisez la page Pilotes de stockage Docker pour les pilotes de stockage supportés.

Device Mapper est un framework basé sur le noyau qui sous-tend de nombreuses technologies avancées de gestion de volumes sur Linux. Le pilote de stockage devicemapper de Docker exploite les capacités de provisioning fin et de snapshot de ce framework pour la gestion d'images et de conteneurs. Cet article fait référence au pilote de stockage Device Mapper comme devicemapper, et au framework du noyau comme Device Mapper.

Pour les systèmes où il est supporté, le support devicemapper est inclus dans le noyau Linux. Cependant, une configuration spécifique est requise pour l'utiliser avec Docker.

Le pilote devicemapper utilise des périphériques bloc dédiés à Docker et opère au niveau bloc, plutôt qu'au niveau fichier. Ces périphériques peuvent être étendus en ajoutant du stockage physique à votre hôte Docker, et ils performent mieux que l'utilisation d'un système de fichiers au niveau du système d'exploitation (OS).

Prérequis

  • devicemapper est supporté sur Docker Engine - Community fonctionnant sur CentOS, Fedora, SLES 15, Ubuntu, Debian, ou RHEL.
  • devicemapper nécessite l'installation des paquets lvm2 et device-mapper-persistent-data.
  • Changer le pilote de stockage rend inaccessibles tous les conteneurs que vous avez déjà créés sur le système local. Utilisez docker save pour sauvegarder les conteneurs, et poussez les images existantes vers Docker Hub ou un registre privé, afin de ne pas avoir besoin de les recréer plus tard.

Configurer Docker avec le pilote de stockage devicemapper

Avant de suivre ces procédures, vous devez d'abord satisfaire tous les prérequis.

Configurer le mode loop-lvm pour les tests

Cette configuration n'est appropriée que pour les tests. Le mode loop-lvm fait usage d'un mécanisme 'loopback' qui permet aux fichiers sur le disque local d'être lus et écrits comme s'ils étaient un disque physique réel ou un périphérique bloc. Cependant, l'ajout du mécanisme loopback, et l'interaction avec la couche de système de fichiers de l'OS, signifie que les opérations IO peuvent être lentes et gourmandes en ressources. L'utilisation de périphériques loopback peut aussi introduire des conditions de course. Cependant, configurer le mode loop-lvm peut aider à identifier des problèmes de base (tels que des paquets espace utilisateur manquants, pilotes de noyau, etc.) avant de tenter la configuration plus complexe requise pour activer le mode direct-lvm. Le mode loop-lvm ne devrait donc être utilisé que pour effectuer des tests rudimentaires avant de configurer direct-lvm.

Pour les systèmes de production, voir Configurer le mode direct-lvm pour la production.

  1. Arrêtez Docker.

    $ sudo systemctl stop docker
    
  2. Éditez /etc/docker/daemon.json. S'il n'existe pas encore, créez-le. En supposant que le fichier était vide, ajoutez le contenu suivant.

    {
      "storage-driver": "devicemapper"
    }

    Voir toutes les options de stockage pour chaque pilote de stockage dans la documentation de référence du démon

    Docker ne démarre pas si le fichier daemon.json contient du JSON mal formé.

  3. Démarrez Docker.

    $ sudo systemctl start docker
    
  4. Vérifiez que le démon utilise le pilote de stockage devicemapper. Utilisez la commande docker info et cherchez Storage Driver.

    $ docker info
    
      Containers: 0
        Running: 0
        Paused: 0
        Stopped: 0
      Images: 0
      Server Version: 17.03.1-ce
      Storage Driver: devicemapper
      Pool Name: docker-202:1-8413957-pool
      Pool Blocksize: 65.54 kB
      Base Device Size: 10.74 GB
      Backing Filesystem: xfs
      Data file: /dev/loop0
      Metadata file: /dev/loop1
      Data Space Used: 11.8 MB
      Data Space Total: 107.4 GB
      Data Space Available: 7.44 GB
      Metadata Space Used: 581.6 KB
      Metadata Space Total: 2.147 GB
      Metadata Space Available: 2.147 GB
      Thin Pool Minimum Free Space: 10.74 GB
      Udev Sync Supported: true
      Deferred Removal Enabled: false
      Deferred Deletion Enabled: false
      Deferred Deleted Device Count: 0
      Data loop file: /var/lib/docker/devicemapper/data
      Metadata loop file: /var/lib/docker/devicemapper/metadata
      Library Version: 1.02.135-RHEL7 (2016-11-16)
    <...>
    

Cet hôte fonctionne en mode loop-lvm, qui n'est pas supporté sur les systèmes de production. Ceci est indiqué par le fait que le Data loop file et un Metadata loop file sont sur des fichiers sous /var/lib/docker/devicemapper. Ce sont des fichiers clairsemés montés en loopback. Pour les systèmes de production, voir Configurer le mode direct-lvm pour la production.

Configurer le mode direct-lvm pour la production

Les hôtes de production utilisant le pilote de stockage devicemapper doivent utiliser le mode direct-lvm. Ce mode utilise des périphériques bloc pour créer le thin pool. C'est plus rapide que d'utiliser des périphériques loopback, utilise les ressources système plus efficacement, et les périphériques bloc peuvent grandir selon les besoins. Cependant, plus de configuration est requise qu'en mode loop-lvm.

Après avoir satisfait les prérequis, suivez les étapes ci-dessous pour configurer Docker à utiliser le pilote de stockage devicemapper en mode direct-lvm.

Warning

Changer le pilote de stockage rend inaccessibles tous les conteneurs que vous avez déjà créés sur le système local. Utilisez docker save pour sauvegarder les conteneurs, et poussez les images existantes vers Docker Hub ou un registre privé, afin de ne pas avoir besoin de les recréer plus tard.

Permettre à Docker de configurer le mode direct-lvm

Docker peut gérer le périphérique bloc pour vous, simplifiant la configuration du mode direct-lvm. Ceci n'est approprié que pour de nouvelles installations Docker. Vous ne pouvez utiliser qu'un seul périphérique bloc. Si vous devez utiliser plusieurs périphériques bloc, configurez le mode direct-lvm manuellement à la place. Les nouvelles options de configuration suivantes sont disponibles :

Option Description Requis ? Défaut Exemple
dm.directlvm_device Le chemin vers le périphérique bloc à configurer pour direct-lvm. Oui dm.directlvm_device="/dev/xvdf"
dm.thinp_percent Le pourcentage d'espace à utiliser pour le stockage depuis le périphérique bloc passé. Non 95 dm.thinp_percent=95
dm.thinp_metapercent Le pourcentage d'espace à utiliser pour le stockage de métadonnées depuis le périphérique bloc passé. Non 1 dm.thinp_metapercent=1
dm.thinp_autoextend_threshold Le seuil pour quand lvm devrait automatiquement étendre le thin pool en pourcentage de l'espace de stockage total. Non 80 dm.thinp_autoextend_threshold=80
dm.thinp_autoextend_percent Le pourcentage d'augmentation du thin pool quand une auto-extension est déclenchée. Non 20 dm.thinp_autoextend_percent=20
dm.directlvm_device_force Formater ou non le périphérique bloc même si un système de fichiers existe déjà dessus. Si défini à false et qu'un système de fichiers est présent, une erreur est journalisée et le système de fichiers est laissé intact. Non false dm.directlvm_device_force=true

Éditez le fichier daemon.json et définissez les options appropriées, puis redémarrez Docker pour que les changements prennent effet. La configuration daemon.json suivante définit toutes les options du tableau ci-dessus.

{
  "storage-driver": "devicemapper",
  "storage-opts": [
    "dm.directlvm_device=/dev/xdf",
    "dm.thinp_percent=95",
    "dm.thinp_metapercent=1",
    "dm.thinp_autoextend_threshold=80",
    "dm.thinp_autoextend_percent=20",
    "dm.directlvm_device_force=false"
  ]
}

Voir toutes les options de stockage pour chaque pilote de stockage dans la documentation de référence du démon

Redémarrez Docker pour que les changements prennent effet. Docker invoque les commandes pour configurer le périphérique bloc pour vous.

Warning

Changer ces valeurs après que Docker ait préparé le périphérique bloc pour vous n'est pas supporté et cause une erreur.

Vous devez encore effectuer des tâches de maintenance périodiques.

Configurer le mode direct-lvm manuellement

La procédure ci-dessous crée un volume logique configuré comme un thin pool à utiliser comme support pour le pool de stockage. Elle suppose que vous avez un périphérique bloc de rechange à /dev/xvdf avec assez d'espace libre pour compléter la tâche. L'identifiant du périphérique et les tailles de volumes peuvent être différents dans votre environnement et vous devriez substituer vos propres valeurs tout au long de la procédure. La procédure assume aussi que le démon Docker est dans l'état arrêté.

  1. Identifiez le périphérique bloc que vous voulez utiliser. Le périphérique est situé sous /dev/ (tel que /dev/xvdf) et a besoin d'assez d'espace libre pour stocker les images et couches de conteneurs pour les charges de travail que l'hôte exécute. Un disque à état solide est idéal.

  2. Arrêtez Docker.

    $ sudo systemctl stop docker
    
  3. Installez les paquets suivants :

    • RHEL / CentOS : device-mapper-persistent-data, lvm2, et toutes les dépendances

    • Ubuntu / Debian / SLES 15 : thin-provisioning-tools, lvm2, et toutes les dépendances

  4. Créez un volume physique sur votre périphérique bloc depuis l'étape 1, en utilisant la commande pvcreate. Substituez votre nom de périphérique pour /dev/xvdf.

    Warning

    Les prochaines étapes sont destructives, alors assurez-vous que vous avez spécifié le bon périphérique.

    $ sudo pvcreate /dev/xvdf
    
    Physical volume "/dev/xvdf" successfully created.
    
  5. Créez un groupe de volumes docker sur le même périphérique, en utilisant la commande vgcreate.

    $ sudo vgcreate docker /dev/xvdf
    
    Volume group "docker" successfully created
    
  6. Créez deux volumes logiques nommés thinpool et thinpoolmeta en utilisant la commande lvcreate. Le dernier paramètre spécifie la quantité d'espace libre à permettre pour l'expansion automatique des données ou métadonnées si l'espace devient bas, comme mesure temporaire. Ce sont les valeurs recommandées.

    $ sudo lvcreate --wipesignatures y -n thinpool docker -l 95%VG
    
    Logical volume "thinpool" created.
    
    $ sudo lvcreate --wipesignatures y -n thinpoolmeta docker -l 1%VG
    
    Logical volume "thinpoolmeta" created.
    
  7. Convertissez les volumes en un thin pool et un emplacement de stockage pour les métadonnées du thin pool, en utilisant la commande lvconvert.

    $ sudo lvconvert -y \
    --zero n \
    -c 512K \
    --thinpool docker/thinpool \
    --poolmetadata docker/thinpoolmeta
    
    WARNING: Converting logical volume docker/thinpool and docker/thinpoolmeta to
    thin pool's data and metadata volumes with metadata wiping.
    THIS WILL DESTROY CONTENT OF LOGICAL VOLUME (filesystem etc.)
    Converted docker/thinpool to thin pool.
    
  8. Configurez l'auto-extension des thin pools via un profil lvm.

    $ sudo vi /etc/lvm/profile/docker-thinpool.profile
    
  9. Spécifiez les valeurs thin_pool_autoextend_threshold et thin_pool_autoextend_percent.

    thin_pool_autoextend_threshold est le pourcentage d'espace utilisé avant que lvm tente d'auto-étendre l'espace disponible (100 = désactivé, non recommandé).

    thin_pool_autoextend_percent est la quantité d'espace à ajouter au périphérique lors de l'extension automatique (0 = désactivé).

    L'exemple ci-dessous ajoute 20% de capacité supplémentaire quand l'utilisation du disque atteint 80%.

    activation {
      thin_pool_autoextend_threshold=80
      thin_pool_autoextend_percent=20
    }

    Sauvegardez le fichier.

  10. Appliquez le profil LVM, en utilisant la commande lvchange.

    $ sudo lvchange --metadataprofile docker-thinpool docker/thinpool
    
    Logical volume docker/thinpool changed.
    
  11. Assurez-vous que la surveillance du volume logique est activée.

    $ sudo lvs -o+seg_monitor
    
    LV       VG     Attr       LSize  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert Monitor
    thinpool docker twi-a-t--- 95.00g             0.00   0.01                             not monitored
    

    Si la sortie dans la colonne Monitor rapporte, comme ci-dessus, que le volume est not monitored, alors la surveillance doit être explicitement activée. Sans cette étape, l'extension automatique du volume logique n'aura pas lieu, peu importe les paramètres dans le profil appliqué.

    $ sudo lvchange --monitor y docker/thinpool
    

    Vérifiez à nouveau que la surveillance est maintenant activée en exécutant la commande sudo lvs -o+seg_monitor une seconde fois. La colonne Monitor devrait maintenant rapporter que le volume logique est monitored.

  12. Si vous avez déjà exécuté Docker sur cet hôte auparavant, ou si /var/lib/docker/ existe, déplacez-le hors du chemin pour que Docker puisse utiliser le nouveau pool LVM pour stocker le contenu des images et conteneurs.

    $ sudo su -
    # mkdir /var/lib/docker.bk
    # mv /var/lib/docker/* /var/lib/docker.bk
    # exit
    

    Si l'une des étapes suivantes échoue et vous devez restaurer, vous pouvez supprimer /var/lib/docker et le remplacer par /var/lib/docker.bk.

  13. Éditez /etc/docker/daemon.json et configurez les options nécessaires pour le pilote de stockage devicemapper. Si le fichier était précédemment vide, il devrait maintenant contenir le contenu suivant :

    {
        "storage-driver": "devicemapper",
        "storage-opts": [
        "dm.thinpooldev=/dev/mapper/docker-thinpool",
        "dm.use_deferred_removal=true",
        "dm.use_deferred_deletion=true"
        ]
    }
  14. Démarrez Docker.

    systemd :

    $ sudo systemctl start docker
    

    service :

    $ sudo service docker start
    
  15. Vérifiez que Docker utilise la nouvelle configuration en utilisant docker info.

    $ docker info
    
    Containers: 0
     Running: 0
     Paused: 0
     Stopped: 0
    Images: 0
    Server Version: 17.03.1-ce
    Storage Driver: devicemapper
     Pool Name: docker-thinpool
     Pool Blocksize: 524.3 kB
     Base Device Size: 10.74 GB
     Backing Filesystem: xfs
     Data file:
     Metadata file:
     Data Space Used: 19.92 MB
     Data Space Total: 102 GB
     Data Space Available: 102 GB
     Metadata Space Used: 147.5 kB
     Metadata Space Total: 1.07 GB
     Metadata Space Available: 1.069 GB
     Thin Pool Minimum Free Space: 10.2 GB
     Udev Sync Supported: true
     Deferred Removal Enabled: true
     Deferred Deletion Enabled: true
     Deferred Deleted Device Count: 0
     Library Version: 1.02.135-RHEL7 (2016-11-16)
    <...>
    

    Si Docker est configuré correctement, le Data file et Metadata file sont vides, et le nom du pool est docker-thinpool.

  16. Après avoir vérifié que la configuration est correcte, vous pouvez supprimer le répertoire /var/lib/docker.bk qui contient la configuration précédente.

    $ sudo rm -rf /var/lib/docker.bk
    

Gérer devicemapper

Surveiller le thin pool

Ne vous fiez pas uniquement à l'auto-extension LVM. Le groupe de volumes s'étend automatiquement, mais le volume peut toujours se remplir. Vous pouvez surveiller l'espace libre sur le volume en utilisant lvs ou lvs -a. Considérez l'utilisation d'un outil de surveillance au niveau OS, tel que Nagios.

Pour voir les logs LVM, vous pouvez utiliser journalctl :

$ sudo journalctl -fu dm-event.service

Si vous rencontrez des problèmes répétés avec le thin pool, vous pouvez définir l'option de stockage dm.min_free_space à une valeur (représentant un pourcentage) dans /etc/docker/daemon.json. Par exemple, la définir à 10 assure que les opérations échouent avec un avertissement quand l'espace libre est à ou près de 10%. Voir les options du pilote de stockage dans la référence du démon Engine.

Augmenter la capacité sur un périphérique en cours d'exécution

Vous pouvez augmenter la capacité du pool sur un périphérique thin-pool en cours d'exécution. C'est utile si le volume logique des données est plein et le groupe de volumes est à pleine capacité. La procédure spécifique dépend de si vous utilisez un thin pool loop-lvm ou un thin pool direct-lvm.

Redimensionner un thin pool loop-lvm

La façon la plus facile de redimensionner un thin pool loop-lvm est d' utiliser l'utilitaire device_tool, mais vous pouvez utiliser les utilitaires du système d'exploitation à la place.

Utiliser l'utilitaire device_tool

Un script contribué par la communauté appelé device_tool.go est disponible dans le dépôt Github moby/moby. Vous pouvez utiliser cet outil pour redimensionner un thin pool loop-lvm, évitant le long processus ci-dessus. Cet outil n'est pas garanti de fonctionner, mais vous ne devriez utiliser loop-lvm que sur des systèmes non-production.

Si vous ne voulez pas utiliser device_tool, vous pouvez redimensionner le thin pool manuellement à la place.

  1. Pour utiliser l'outil, clonez le dépôt Github, changez vers le contrib/docker-device-tool, et suivez les instructions dans le README.md pour compiler l'outil.

  2. Utilisez l'outil. L'exemple suivant redimensionne le thin pool à 200GB.

    $ ./device_tool resize 200GB
    
Utiliser les utilitaires du système d'exploitation

Si vous ne voulez pas utiliser l'utilitaire device-tool, vous pouvez redimensionner un thin pool loop-lvm manuellement en utilisant la procédure suivante.

En mode loop-lvm, un périphérique loopback est utilisé pour stocker les données, et un autre pour stocker les métadonnées. Le mode loop-lvm n'est supporté que pour les tests, parce qu' il a des inconvénients significatifs de performance et stabilité.

Si vous utilisez le mode loop-lvm, la sortie de docker info montre les chemins de fichiers pour Data loop file et Metadata loop file :

$ docker info |grep 'loop file'

 Data loop file: /var/lib/docker/devicemapper/data
 Metadata loop file: /var/lib/docker/devicemapper/metadata

Suivez ces étapes pour augmenter la taille du thin pool. Dans cet exemple, le thin pool fait 100 GB, et est augmenté à 200 GB.

  1. Listez les tailles des périphériques.

    $ sudo ls -lh /var/lib/docker/devicemapper/
    
    total 1175492
    -rw------- 1 root root 100G Mar 30 05:22 data
    -rw------- 1 root root 2.0G Mar 31 11:17 metadata
    
  2. Augmentez la taille du fichier data à 200 G en utilisant la commande truncate, qui est utilisée pour augmenter ou diminuer la taille d'un fichier. Notez que diminuer la taille est une opération destructive.

    $ sudo truncate -s 200G /var/lib/docker/devicemapper/data
    
  3. Vérifiez que la taille du fichier a changé.

    $ sudo ls -lh /var/lib/docker/devicemapper/
    
    total 1.2G
    -rw------- 1 root root 200G Apr 14 08:47 data
    -rw------- 1 root root 2.0G Apr 19 13:27 metadata
    
  4. Le fichier loopback a changé sur disque mais pas en mémoire. Listez la taille du périphérique loopback en mémoire, en GB. Rechargez-le, puis listez la taille à nouveau. Après le rechargement, la taille est 200 GB.

    $ echo $[ $(sudo blockdev --getsize64 /dev/loop0) / 1024 / 1024 / 1024 ]
    
    100
    
    $ sudo losetup -c /dev/loop0
    
    $ echo $[ $(sudo blockdev --getsize64 /dev/loop0) / 1024 / 1024 / 1024 ]
    
    200
    
  5. Rechargez le thin pool devicemapper.

    a. Obtenez d'abord le nom du pool. Le nom du pool est le premier champ, délimité par :. Cette commande l'extrait.

    $ sudo dmsetup status | grep ' thin-pool ' | awk -F ': ' {'print $1'}
    docker-8:1-123141-pool
    

    b. Videz la table device mapper pour le thin pool.

    $ sudo dmsetup table docker-8:1-123141-pool
    0 209715200 thin-pool 7:1 7:0 128 32768 1 skip_block_zeroing
    

    c. Calculez le total de secteurs du thin pool en utilisant le second champ de la sortie. Le nombre est exprimé en secteurs de 512-k. Un fichier de 100G a 209715200 secteurs de 512-k. Si vous doublez ce nombre à 200G, vous obtenez 419430400 secteurs de 512-k.

    d. Rechargez le thin pool avec le nouveau nombre de secteurs, en utilisant les trois commandes dmsetup suivantes.

    $ sudo dmsetup suspend docker-8:1-123141-pool
    $ sudo dmsetup reload docker-8:1-123141-pool --table '0 419430400 thin-pool 7:1 7:0 128 32768 1 skip_block_zeroing'
    $ sudo dmsetup resume docker-8:1-123141-pool
    

Redimensionner un thin pool direct-lvm

Pour étendre un thin pool direct-lvm, vous devez d'abord attacher un nouveau périphérique bloc à l'hôte Docker, et noter le nom qui lui est assigné par le noyau. Dans cet exemple, le nouveau périphérique bloc est /dev/xvdg.

Suivez cette procédure pour étendre un thin pool direct-lvm, en substituant votre périphérique bloc et autres paramètres pour convenir à votre situation.

  1. Rassemblez des informations sur votre groupe de volumes.

    Utilisez la commande pvdisplay pour trouver les périphériques bloc physiques actuellement en usage par votre thin pool, et le nom du groupe de volumes.

    $ sudo pvdisplay |grep 'VG Name'
    
    PV Name               /dev/xvdf
    VG Name               docker
    

    Dans les étapes suivantes, substituez votre périphérique bloc ou nom de groupe de volumes selon le cas.

  2. Étendez le groupe de volumes, en utilisant la commande vgextend avec le VG Name de l'étape précédente, et le nom de votre nouveau périphérique bloc.

    $ sudo vgextend docker /dev/xvdg
    
    Physical volume "/dev/xvdg" successfully created.
    Volume group "docker" successfully extended
    
  3. Étendez le volume logique docker/thinpool. Cette commande utilise 100% du volume immédiatement, sans auto-extension. Pour étendre le thinpool de métadonnées à la place, utilisez docker/thinpool_tmeta.

    $ sudo lvextend -l+100%FREE -n docker/thinpool
    
    Size of logical volume docker/thinpool_tdata changed from 95.00 GiB (24319 extents) to 198.00 GiB (50688 extents).
    Logical volume docker/thinpool_tdata successfully resized.
    
  4. Vérifiez la nouvelle taille du thin pool en utilisant le champ Data Space Available dans la sortie de docker info. Si vous avez étendu le volume logique docker/thinpool_tmeta à la place, cherchez Metadata Space Available.

    Storage Driver: devicemapper
     Pool Name: docker-thinpool
     Pool Blocksize: 524.3 kB
     Base Device Size: 10.74 GB
     Backing Filesystem: xfs
     Data file:
     Metadata file:
     Data Space Used: 212.3 MB
     Data Space Total: 212.6 GB
     Data Space Available: 212.4 GB
     Metadata Space Used: 286.7 kB
     Metadata Space Total: 1.07 GB
     Metadata Space Available: 1.069 GB
    <...>

Activer le devicemapper après redémarrage

Si vous redémarrez l'hôte et trouvez que le service docker a échoué à démarrer, cherchez l'erreur, "Non existing device". Vous devez réactiver les volumes logiques avec cette commande :

$ sudo lvchange -ay docker/thinpool

Comment fonctionne le pilote de stockage devicemapper

Warning

Ne manipulez pas directement les fichiers ou répertoires dans /var/lib/docker/. Ces fichiers et répertoires sont gérés par Docker.

Utilisez la commande lsblk pour voir les périphériques et leurs pools, du point de vue du système d'exploitation :

$ sudo lsblk

NAME                    MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
xvda                    202:0    0    8G  0 disk
└─xvda1                 202:1    0    8G  0 part /
xvdf                    202:80   0  100G  0 disk
├─docker-thinpool_tmeta 253:0    0 1020M  0 lvm
│ └─docker-thinpool     253:2    0   95G  0 lvm
└─docker-thinpool_tdata 253:1    0   95G  0 lvm
  └─docker-thinpool     253:2    0   95G  0 lvm

Utilisez la commande mount pour voir le point de montage que Docker utilise :

$ mount |grep devicemapper
/dev/xvda1 on /var/lib/docker/devicemapper type xfs (rw,relatime,seclabel,attr2,inode64,noquota)

Quand vous utilisez devicemapper, Docker stocke le contenu des images et couches dans le thinpool, et les expose aux conteneurs en les montant sous des sous-répertoires de /var/lib/docker/devicemapper/.

Couches d'images et de conteneurs sur disque

Le répertoire /var/lib/docker/devicemapper/metadata/ contient des métadonnées sur la configuration Devicemapper elle-même et sur chaque couche d'image et de conteneur qui existe. Le pilote de stockage devicemapper utilise des snapshots, et ces métadonnées incluent des informations sur ces snapshots. Ces fichiers sont au format JSON.

Le répertoire /var/lib/docker/devicemapper/mnt/ contient un point de montage pour chaque couche d'image et de conteneur qui existe. Les points de montage des couches d'images sont vides, mais le point de montage d'un conteneur montre le système de fichiers du conteneur tel qu'il apparaît depuis l'intérieur du conteneur.

Superposition et partage d'images

Le pilote de stockage devicemapper utilise des périphériques bloc dédiés plutôt que des systèmes de fichiers formatés, et opère sur les fichiers au niveau bloc pour une performance maximum pendant les opérations de copie-sur-écriture (CoW).

Snapshots

Une autre fonctionnalité de devicemapper est son utilisation de snapshots (aussi parfois appelés périphériques fins ou périphériques virtuels), qui stockent les différences introduites dans chaque couche comme des thin pools très petits et légers. Les snapshots fournissent de nombreux avantages :

  • Les couches qui sont partagées en commun entre conteneurs ne sont stockées sur disque qu' une seule fois, à moins qu'elles ne soient inscriptibles. Par exemple, si vous avez 10 images différentes qui sont toutes basées sur alpine, l'image alpine et toutes ses images parentes ne sont stockées qu'une fois chacune sur disque.

  • Les snapshots sont une implémentation d'une stratégie de copie-sur-écriture (CoW). Cela signifie qu'un fichier ou répertoire donné n'est copié vers la couche inscriptible du conteneur que quand il est modifié ou supprimé par ce conteneur.

  • Parce que devicemapper opère au niveau bloc, plusieurs blocs dans une couche inscriptible peuvent être modifiés simultanément.

  • Les snapshots peuvent être sauvegardés en utilisant des utilitaires de sauvegarde standard au niveau OS. Faites simplement une copie de /var/lib/docker/devicemapper/.

Flux de travail Devicemapper

Quand vous démarrez Docker avec le pilote de stockage devicemapper, tous les objets liés aux couches d'images et de conteneurs sont stockés dans /var/lib/docker/devicemapper/, qui est supporté par un ou plusieurs périphériques de niveau bloc, soit des périphériques loopback (tests seulement) soit des disques physiques.

  • Le périphérique de base est l'objet de plus bas niveau. C'est le thin pool lui-même. Vous pouvez l'examiner en utilisant docker info. Il contient un système de fichiers. Ce périphérique de base est le point de départ pour chaque couche d'image et de conteneur. Le périphérique de base est un détail d'implémentation Device Mapper, plutôt qu'une couche Docker.

  • Les métadonnées sur le périphérique de base et chaque couche d'image ou de conteneur sont stockées dans /var/lib/docker/devicemapper/metadata/ au format JSON. Ces couches sont des snapshots de copie-sur-écriture, ce qui signifie qu'elles sont vides jusqu'à ce qu'elles divergent de leurs couches parentes.

  • La couche inscriptible de chaque conteneur est montée sur un point de montage dans /var/lib/docker/devicemapper/mnt/. Un répertoire vide existe pour chaque couche d'image en lecture seule et chaque conteneur arrêté.

Chaque couche d'image est un snapshot de la couche en dessous. La couche la plus basse de chaque image est un snapshot du périphérique de base qui existe dans le pool. Quand vous exécutez un conteneur, c'est un snapshot de l'image sur laquelle le conteneur est basé. L'exemple suivant montre un hôte Docker avec deux conteneurs en cours d'exécution. Le premier est un conteneur ubuntu et le second est un conteneur busybox.

Couches d'images Ubuntu et busybox

Comment les lectures et écritures de conteneur fonctionnent avec devicemapper

Lecture de fichiers

Avec devicemapper, les lectures se passent au niveau bloc. Le diagramme ci-dessous montre le processus de haut niveau pour lire un seul bloc (0x44f) dans un exemple de conteneur.

Lecture d'un bloc avec devicemapper

Une application fait une demande de lecture pour le bloc 0x44f dans le conteneur. Parce que le conteneur est un snapshot fin d'une image, il n'a pas le bloc, mais il a un pointeur vers le bloc sur l'image parente la plus proche où il existe, et il lit le bloc depuis là. Le bloc existe maintenant dans la mémoire du conteneur.

Écriture de fichiers

Écriture d'un nouveau fichier : Avec le pilote devicemapper, écrire de nouvelles données dans un conteneur s'accomplit par une opération allocate-on-demand. Chaque bloc du nouveau fichier est alloué dans la couche inscriptible du conteneur et le bloc y est écrit.

Mise à jour d'un fichier existant : Le bloc pertinent du fichier est lu depuis la couche la plus proche où il existe. Quand le conteneur écrit le fichier, seuls les blocs modifiés sont écrits dans la couche inscriptible du conteneur.

Suppression d'un fichier ou répertoire : Quand vous supprimez un fichier ou répertoire dans la couche inscriptible d'un conteneur, ou quand une couche d'image supprime un fichier qui existe dans sa couche parente, le pilote de stockage devicemapper intercepte les futures tentatives de lecture sur ce fichier ou répertoire et répond que le fichier ou répertoire n'existe pas.

Écriture puis suppression d'un fichier : Si un conteneur écrit dans un fichier et plus tard supprime le fichier, toutes ces opérations se passent dans la couche inscriptible du conteneur. Dans ce cas, si vous utilisez direct-lvm, les blocs sont libérés. Si vous utilisez loop-lvm, les blocs peuvent ne pas être libérés. C'est une autre raison de ne pas utiliser loop-lvm en production.

Device Mapper et performance Docker

  • Impact de performance allocate-on demand :

    Le pilote de stockage devicemapper utilise une opération allocate-on-demand pour allouer de nouveaux blocs depuis le thin pool dans la couche inscriptible d'un conteneur. Chaque bloc fait 64KB, donc c'est la quantité minimale d'espace qui est utilisée pour une écriture.

  • Impact de performance de copie-sur-écriture : La première fois qu'un conteneur modifie un bloc spécifique, ce bloc est écrit dans la couche inscriptible du conteneur. Parce que ces écritures se passent au niveau du bloc plutôt qu'au niveau du fichier, l'impact sur la performance est minimisé. Cependant, écrire un grand nombre de blocs peut encore impacter négativement la performance, et le pilote de stockage devicemapper peut en fait performer moins bien que d'autres pilotes de stockage dans ce scénario. Pour les charges de travail intensives en écriture, vous devriez utiliser des volumes de données, qui contournent complètement le pilote de stockage.

Meilleures pratiques de performance

Gardez ces choses à l'esprit pour maximiser la performance lors de l'utilisation du pilote de stockage devicemapper.

  • Utilisez direct-lvm : Le mode loop-lvm n'est pas performant et ne devrait jamais être utilisé en production.

  • Utilisez du stockage rapide : Les disques à état solide (SSD) fournissent des lectures et écritures plus rapides que les disques rotatifs.

  • Utilisation mémoire : le devicemapper utilise plus de mémoire que certains autres pilotes de stockage. Chaque conteneur lancé charge une ou plusieurs copies de ses fichiers en mémoire, selon combien de blocs du même fichier sont modifiés en même temps. Dû à la pression mémoire, le pilote de stockage devicemapper peut ne pas être le bon choix pour certaines charges de travail dans les cas d'usage à haute densité.

  • Utilisez des volumes pour les charges de travail intensives en écriture : Les volumes fournissent les meilleures et plus prévisibles performances pour les charges de travail intensives en écriture. C'est parce qu'ils contournent le pilote de stockage et n'encourent aucun des coûts supplémentaires potentiels introduits par le provisioning fin et la copie-sur-écriture. Les volumes ont d'autres avantages, tels que vous permettre de partager des données entre conteneurs et persister même quand aucun conteneur en cours d'exécution ne les utilise.

    Note

    Lors de l'utilisation de devicemapper et du pilote de log json-file, les fichiers de log générés par un conteneur sont encore stockés dans le répertoire dataroot de Docker, par défaut /var/lib/docker. Si vos conteneurs génèrent beaucoup de messages de log, ceci peut mener à une utilisation accrue du disque ou à l'incapacité de gérer votre système dû à un disque plein. Vous pouvez configurer un pilote de log pour stocker vos logs de conteneur externalement.

Informations connexes