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

Pilote de stockage OverlayFS

OverlayFS est un système de fichiers unionisé.

Cette page fait référence au pilote du noyau Linux sous le nom OverlayFS et au pilote de stockage Docker sous le nom overlay2.

Note

Pour le pilote fuse-overlayfs, consultez la documentation du mode rootless.

Prérequis

OverlayFS est le pilote de stockage recommandé, et pris en charge si vous respectez les prérequis suivants :

  • Version 4.0 ou supérieure du noyau Linux, ou RHEL ou CentOS utilisant la version 3.10.0-514 du noyau ou supérieure.

  • Le pilote overlay2 est pris en charge sur les systèmes de fichiers de support xfs, mais seulement avec d_type=true activé.

    Utilisez xfs_info pour vérifier que l'option ftype est définie à 1. Pour formater un système de fichiers xfs correctement, utilisez le flag -n ftype=1.

  • Changer le pilote de stockage rend les conteneurs et images existants inaccessibles sur le système local. Utilisez docker save pour sauvegarder toutes les images que vous avez construites ou poussez-les vers Docker Hub ou un registre privé avant de changer le pilote de stockage, afin de ne pas avoir besoin de les recréer plus tard.

Configurer Docker avec le pilote de stockage overlay2

Avant de suivre cette procédure, vous devez d'abord respecter tous les prérequis.

Les étapes suivantes décrivent comment configurer le pilote de stockage overlay2.

  1. Arrêtez Docker.

    $ sudo systemctl stop docker
    
  2. Copiez le contenu de /var/lib/docker vers un emplacement temporaire.

    $ cp -au /var/lib/docker /var/lib/docker.bk
    
  3. Si vous voulez utiliser un système de fichiers de support séparé de celui utilisé par /var/lib/, formatez le système de fichiers et montez-le dans /var/lib/docker. Assurez-vous d'ajouter ce montage à /etc/fstab pour le rendre permanent.

  4. Modifiez /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": "overlay2"
    }

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

  5. Démarrez Docker.

    $ sudo systemctl start docker
    
  6. Vérifiez que le démon utilise le pilote de stockage overlay2. Utilisez la commande docker info et recherchez Storage Driver et Backing filesystem.

    $ docker info
    
    Containers: 0
    Images: 0
    Storage Driver: overlay2
     Backing Filesystem: xfs
     Supports d_type: true
     Native Overlay Diff: true
    <...>
    

Docker utilise maintenant le pilote de stockage overlay2 et a automatiquement créé le montage overlay avec les constructions requises lowerdir, upperdir, merged, et workdir.

Continuez la lecture pour les détails sur comment OverlayFS fonctionne dans vos conteneurs Docker, ainsi que les conseils de performance et les informations sur les limitations de sa compatibilité avec différents systèmes de fichiers de support.

Comment fonctionne le pilote overlay2

OverlayFS superpose deux répertoires sur un seul hôte Linux et les présente comme un seul répertoire. Ces répertoires sont appelés couches, et le processus d'unification est appelé montage union. OverlayFS fait référence au répertoire inférieur comme lowerdir et au répertoire supérieur comme upperdir. La vue unifiée est exposée à travers son propre répertoire appelé merged.

Le pilote overlay2 prend en charge nativement jusqu'à 128 couches OverlayFS inférieures. Cette capacité fournit de meilleures performances pour les commandes Docker liées aux couches telles que docker build et docker commit, et consomme moins d'inodes sur le système de fichiers de support.

Couches d'image et de conteneur sur disque

Après avoir téléchargé une image à cinq couches en utilisant docker pull ubuntu, vous pouvez voir six répertoires sous /var/lib/docker/overlay2.

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.

$ ls -l /var/lib/docker/overlay2

