Docker ist eine Open-Source-Anwendungscontainer-Engine, die es Entwicklern ermöglicht, ihre Anwendungen und Abhängigkeiten in einen tragbaren Container zu packen und sie dann auf jeder gängigen Linux-Maschine zu veröffentlichen, die auch virtualisiert werden kann. In diesem Artikel wird hauptsächlich die erweiterte Version des Docker-Datenvolumens vorgestellt. Ich teile ihn mit Ihnen und hoffe, dass er für Sie hilfreich ist.
Warum braucht man ein Datenvolumen?
Dies muss mit dem Dateisystem des Docker-Containers beginnen. Aus einer Reihe von Gründen, beispielsweise aus Effizienzgründen, ist die Art und Weise, wie das Dateisystem des Docker-Containers auf dem Host existiert, sehr kompliziert, was zu folgenden Problemen führt:
kann nicht einfach gespeichert werden Auf dem Host bequem auf Dateien in Containern zugreifen.
Daten können nicht zwischen mehreren Containern ausgetauscht werden.
Wenn der Container gelöscht wird, gehen die im Container generierten Daten verloren.
Um diese Probleme zu lösen, hat Docker den Datenvolumenmechanismus (Volume) eingeführt. Ein Datenvolumen ist eine bestimmte Datei oder ein bestimmter Ordner, der in einem oder mehreren Containern vorhanden ist. Diese Datei oder dieser Ordner ist unabhängig vom Docker-Dateisystem auf dem Host-Computer vorhanden. Die größte Besonderheit eines Datenvolumens besteht darin, dass sein Lebenszyklus unabhängig vom Lebenszyklus des Containers ist.
Das beste Szenario für die Nutzung von Datenmengen
Daten zwischen mehreren Containern teilen. Mehrere Container können dieselbe Datei gleichzeitig im Lese- oder Lese-/Schreibmodus bereitstellen Zeit. Ein Datenvolumen zum Teilen der Daten im Datenvolumen.
Wenn der Host nicht garantieren kann, dass ein bestimmtes Verzeichnis oder Dateien mit festen Pfaden vorhanden sein müssen, können die durch diese Einschränkung verursachten Probleme durch die Verwendung von Datenvolumes umgangen werden.
Wenn Sie die Daten im Container außerhalb des Hosts speichern möchten, z. B. auf einem Remote-Host oder Cloud-Speicher.
Wenn Sie Containerdaten zwischen verschiedenen Hosts sichern, wiederherstellen oder migrieren müssen, sind Datenvolumes eine gute Wahl.
Docker-Volume-Unterbefehl
Docker stellt speziell den Volume-Unterbefehl zum Betreiben von Datenvolumes bereit:
create erstellt ein Datenvolume
inspect zeigt Details zu Datenvolumes an
ls listet alle Datenvolumes auf
prune löscht alle nicht verwendeten Volumes mit der Option -f
rm löscht ein oder mehrere nicht verwendete Volumes mit der Option -f
Erst erstellen Erstellen Sie ein Daten-Volume mit dem Namen „hello“ und zeigen Sie es mit dem Befehl „ls“ an:
Anschließend können Sie den Befehl „inspect“ verwenden, um die Details zum Daten-Volume „hello“ anzuzeigen:
Hier können wir sehen, wann das Datenvolumen erstellt wurde. Der von diesem Datenvolumen verwendete Treiber ist standardmäßig „lokal“, was bedeutet, dass das Datenvolumen den lokalen Speicher des Hosts verwendet Der Punkt des Datenvolumens ist standardmäßig ein Verzeichnis unter dem lokalen /var/lib/docker/volumes.
Schließlich können wir den Befehl rm oder prune verwenden, um das Datenvolumen zu löschen. Später wird der Autor einige Vorgehensweisen im Zusammenhang mit dem Löschen von Datenvolumen im tatsächlichen Gebrauch vorstellen.
Verwenden Sie die Mount-Syntax zum Mounten von Datenvolumes
Bevor wir die Option --volume(-v) zum Mounten von Datenvolumes verwendet haben, bietet Docker jetzt eine leistungsfähigere - - Mount-Option zum Verwalten von Datenmengen. Die Mount-Option kann über mehrere durch Kommas getrennte Schlüssel-Wert-Paare mehrere Konfigurationselemente gleichzeitig bereitstellen, sodass die Mount-Option eine detailliertere Konfiguration bereitstellen kann als die Volume-Option. Die übliche
-Konfiguration mit der Mount-Option lautet wie folgt:
type gibt die Mount-Methode an. Tatsächlich sind hier auch bind und tmpfs verfügbar.
volume-driver gibt den Treiber zum Mounten des Datenvolumens an. Der Standardwert ist lokal.
Quelle gibt die Quelle des Mounts an. Bei einem benannten Daten-Volume sollte hier der Name des Daten-Volumes angegeben werden. Wenn Sie es verwenden, können Sie „source“ schreiben oder es als „src“ abkürzen.
Ziel gibt den Pfad der bereitgestellten Daten im Container an. Sie können bei der Verwendung „destination“ schreiben oder es als „dst“ oder „target“ abkürzen.
readonly gibt an, dass die bereitgestellten Daten schreibgeschützt sind.
volume-opt kann mehrfach angegeben werden, um mehr mountbezogene Konfigurationen zu verbessern.
Sehen wir uns ein konkretes Beispiel an:
$ docker volume create hello $ docker run -id --mount type=volume,source=hello,target=/world ubuntu /bin/bash
Wir haben ein Datenvolumen mit dem Namen „hello“ erstellt und es dann auf /world im Container „Inhaltsverzeichnis“ gemountet. Verwenden Sie den Befehl „inspect“, um die „Mounts“-Informationen in den Containerdetails anzuzeigen und die tatsächlichen Ergebnisse der Datenvolume-Montage zu überprüfen:
Volume-Treiber verwenden, um Daten an anderer Stelle zu speichern
Zusätzlich zur standardmäßigen Speicherung der Daten im Daten-Volume auf dem Host ermöglicht uns Docker auch die Speicherung der Daten im Daten-Volume an anderen Orten, wie z. B. Azrue Storge oder AWS, durch Angabe von Lautstärke-Treiber.
简单起见,我们接下来的 demo 演示如何通过 vieux/sshfs 驱动把数据卷的存储在其它的主机上。
docker 默认是不安装 vieux/sshfs 插件的,我们可以通过下面的命令进行安装:
$ docker plugin install --grant-all-permissions vieux/sshfs
然后通过 vieux/sshfs 驱动创建数据卷,并指定远程主机的登录用户名、密码和数据存放目录:
docker volume create --driver vieux/sshfs \ -o sshcmd=nick@10.32.2.134:/home/nick/sshvolume \ -o password=yourpassword \ mysshvolume
注意,请确保你指定的远程主机上的挂载点目录是存在的(demo 中是 /home/nick/sshvolume 目录),否则在启动容器时会报错。
最后在启动容器时指定挂载这个数据卷:
docker run -id \ --name testcon \ --mount type=volume,volume-driver=vieux/sshfs,source=mysshvolume,target=/world \ ubuntu /bin/bash
这就搞定了,你在容器中 /world 目录下操作的文件都存储在远程主机的 /home/nick/sshvolume 目录中。进入容器 testcon 然后在 /world 目录中创建一个文件,然后打开远程主机的 /home/nick/sshvolume 目录进行查看,你新建的文件是不是已经出现在那里了!
数据卷原理
下图描述了 docker 容器挂载数据的三种方式:
数据卷是完全被 docker 管理的,就像上图中的黄色区域描述的一样,docker 在宿主机的文件系统中找了个文件管理数据卷相关的数据。因此你可能根本不需要知道数据卷文件在宿主机上的存储位置(事实上抱着刨根问底的精神我们还是很想搞清楚它背后的工作原理!)。
docker 数据卷的本质是容器中的一个特殊目录。在容器创建的过程中,docker 会将宿主机上的指定目录(一个以数据卷 ID 为名称的目录)挂载到容器中指定的目录上。这里使用的挂载方式为绑定挂载(bind mount),所以挂载完成后的宿主机目录和容器内的目标目录表现一致。
比如我们执行下面的命令创建数据卷 hello,并挂载到容器 testcon 的 /world 目录:
$ docker volume create hello $ docker run -id --name testcon --mount type=volume,source=hello,target=/world ubuntu /bin/bash
实际上在容器的创建过程中,类似于在容器中执行了下面的代码:
// 将数据卷 hello 在宿主机上的目录绑定挂载到 rootfs 中指定的挂载点 /world 上 mount("/var/lib/docker/volumes/hello/_data", "rootfs/world", "none", MS_BIND, NULL)
在处理完所有的 mount 操作之后(真正需要 docker 容器挂载的除了数据卷目录还包括 rootfs,init-layer 里的内容,/proc 设备等),docker 只需要通过 chdir 和 pivot_root 切换进程的根目录到 rootfs 中,这样容器内部进程就只能看见以 rootfs 为根的文件系统以及被 mount 到 rootfs 之下的各项目录了。例如我们启动的 testcon 中的文件系统为:
下面我们介绍几个数据卷在使用中比较常见的问题。
数据的覆盖问题
如果挂载一个空的数据卷到容器中的一个非空目录中,那么这个目录下的文件会被复制到数据卷中。
如果挂载一个非空的数据卷到容器中的一个目录中,那么容器中的目录中会显示数据卷中的数据。如果原来容器中的目录中有数据,那么这些原始数据会被隐藏掉。
这两个规则都非常重要,灵活利用第一个规则可以帮助我们初始化数据卷中的内容。掌握第二个规则可以保证挂载数据卷后的数据总是你期望的结果。
在 Dockerfile 中添加数据卷
在 Dockerfile 中我们可以使用 VOLUME 指令向容器添加数据卷:
VOLUME /data
在使用 docker build 命令生成镜像并且以该镜像启动容器时会挂载一个数据卷到 /data 目录。根据我们已知的数据覆盖规则,如果镜像中存在 /data 目录,这个目录中的内容将全部被复制到宿主机中对应的目录中,并且根据容器中的文件设置合适的权限和所有者。
注意,VOLUME 指令不能挂载主机中指定的目录。这是为了保证 Dockerfile 的可一致性,因为不能保证所有的宿主机都有对应的目录。
在实际的使用中,这里还有一个陷阱需要大家注意:在 Dockerfile 中使用 VOLUME 指令之后的代码,如果尝试对这个数据卷进行修改,这些修改都不会生效!下面是一个这样的例子:
FROM ubuntu RUN useradd nick VOLUME /data RUN touch /data/test.txt RUN chown -R nick:nick /data
通过这个 Dockerfile 创建镜像并启动容器后,该容器中存在用户 nick,并且能够看到 /data 目录挂载的数据卷。但是 /data 目录内并没有文件 test.txt,更别说 test.txt 文件的所有者属性了。要解释这个现象需要我们了解通过 Dockerfile 创建镜像的过程:
Dockerfile 中除了 FROM 指令的每一行都是基于上一行生成的临时镜像运行一个容器,执行一条指令并执行类似 docker commit 的命令得到一个新的镜像。这条类似 docker commit 的命令不会对挂载的数据卷进行保存。
所以上面的 Dockerfile 最后两行执行时,都会在一个临时的容器上挂载 /data,并对这个临时的数据卷进行操作,但是这一行指令执行并提交后,这个临时的数据卷并没有被保存。因而我们最终通过镜像创建的容器所挂载的数据卷是没有被最后两条指令操作过的。我们姑且叫它 "Dockerfile 中数据卷的初始化问题"。
下面的写法可以解决 Dockerfile 中数据卷的初始化问题:
FROM ubuntu RUN useradd nick RUN mkdir /data && touch /data/test.txt RUN chown -R nick:nick /data VOLUME /data
通过这个 Dockerfile 创建镜像并启动容器后,数据卷的初始化是符合预期的。这是由于在挂载数据卷时,/data 已经存在,/data 中的文件以及它们的权限和所有者设置会被复制到数据卷中。
还有另外一种方法可以解决 Dockerfile 中数据卷的初始化问题。就是利用 CMD 指令和 ENTRYPOINT 指令的执行特点:与 RUN 指令在镜像构建过程中执行不同,CMD 指令和 ENTRYPOINT 指令是在容器启动时执行。因此使用下面的 Dockerfile 也可以达到对数据卷的初始化目的:
FROM ubuntu RUN useradd nick VOLUME /data CMD touch /data/test.txt && chown -R nick:nick /data && /bin/bash
总结
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家支持php中文网。
Das obige ist der detaillierte Inhalt vonErweitertes Kapitel zum Docker-Datenvolumen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!