Les systèmes de fichiers superposés (également appelés systèmes de fichiers d’union) sont une technologie fondamentale de Docker pour créer des images et des conteneurs. Ils permettent de créer une union de répertoires pour créer un système de fichiers. Plusieurs systèmes de fichiers, qui ne sont que des répertoires, sont superposés les uns sur les autres pour créer un nouveau système de fichiers. Ces répertoires sont appelés couches et le processus d’unification est appelé montage d’union. Si deux fichiers avec le même chemin existent dans deux couches, seul le dernier fichier apparaîtra dans le système de fichiers superposé.
Nous apprendrons comment créer nous-mêmes un système de fichiers superposé et comment Docker l’utilise pour créer des images et exécuter des conteneurs.
Créer un système de fichiers superposé est facile
Le système de fichiers superposé est constitué de deux types de système de fichiers. Un ou plus plus bas systèmes de fichiers immuables. Leur contenu est uniquement lu et aucune modification n’interviendra à l’intérieur. Une plus haut Le système de fichiers reçoit toutes les modifications du système de fichiers superposé, y compris les créations, modifications et suppressions de fichiers.
La création d’un système de fichiers superposé est facile une fois que vous avez mis la main dessus. Tout ce dont vous avez besoin pour une machine Linux avec un accès root ou sudoer. Une machine virtuelle fera l’affaire.
Nous initialisons la mise en page en créant plusieurs dossiers, chacun d’eux correspondant à un calque. Nous avons également besoin d’un mount
dossier à l’endroit où nous voulons que le système de fichiers superposé soit créé et un workdir
dossier à des fins internes.
mkdir overlay; cd overlay
mkdir \
lower-layer-1 lower-layer-2 lower-layer-3 upper-layer \
mount \
workdir
Créons également des fichiers dans 3 dossiers. Nous laissons le dossier supérieur vide.
echo "Content layer 1" > ./lower-layer-1/file-in-layer-1
echo "Content layer 2" > ./lower-layer-2/file-in-layer-2
echo "Content layer 3" > ./lower-layer-3/file-in-layer-3
Deux répertoires ou plus sont requis. Ils font une liste de répertoires inférieurs et un répertoire supérieur. Les répertoires inférieurs du système de fichiers sont en lecture seule, tandis que le répertoire supérieur peut être utilisé à la fois pour les lectures et les écritures. La mount
La commande crée le système de fichiers superposé avec le type externe -t
mis à overlay
. Il doit être exécuté comme root
.
sudo mount -t overlay my-overlay \
-o lowerdir=$HOME/overlay/lower-layer-1:$HOME/overlay/lower-layer-2:$HOME/overlay/lower-layer-3,upperdir=$HOME/overlay/upper-layer,workdir=$HOME/overlay/workdir \
$HOME/overlay/mount
La df
La commande répertorie tous les systèmes de fichiers ainsi que des informations utiles telles que la quantité d’espace libre et le type de système de fichiers lorsqu’il est exécuté avec la commande -T
Drapeau. La -h
flag n’est là que pour imprimer la taille du système de fichiers dans un format lisible par l’homme.
df -Th | grep overlay
my-overlay overlay 20G 5.5G 14G 29% /home/ubuntu/overlay/mount
Le système de fichiers superposé est créé et monté à l’intérieur du mount
dossier. Il contient les fichiers de tous les systèmes de fichiers d’origine.
ls -l mount
total 12
-rw-rw-r-- 1 ubuntu ubuntu 13 Jun 2 22:38 file-in-layer-1
-rw-rw-r-- 1 ubuntu ubuntu 13 Jun 2 22:38 file-in-layer-2
-rw-rw-r-- 1 ubuntu ubuntu 13 Jun 2 22:38 file-in-layer-3
cat mount/file-in-layer-3
Content layer 3
Essayons de créer un fichier dans le dossier de montage :
echo "new content" > mount/new-file
Il est écrit dans le répertoire supérieur, upper-layer
:
tree
.
├── lower-layer-1
│ └── file-in-layer-1
├── lower-layer-2
│ └── file-in-layer-2
├── lower-layer-3
│ └── file-in-layer-3
├── mount
│ ├── new-file
│ ├── file-in-layer-1
│ ├── file-in-layer-2
│ └── file-in-layer-3
├── upper-layer
│ └── new-file
└── workdir
└── work [error opening dir]
7 directories, 8 files
Maintenant, nous modifions un fichier, par exemple, file-in-layer-1
.
echo 'Add a new line' >> mount/file-in-layer-1
Le fichier original présent à l’intérieur lower-layer-1
n’est pas modifié. Au lieu de cela, un nouveau fichier dans upper-layer
est créé:
cat lower-layer-1/file-in-layer-1
Content layer 1
cat upper-layer/file-in-layer-1
Content layer 1
Add a new line
cat mount/file-in-layer-1
Content layer 1
Add a new line
Voyons le comportement lors de la suppression d’un fichier, par exemple, file-in-layer-2
.
Le fichier original à l’intérieur lower-layer-2
est toujours là. Un nouveau dossier dans upper-layer
est créé avec un type spécial, c’est un fichier de caractères. C’est ainsi que le système de fichiers superposé représente un fichier supprimé.
ls -l lower-layer-2/file-in-layer-2
-rw-rw-r-- 1 ubuntu ubuntu 13 Jun 2 22:38 lower-layer-2/file-in-layer-2
ls -l upper-layer/file-in-layer-2
c--------- 1 root root 0, 0 Jun 2 23:33 upper-layer/file-in-layer-2
Maintenant que le laboratoire est terminé, nous pouvons démonter le système de fichiers et purger nos fichiers.
sudo umount $HOME/overlay/mount
ls -l mount/
total 0
cd ..
rm -rf overlay
Superposition dans Docker
Docker prend en charge plusieurs pilotes de stockage pour écrire des données sur la couche inscriptible d’un conteneur, SuperpositionFS est le pilote de stockage recommandé. Si vous imprimez les informations à partir de votre installation Docker locale, il est probable qu’elle imprime le overlay2
pilote de stockage.
docker info | grep "Storage Driver"
Storage Driver: overlay2
Docker utilise le système de fichiers de superposition pour créer des images ainsi que pour positionner la couche de conteneur au-dessus des couches d’image.
Lorsqu’une image est téléchargée, ses calques sont situés à l’intérieur du /var/lib/docker/overlay2
dossier. Par exemple, télécharger une image à 3 couches en utilisant docker pull ubuntu
crée 3+1 répertoires. La l
Le répertoire contient des identifiants de couche raccourcis sous forme de liens symboliques.
docker pull ubuntu
Using default tag: latest
latest: Pulling from library/ubuntu
345e3491a907: Pull complete
57671312ef6f: Pull complete
5e9250ddb7d0: Pull complete
Digest: sha256:adf73ca014822ad8237623d388cedf4d5346aa72c270c5acc01431cc93e18e2d
Status: Downloaded newer image for ubuntu:latest
docker.io/library/ubuntu:latest
Dans mon cas, 3 couches sont téléchargées :
ls -l /var/lib/docker/overlay2/
total 16
drwx------ 4 root root 4096 Jun 3 11:21 289a71f4e07caadc95892ac5b4027606bb93c69d1a23d0e866818cdb1179644b/
drwx------ 4 root root 4096 Jun 3 11:21 40766b9f546e9826ff353976c167f60cb615f57c01926a607ab48a2df64806ab/
drwx------ 3 root root 4096 Jun 3 11:21 88826e8f5f21df691dbd998df70d94e1b6b480e489c4dbb5999dcc8a7367159e/
drwx------ 2 root root 4096 Jun 3 11:21 l/
ls -l /var/lib/docker/overlay2/l/
total 12
lrwxrwxrwx 1 root root 72 Jun 3 11:21 NSEHV6LZKQIRKICXA2T7T5252D -> ../88826e8f5f21df691dbd998df70d94e1b6b480e489c4dbb5999dcc8a7367159e/diff/
lrwxrwxrwx 1 root root 72 Jun 3 11:21 QPAIOX2SCZPFZIIXB27PFVHUPH -> ../40766b9f546e9826ff353976c167f60cb615f57c01926a607ab48a2df64806ab/diff/
lrwxrwxrwx 1 root root 72 Jun 3 11:21 USIDUBYHQEGWIRN4JOSF74ZWIL -> ../289a71f4e07caadc95892ac5b4027606bb93c69d1a23d0e866818cdb1179644b/diff/
Ces couches sont également exposées en inspectant l’image Docker. La sortie de la commande Docker est au format JSON. Nous utilisons jq pour filtrer la partie qui nous intéresse le plus.
docker image inspect ubuntu | jq -r '.[0] | Data: .GraphDriver.Data'
"Data":
"LowerDir": "/var/lib/docker/overlay2/40766b9f546e9826ff353976c167f60cb615f57c01926a607ab48a2df64806ab/diff:/var/lib/docker/overlay2/88826e8f5f21df691dbd998df70d94e1b6b480e489c4dbb5999dcc8a7367159e/diff",
"MergedDir": "/var/lib/docker/overlay2/289a71f4e07caadc95892ac5b4027606bb93c69d1a23d0e866818cdb1179644b/merged",
"UpperDir": "/var/lib/docker/overlay2/289a71f4e07caadc95892ac5b4027606bb93c69d1a23d0e866818cdb1179644b/diff",
"WorkDir": "/var/lib/docker/overlay2/289a71f4e07caadc95892ac5b4027606bb93c69d1a23d0e866818cdb1179644b/work"
L’ordre de priorité commence par le répertoire supérieur, puis évalue les répertoires inférieurs de gauche à droite. Ainsi, les couches sont évaluées dans cet ordre :
1: 88826e8f5f21df691dbd998df70d94e1b6b480e489c4dbb5999dcc8a7367159e
2: 40766b9f546e9826ff353976c167f60cb615f57c01926a607ab48a2df64806ab
3: 289a71f4e07caadc95892ac5b4027606bb93c69d1a23d0e866818cdb1179644b
En commençant par la première couche à évaluer, son contenu est le système de fichiers Ubuntu :
ls /var/lib/docker/overlay2/88826e8f5f21df691dbd998df70d94e1b6b480e489c4dbb5999dcc8a7367159e/diff
bin boot dev etc home lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys tmp usr var
À partir de là, les répertoires supplémentaires de la deuxième couche :
tree /var/lib/docker/overlay2/40766b9f546e9826ff353976c167f60cb615f57c01926a607ab48a2df64806ab/diff/
├── etc
│ ├── apt
│ │ └── apt.conf.d
│ │ ├── docker-autoremove-suggests
│ │ ├── docker-clean
│ │ ├── docker-gzip-indexes
│ │ └── docker-no-languages
│ └── dpkg
│ └── dpkg.cfg.d
│ └── docker-apt-speedup
├── usr
│ └── sbin
│ ├── initctl
│ └── policy-rc.d
└── var
└── lib
└── dpkg
├── diversions
└── diversions-old
10 directories, 9 files
Et la troisième couche aussi :
tree /var/lib/docker/overlay2/289a71f4e07caadc95892ac5b4027606bb93c69d1a23d0e866818cdb1179644b/diff/
/var/lib/docker/overlay2/289a71f4e07caadc95892ac5b4027606bb93c69d1a23d0e866818cdb1179644b/diff/
└── run
└── systemd
└── container
2 directories, 1 file
Les instructions de création des couches sont définies dans le Dockerfile. La curl
commande télécharger le fichier Dockerfile.
curl https://raw.githubusercontent.com/tianon/docker-brew-ubuntu-core/c5bc8f61f0e0a8aa3780a8dc3a09ae6558693117/focal/Dockerfile
Par défaut, il imprime le contenu sur la console.
FROM scratch
ADD ubuntu-focal-core-cloudimg-amd64-root.tar.gz /
RUN set -xe \ \ && echo '#!/bin/sh' > /usr/sbin/policy-rc.d \ && echo 'exit 101' >> /usr/sbin/policy-rc.d \ && chmod +x /usr/sbin/policy-rc.d \ \ && dpkg-divert --local --rename --add /sbin/initctl \ && cp -a /usr/sbin/policy-rc.d /sbin/initctl \ && sed -i 's/^exit.*/exit 0/' /sbin/initctl \ \ && echo 'force-unsafe-io' > /etc/dpkg/dpkg.cfg.d/docker-apt-speedup \ \ && echo 'DPkg::Post-Invoke true"; ;' > /etc/apt/apt.conf.d/docker-clean \ && echo 'APT::Update::Post-Invoke ;' >> /etc/apt/apt.conf.d/docker-clean \ && echo 'Dir::Cache::pkgcache ""; Dir::Cache::srcpkgcache "";' >> /etc/apt/apt.conf.d/docker-clean \ \ && echo 'Acquire::Languages "none";' > /etc/apt/apt.conf.d/docker-no-languages \ \ && echo 'Acquire::GzipIndexes "true"; Acquire::CompressionTypes::Order:: "gz";' > /etc/apt/apt.conf.d/docker-gzip-indexes \ \ && echo 'Apt::AutoRemove::SuggestsImportant "false";' > /etc/apt/apt.conf.d/docker-autoremove-suggests
RUN [ -z "$(apt-get indextargets)" ]
RUN mkdir -p /run/systemd && echo 'docker' > /run/systemd/container
CMD ["/bin/bash"]CMD hello
La ADD
créé la première couche. La première RUN
La commande a créé la deuxième couche. La deuxième RUN
n’a créé aucun calque car aucun fichier n’a été créé. Le troisième RUN
La commande a créé la troisième couche. La CMD
La commande n’a créé aucune couche car elle est évaluée au moment de l’exécution lorsque le conteneur est créé à partir de l’image.
Conclusion
Une fois que nous avons compris le fonctionnement des systèmes de fichiers superposés, il est assez facile de voir comment Docker a utilisé le système de fichiers superposé dans son Dockerfile avec une mise en cache supplémentaire entre chaque couche. Il se combine facilement avec le chroot jail
pour fournir un système de fichiers isolé au conteneur au-dessus des systèmes de fichiers immuables des couches d’image. La distribution d’images consiste simplement à combiner plusieurs images ensemble comme tar
archive.
More Stories
Test des écouteurs Jabra Elite 5 ANC : superbe design, bon son
La filiale londonienne du CWU dit aux ingénieurs de BT de rejeter l’offre de rémunération
Revue du générateur solaire Jackery Explorer 1500 : la protection contre les pannes de courant à son meilleur