total 24
drwx------ 5 root root 4096 Jun 20 07:36 223c2864175491657d238e2664251df13b63adb8d050924fd1bfcdb278b866f7
drwx------ 3 root root 4096 Jun 20 07:36 3a36935c9df35472229c57f4a27105a136f5e4dbef0f87905b2e506e494e348b
drwx------ 5 root root 4096 Jun 20 07:36 4e9fa83caff3e8f4cc83693fa407a4a9fac9573deaf481506c102d484dd1e6a1
drwx------ 5 root root 4096 Jun 20 07:36 e8876a226237217ec61c4baf238a32992291d059fdac95ed6303bdff3f59cff5
drwx------ 5 root root 4096 Jun 20 07:36 eca1e4e1694283e001f200a667bb3cb40853cf2d1b12c29feda7422fed78afed
drwx------ 2 root root 4096 Jun 20 07:36 l

Le nouveau répertoire l (L minuscule) contient des identifiants de couche raccourcis sous forme de liens symboliques. Ces identifiants sont utilisés pour éviter d'atteindre la limitation de taille de page sur les arguments de la commande mount.

$ ls -l /var/lib/docker/overlay2/l

total 20
lrwxrwxrwx 1 root root 72 Jun 20 07:36 6Y5IM2XC7TSNIJZZFLJCS6I4I4 -> ../3a36935c9df35472229c57f4a27105a136f5e4dbef0f87905b2e506e494e348b/diff
lrwxrwxrwx 1 root root 72 Jun 20 07:36 B3WWEFKBG3PLLV737KZFIASSW7 -> ../4e9fa83caff3e8f4cc83693fa407a4a9fac9573deaf481506c102d484dd1e6a1/diff
lrwxrwxrwx 1 root root 72 Jun 20 07:36 JEYMODZYFCZFYSDABYXD5MF6YO -> ../eca1e4e1694283e001f200a667bb3cb40853cf2d1b12c29feda7422fed78afed/diff
lrwxrwxrwx 1 root root 72 Jun 20 07:36 NFYKDW6APBCCUCTOUSYDH4DXAT -> ../223c2864175491657d238e2664251df13b63adb8d050924fd1bfcdb278b866f7/diff
lrwxrwxrwx 1 root root 72 Jun 20 07:36 UL2MW33MSE3Q5VYIKBRN4ZAGQP -> ../e8876a226237217ec61c4baf238a32992291d059fdac95ed6303bdff3f59cff5/diff

La couche la plus basse contient un fichier appelé link, qui contient le nom de l'identifiant raccourci, et un répertoire appelé diff qui contient le contenu de la couche.

$ ls /var/lib/docker/overlay2/3a36935c9df35472229c57f4a27105a136f5e4dbef0f87905b2e506e494e348b/

diff  link

$ cat /var/lib/docker/overlay2/3a36935c9df35472229c57f4a27105a136f5e4dbef0f87905b2e506e494e348b/link

6Y5IM2XC7TSNIJZZFLJCS6I4I4

$ ls  /var/lib/docker/overlay2/3a36935c9df35472229c57f4a27105a136f5e4dbef0f87905b2e506e494e348b/diff

bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

La deuxième couche la plus basse, et chaque couche supérieure, contiennent un fichier appelé lower, qui désigne son parent, et un répertoire appelé diff qui contient son contenu. Elle contient aussi un répertoire merged, qui contient le contenu unifié de sa couche parent et d'elle-même, et un répertoire work qui est utilisé en interne par OverlayFS.

$ ls /var/lib/docker/overlay2/223c2864175491657d238e2664251df13b63adb8d050924fd1bfcdb278b866f7

diff  link  lower  merged  work

$ cat /var/lib/docker/overlay2/223c2864175491657d238e2664251df13b63adb8d050924fd1bfcdb278b866f7/lower

l/6Y5IM2XC7TSNIJZZFLJCS6I4I4

$ ls /var/lib/docker/overlay2/223c2864175491657d238e2664251df13b63adb8d050924fd1bfcdb278b866f7/diff/

