Maison > Article > Opération et maintenance > Vous pouvez apprendre l'idée de la réutilisation en couches avec Docker en dix minutes
Cet article vous apporte quelques problèmes liés à la superposition d'images, à la superposition de conteneurs et à l'espace disque occupé par les conteneurs dans Docker. J'espère qu'il vous sera utile.
dokcer applique intelligemment l'idée de réutilisation hiérarchique lors de l'organisation du contenu de stockage. Nous pouvons donc utiliser cela comme cas pour apprendre cette idée.
Une image Docker est divisée en plusieurs couches pendant le processus de construction, et chaque couche est en lecture seule. Illustrons avec l'exemple suivant :
# syntax=docker/dockerfile:1 FROM ubuntu:18.04 LABEL org.opencontainers.image.authors="org@example.com" COPY . /app RUN make /app RUN rm -r $HOME/.cache CMD python /app/app.py
Il y aura 4 instructions dans ce Dockerfile qui changeront le système de fichiers et créeront un nouveau calque.
FROM
crée la couche de base à partir de l'image ubuntu:18.04. FROM
指令从ubuntu:18.04的镜像中创建了基础层。LABEL
指令仅仅修改了镜像的元数据,不会创建新层。COPY
指令将执行本次构建的当前目录中的内容添加到镜像当中,会创建一个新层记录改变。RUN
指令,构建了程序并将结果输出到镜像中,会创建一个新层记录改变。RUN
指令,删除了缓存目录,会创建一个新层记录改变。CMD
指令定义了容器中运行的指令,只是修改了镜像的元数据,并不会创建新层。这里每层都只记录与其上一层的不同。当我们创建一个容器的时候,这是就会创建一层可写层,也叫容器层。对于正在运行中的容器的内容的变化都会记录在该层中。下图描述了该关系:
容器和镜像的不同主要是最顶层的可写层的不同,所有对于容器的写操作都会记录在这层中,如果容器被删除,那么这个可写层也会被删除,但是镜像会被保留。
注意:如果想要多个容器共享相同的数据,可以通过Docker Volumes实现。
每个容器都有其自己的可写层,所有的变换都会被存放在其中,所以多个容器可共享同一个镜像。下图描述了该关系:
注意 :此处还有个细节,多个镜像可能共用相同的层,比如两个镜像中有相同的层,那么在构建或是拉取的时候发现本地以存在,则不会再次构建或拉取。所以计算镜像大小的时候,不能仅通过 docker images
命令显示出的大小来汇总求和,该值有可能大于实际值。
可以通过 docker ps -s
命令,来看正在运行中的容器占用的空间(部分值)。两个列的不同代表的内容:
容器占用磁盘空间的其它途径:
Docker中的存储驱动都是采用该策略。
CoW策略能够最大效率的共享和复制文件。如果一个文件在镜像的更低层存在,那么其上层(包括可写层)需要读取该内容则可以直接使用该文件。当需要对其进行修改时,会复制该文件到该层并进行修改。这最大限度的减少了IO和每个后续层的大小。
当我们使用 docker pull
拉取镜像或是使用一个本地没有的镜像创建容器的时候,该镜像会被分层的存储到本地Dockers存储区域中。在linux中通常是 /var/lib/docker
。
我们可以去 /var/lib/docker/<storage-driver></storage-driver>
目录下看我们已拉取各层镜像。比如使用 overlay2
存储驱动。
这么多层,我们可以通过 docker image inspect
La commande LABEL
modifie uniquement les métadonnées de l'image et ne crée pas de nouveau calque.
COPY
La commande ajoute le contenu du répertoire actuel où cette construction est exécutée à l'image et crée un nouveau calque pour enregistrer les modifications. La première commande RUN
construit le programme et affiche les résultats sur l'image. Elle créera un nouveau calque pour enregistrer les modifications. La deuxième commande RUN
supprime le répertoire de cache et crée une nouvelle couche pour enregistrer les modifications.
CMD
définit les instructions à exécuter dans le conteneur. Elle modifie uniquement les métadonnées de l'image et ne crée pas de nouveau calque. Ici, chaque calque enregistre uniquement les différences par rapport au calque précédent. Lorsque nous créons un conteneur, une couche inscriptible est créée, également appelée couche conteneur. Les modifications apportées au contenu des conteneurs en cours d'exécution sont enregistrées dans cette couche. La figure suivante décrit la relation :
🎜2 .Superposition de conteneurs🎜🎜🎜La principale différence entre les conteneurs et les images est la couche inscriptible de niveau supérieur. Toutes les opérations d'écriture sur le conteneur seront enregistrées dans cette couche, si le conteneur est supprimé, la couche inscriptible sera également supprimée, mais. l'image sera conservée. 🎜🎜🎜Remarque🎜 : Si vous souhaitez que plusieurs conteneurs partagent les mêmes données, vous pouvez le faire via Docker Volumes. 🎜🎜Chaque conteneur possède son propre calque inscriptible, où toutes les transformations seront stockées, afin que plusieurs conteneurs puissent partager la même image. La figure suivante décrit la relation : 🎜🎜🎜🎜🎜Remarque 🎜 : Il y a un autre détail ici. Plusieurs images peuvent partager le même calque. Par exemple, si deux images ont le même calque, s'il existe localement lors de la construction ou de l'extraction, il ne sera pas construit ou extrait à nouveau. Par conséquent, lors du calcul de la taille de l'image, vous ne pouvez pas simplement résumer la taille affichée par la commandedocker images
. La valeur peut être supérieure à la valeur réelle. 🎜🎜🎜3. L'espace occupé par le conteneur sur le disque🎜🎜🎜Vous pouvez utiliser la commande docker ps -s
pour voir l'espace occupé par le conteneur en cours d'exécution (valeur partielle). Les différents contenus représentés par les deux colonnes : 🎜🎜🎜size : La taille du disque occupée par la couche inscriptible du conteneur 🎜taille virtuelle : Contient la taille de la couche inscriptible du conteneur et l'image en lecture seule. 🎜Autres façons dont les conteneurs occupent l'espace disque : 🎜🎜🎜Fichiers journaux générés par les conteneurs. 🎜Contenu monté à l'aide des montages Volume et Bind. 🎜Fichier de configuration du conteneur🎜Contenu en mémoire (si l'échange est activé)🎜Points de contrôle (si cette fonction est utilisée)🎜🎜4.Copie -on -Stratégie d'écriture (CoW) 🎜🎜🎜Les pilotes de stockage dans Docker adoptent tous cette stratégie. 🎜🎜La stratégie CoW peut partager et copier des fichiers avec une efficacité maximale. Si un fichier existe dans une couche inférieure de l'image, alors sa couche supérieure (y compris la couche inscriptible) doit lire le contenu et peut utiliser le fichier directement. Lorsqu'il doit être modifié, le fichier est copié sur ce calque et modifié. Cela minimise les E/S et la taille de chaque couche suivante. 🎜docker pull
pour extraire l'image ou créer un conteneur en utilisant une image qui n'est pas disponible localement, l'image sera divisé La couche est stockée dans la zone de stockage Dockers locale. Sous Linux, il s'agit généralement de /var/lib/docker
. 🎜🎜Nous pouvons aller dans le répertoire /var/lib/docker/<storage-driver></storage-driver>
pour voir que nous avons extrait les images de chaque couche. Par exemple, utilisez le pilote de stockage overlay2
. 🎜🎜🎜🎜Avec autant de couches, nous pouvons réussirdocker image inspect pour voir quels calques une certaine image contient 🎜docker image inspect --format "{{json .RootFS.Layers}}" redis docker image inspect --format "{{json .RootFS.Layers}}" mysql:5.7🎜🎜🎜🎜🎜🎜🎜Grâce à la vue ci-dessus, nous pouvons voir que redis et mysql5.7 utilisent le même calque, partageant donc le même calque économise beaucoup L'espace de stockage des images augmente également la vitesse d'extraction des images. 🎜
我们可以通过 docker image history
命令来查看镜像分层情况,以redis为例
docker history redis
注意 :
有些步骤的大小为0,是因为他们只改变了元数据,并不会产生新层,也不会占用额外的空间(除元数据本身)。所以上述redis镜像中包含了5层。
<missing></missing>
步骤,这些步骤可能是以下情况中的一种
当我们启动一个容器的时候,会添加一个可写层在镜像之上,用于存储所有的变化。当对已有文件进行修改的时候采用CoW策略。首先会到各层寻找到该文件,然后复制该文件到可写层,然后进行修改并存储。
这么做能够让我们最大限度地减少I/O操作。
但是,很明显的是当一个容器中的应用需要进行频繁的写操作,那么会造成可写层越来越庞大,此时我们可以通过Volume来帮助我们分担压力。
容器的元数据和日志是单独存放的,一般是存放在 /var/lib/docker/containers
中,我们可以使用 du -sh /var/lib/docker/containers/*
来查看各个容器占用多少。(容器ID其实就是文件夹名称的前12位)。
推荐学习:《docker视频教程》
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!