Dieser Artikel bringt Ihnen einige Probleme im Zusammenhang mit Image Layering, Container Layering und dem von Containern belegten Speicherplatz in Docker näher. Ich hoffe, dass er Ihnen hilfreich sein wird.
dokcer wendet die Idee der hierarchischen Wiederverwendung bei der Organisation von Speicherinhalten geschickt an. Wir können dies also als Beispiel verwenden, um diese Idee zu lernen.
Ein Docker-Image wird während des Erstellungsprozesses in viele Ebenen unterteilt, und jede Ebene ist schreibgeschützt. Lassen Sie uns das anhand des folgenden Beispiels veranschaulichen:
# 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
Diese Docker-Datei enthält 4 Anweisungen, die das Dateisystem ändern und eine neue Ebene erstellen.
FROM
erstellt die Basisebene aus dem Ubuntu:18.04-Image. 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
LABEL
Der Befehl ändert nur die Metadaten des Bildes und erstellt keine neue Ebene.
COPY
Der Befehl fügt den Inhalt des aktuellen Verzeichnisses, in dem dieser Build ausgeführt wird, zum Image hinzu und erstellt eine neue Ebene, um die Änderungen aufzuzeichnen. Der erste RUN
-Befehl erstellt das Programm und gibt die Ergebnisse an das Bild aus. Es wird eine neue Ebene erstellt, um die Änderungen aufzuzeichnen. Der zweite RUN
-Befehl löscht das Cache-Verzeichnis und erstellt eine neue Ebene, um die Änderungen aufzuzeichnen.
CMD
-Anweisung definiert die im Container auszuführenden Anweisungen. Sie ändert nur die Metadaten des Bildes und erstellt keine neue Ebene. Hier erfasst jede Ebene nur die Unterschiede zur vorherigen Ebene. Wenn wir einen Container erstellen, wird eine beschreibbare Ebene erstellt, die auch Containerebene genannt wird. In dieser Ebene werden Änderungen am Inhalt laufender Container aufgezeichnet. Die folgende Abbildung beschreibt die Beziehung:
🎜2 .Container-Layering🎜🎜🎜Der Hauptunterschied zwischen Containern und Bildern besteht in der beschreibbaren Ebene der obersten Ebene. Wenn der Container gelöscht wird, wird auch die beschreibbare Ebene gelöscht Das Bild bleibt erhalten. 🎜🎜🎜Hinweis🎜: Wenn Sie möchten, dass mehrere Container dieselben Daten gemeinsam nutzen, können Sie dies über Docker Volumes tun. 🎜🎜Jeder Container verfügt über eine eigene beschreibbare Ebene, in der alle Transformationen gespeichert werden, sodass mehrere Container dasselbe Bild teilen können. Die folgende Abbildung beschreibt die Beziehung: 🎜🎜🎜🎜🎜Hinweis 🎜: Hier gibt es noch ein weiteres Detail. Wenn beispielsweise zwei Bilder dieselbe Ebene haben und diese beim Erstellen oder Ziehen lokal vorhanden ist, wird sie nicht erneut erstellt oder gezogen. Daher können Sie bei der Berechnung der Bildgröße nicht einfach die vom Befehldocker images
angezeigte Größe addieren. Der Wert kann größer als der tatsächliche Wert sein. 🎜🎜🎜3. Der vom Container belegte Speicherplatz auf der Festplatte🎜🎜🎜Mit dem Befehl docker ps -s
können Sie den vom laufenden Container belegten Speicherplatz anzeigen (Teilwert). Die unterschiedlichen Inhalte werden durch die beiden Spalten dargestellt: 🎜🎜🎜Größe: Die von der beschreibbaren Ebene des Containers belegte Festplattengröße 🎜Virtuelle Größe: Enthält die Größe der beschreibbaren Ebene und des schreibgeschützten Bilds des Containers. 🎜Andere Arten, wie Container Speicherplatz belegen: 🎜🎜🎜Von Containern generierte Protokolldateien. 🎜Inhalte werden mithilfe von Volume- und Bind-Mounts bereitgestellt. 🎜Container-Konfigurationsdatei🎜Inhalte im Speicher (wenn das Auslagern aktiviert ist)🎜Prüfpunkte (wenn diese Funktion verwendet wird)🎜🎜4.Copy -on -Write (CoW)-Strategie 🎜🎜🎜Die Speichertreiber in Docker übernehmen alle diese Strategie. 🎜🎜CoW-Strategie kann Dateien mit maximaler Effizienz teilen und kopieren. Wenn eine Datei in einer unteren Ebene des Bildes vorhanden ist, muss ihre obere Ebene (einschließlich der beschreibbaren Ebene) den Inhalt lesen und kann die Datei direkt verwenden. Wenn eine Änderung erforderlich ist, wird die Datei auf diese Ebene kopiert und geändert. Dies minimiert IO und die Größe jeder nachfolgenden Schicht. 🎜docker pull
verwenden, um das Bild abzurufen oder einen Container mit einem Bild zu erstellen, das lokal nicht verfügbar ist, wird das Bild kleiner geteilt Die Ebene wird im lokalen Dockers-Speicherbereich gespeichert. Unter Linux ist es normalerweise /var/lib/docker
. 🎜🎜Wir können zum Verzeichnis /var/lib/docker/<storage-driver></storage-driver>
gehen, um zu sehen, dass wir die Bilder jeder Ebene abgerufen haben. Verwenden Sie beispielsweise den Speichertreiber overlay2
. 🎜🎜🎜🎜Mit so vielen Schichten können wir bestehenDocker Image Inspect, um zu sehen, welche Ebenen ein bestimmtes Bild enthält viel Der Speicherplatz zum Speichern von Bildern erhöht auch die Geschwindigkeit beim Abrufen von Bildern. 🎜我们可以通过 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视频教程》
Das obige ist der detaillierte Inhalt vonSie können die Idee der mehrschichtigen Wiederverwendung mit Docker in zehn Minuten erlernen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!