etc  sbin  usr  var

To view the mounts which exist when you use the overlay storage driver with Docker, use the mount command. The output below is truncated for readability.

$ mount | grep overlay

overlay on /var/lib/docker/overlay2/9186877cdf386d0a3b016149cf30c208f326dca307529e646afce5b3f83f5304/merged
type overlay (rw,relatime,
lowerdir=l/DJA75GUWHWG7EWICFYX54FIOVT:l/B3WWEFKBG3PLLV737KZFIASSW7:l/JEYMODZYFCZFYSDABYXD5MF6YO:l/UL2MW33MSE3Q5VYIKBRN4ZAGQP:l/NFYKDW6APBCCUCTOUSYDH4DXAT:l/6Y5IM2XC7TSNIJZZFLJCS6I4I4,
upperdir=9186877cdf386d0a3b016149cf30c208f326dca307529e646afce5b3f83f5304/diff,
workdir=9186877cdf386d0a3b016149cf30c208f326dca307529e646afce5b3f83f5304/work)

The rw on the second line shows that the overlay mount is read-write.

Le diagramme suivant montre comment une image Docker et un conteneur Docker sont superposés. La couche d'image est le lowerdir et la couche de conteneur est l' upperdir. Si l'image a plusieurs couches, plusieurs répertoires lowerdir sont utilisés. La vue unifiée est exposée à travers un répertoire appelé merged qui est effectivement le point de montage du conteneur.

Comment les constructions Docker correspondent aux constructions OverlayFS

Lorsque la couche d'image et la couche de conteneur contiennent les mêmes fichiers, la couche de conteneur (upperdir) a la précédence et masque l'existence des mêmes fichiers dans la couche d'image.

Pour créer un conteneur, le pilote overlay2 combine le répertoire représentant la couche supérieure de l'image plus un nouveau répertoire pour le conteneur. Les couches de l'image sont les lowerdirs dans l'overlay et sont en lecture seule. Le nouveau répertoire pour le conteneur est l'upperdir et est modifiable.

Image and container layers on-disk

The following docker pull command shows a Docker host downloading a Docker image comprising five layers.

$ docker pull ubuntu

Using default tag: latest
latest: Pulling from library/ubuntu

5ba4f30e5bea: Pull complete
9d7d19c9dc56: Pull complete
ac6ad7efd0f9: Pull complete
e7491a747824: Pull complete
a3ed95caeb02: Pull complete
Digest: sha256:46fb5d001b88ad904c5c732b086b596b92cfb4a4840a3abd0e35dbb6870585e4
Status: Downloaded newer image for ubuntu:latest

The image layers

Each image layer has its own directory within /var/lib/docker/overlay/, which contains its contents, as shown in the following example. The image layer IDs don't correspond to the directory IDs.

Warning

Don't directly manipulate any files or directories within /var/lib/docker/. These files and directories are managed by Docker.

$ ls -l /var/lib/docker/overlay/

total 20
drwx------ 3 root root 4096 Jun 20 16:11 38f3ed2eac129654acef11c32670b534670c3a06e483fce313d72e3e0a15baa8
drwx------ 3 root root 4096 Jun 20 16:11 55f1e14c361b90570df46371b20ce6d480c434981cbda5fd68c6ff61aa0a5358
drwx------ 3 root root 4096 Jun 20 16:11 824c8a961a4f5e8fe4f4243dab57c5be798e7fd195f6d88ab06aea92ba931654
drwx------ 3 root root 4096 Jun 20 16:11 ad0fe55125ebf599da124da175174a4b8c1878afe6907bf7c78570341f308461
drwx------ 3 root root 4096 Jun 20 16:11 edab9b5e5bf73f2997524eebeac1de4cf9c8b904fa8ad3ec43b3504196aa3801

The image layer directories contain the files unique to that layer as well as hard links to the data shared with lower layers. This allows for efficient use of disk space.

$ ls -i /var/lib/docker/overlay2/38f3ed2eac129654acef11c32670b534670c3a06e483fce313d72e3e0a15baa8/root/bin/ls

19793696 /var/lib/docker/overlay2/38f3ed2eac129654acef11c32670b534670c3a06e483fce313d72e3e0a15baa8/root/bin/ls

$ ls -i /var/lib/docker/overlay2/55f1e14c361b90570df46371b20ce6d480c434981cbda5fd68c6ff61aa0a5358/root/bin/ls

19793696 /var/lib/docker/overlay2/55f1e14c361b90570df46371b20ce6d480c434981cbda5fd68c6ff61aa0a5358/root/bin/ls

The container layer

Containers also exist on-disk in the Docker host's filesystem under /var/lib/docker/overlay/. If you list a running container's subdirectory using the ls -l command, three directories and one file exist:

$ ls -l /var/lib/docker/overlay2/<directory-of-running-container>

total 16
-rw-r--r-- 1 root root   64 Jun 20 16:39 lower-id
drwxr-xr-x 1 root root 4096 Jun 20 16:39 merged
drwxr-xr-x 4 root root 4096 Jun 20 16:39 upper
drwx------ 3 root root 4096 Jun 20 16:39 work

The lower-id file contains the ID of the top layer of the image the container is based on, which is the OverlayFS lowerdir.

$ cat /var/lib/docker/overlay2/ec444863a55a9f1ca2df72223d459c5d940a721b2288ff86a3f27be28b53be6c/lower-id

55f1e14c361b90570df46371b20ce6d480c434981cbda5fd68c6ff61aa0a5358

The upper directory contains the contents of the container's read-write layer, which corresponds to the OverlayFS upperdir.

The merged directory is the union mount of the lowerdir and upperdirs, which comprises the view of the filesystem from within the running container.

The work directory is internal to OverlayFS.

To view the mounts which exist when you use the overlay2 storage driver with Docker, use the mount command. The following output is truncated for readability.

$ mount | grep overlay

overlay on /var/lib/docker/overlay2/l/ec444863a55a.../merged
type overlay (rw,relatime,lowerdir=/var/lib/docker/overlay2/l/55f1e14c361b.../root,
upperdir=/var/lib/docker/overlay2/l/ec444863a55a.../upper,
workdir=/var/lib/docker/overlay2/l/ec444863a55a.../work)

The rw on the second line shows that the overlay mount is read-write.

Comment fonctionnent les lectures et écritures de conteneur avec overlay2

Lecture de fichiers

Considérez trois scénarios où un conteneur ouvre un fichier pour un accès en lecture avec overlay.

Le fichier n'existe pas dans la couche de conteneur

Si un conteneur ouvre un fichier pour un accès en lecture et que le fichier n'existe pas déjà dans le conteneur (upperdir), il est lu depuis l'image (lowerdir). Cela entraîne très peu de surcharge de performance.

Le fichier existe seulement dans la couche de conteneur

Si un conteneur ouvre un fichier pour un accès en lecture et que le fichier existe dans le conteneur (upperdir) et pas dans l'image (lowerdir), il est lu directement depuis le conteneur.

Le fichier existe dans les deux couches, de conteneur et d'image

Si un conteneur ouvre un fichier pour un accès en lecture et que le fichier existe dans la couche d'image et la couche de conteneur, la version du fichier dans la couche de conteneur est lue. Les fichiers dans la couche de conteneur (upperdir) masquent les fichiers avec le même nom dans la couche d'image (lowerdir).

Modification de fichiers ou répertoires

Considérez quelques scénarios où les fichiers dans un conteneur sont modifiés.

Écriture dans un fichier pour la première fois

La première fois qu'un conteneur écrit dans un fichier existant, ce fichier n'existe pas dans le conteneur (upperdir). Le pilote overlay2 effectue une opération copy_up pour copier le fichier depuis l'image (lowerdir) vers le conteneur (upperdir). Le conteneur écrit ensuite les changements dans la nouvelle copie du fichier dans la couche de conteneur.

Cependant, OverlayFS fonctionne au niveau des fichiers plutôt qu'au niveau des blocs. Cela signifie que toutes les opérations copy_up d'OverlayFS copient le fichier entier, même si le fichier est grand et que seulement une petite partie est modifiée. Cela peut avoir un impact notable sur les performances d'écriture du conteneur. Cependant, deux choses sont à noter :

  • L'opération copy_up n'a lieu que la première fois qu'un fichier donné est écrit. Les écritures suivantes dans le même fichier opèrent sur la copie du fichier déjà copiée vers le conteneur.

  • OverlayFS fonctionne avec plusieurs couches. Cela signifie que les performances peuvent être impactées lors de la recherche de fichiers dans des images avec de nombreuses couches.

Deleting files and directories

  • When a file is deleted within a container, a whiteout file is created in the container (upperdir). The version of the file in the image layer (lowerdir) is not deleted (because the lowerdir is read-only). However, the whiteout file prevents it from being available to the container.

  • When a directory is deleted within a container, an opaque directory is created within the container (upperdir). This works in the same way as a whiteout file and effectively prevents the directory from being accessed, even though it still exists in the image (lowerdir).

Renaming directories

Calling rename(2) for a directory is allowed only when both the source and the destination path are on the top layer. Otherwise, it returns EXDEV error ("cross-device link not permitted"). Your application needs to be designed to handle EXDEV and fall back to a "copy and unlink" strategy.

OverlayFS and Docker Performance

overlay2 may perform better than btrfs. However, be aware of the following details:

Page caching

OverlayFS supports page cache sharing. Multiple containers accessing the same file share a single page cache entry for that file. This makes the overlay2 drivers efficient with memory and a good option for high-density use cases such as PaaS.

Copyup

As with other copy-on-write filesystems, OverlayFS performs copy-up operations whenever a container writes to a file for the first time. This can add latency into the write operation, especially for large files. However, once the file has been copied up, all subsequent writes to that file occur in the upper layer, without the need for further copy-up operations.

Performance best practices

The following generic performance best practices apply to OverlayFS.

Use fast storage

Solid-state drives (SSDs) provide faster reads and writes than spinning disks.

Use volumes for write-heavy workloads

Volumes provide the best and most predictable performance for write-heavy workloads. This is because they bypass the storage driver and don't incur any of the potential overheads introduced by thin provisioning and copy-on-write. Volumes have other benefits, such as allowing you to share data among containers and persisting your data even if no running container is using them.

Limitations on OverlayFS compatibility

To summarize the OverlayFS's aspect which is incompatible with other filesystems:

open(2)
OverlayFS only implements a subset of the POSIX standards. This can result in certain OverlayFS operations breaking POSIX standards. One such operation is the copy-up operation. Suppose that your application calls fd1=open("foo", O_RDONLY) and then fd2=open("foo", O_RDWR). In this case, your application expects fd1 and fd2 to refer to the same file. However, due to a copy-up operation that occurs after the second calling to open(2), the descriptors refer to different files. The fd1 continues to reference the file in the image (lowerdir) and the fd2 references the file in the container (upperdir). A workaround for this is to touch the files which causes the copy-up operation to happen. All subsequent open(2) operations regardless of read-only or read-write access mode reference the file in the container (upperdir).

yum is known to be affected unless the yum-plugin-ovl package is installed. If the yum-plugin-ovl package is not available in your distribution such as RHEL/CentOS prior to 6.8 or 7.2, you may need to run touch /var/lib/rpm/* before running yum install. This package implements the touch workaround referenced above for yum.

rename(2)
OverlayFS does not fully support the rename(2) system call. Your application needs to detect its failure and fall back to a "copy and unlink" strategy.