©
本文档使用 PHP中文网手册 发布
卷是持久化由 Docker 容器生成和使用的数据的首选机制。虽然绑定挂载依赖于主机的目录结构,但卷由 Docker 完全管理。与绑定安装相比,卷有几个优点:
与绑定挂载相比,卷更容易备份或迁移。
您可以使用 Docker CLI 命令或 Docker API 管理卷。
卷在 Linux 和 Windows 容器上均可使用。
卷可以在多个容器之间更安全地共享。
卷驱动程序允许您在远程主机或云提供程序上存储卷,加密卷的内容或添加其他功能。
新卷的内容可以由容器预先填充。
另外,与使容器的可写入层中的数据持久化相比,卷通常是更好的选择,因为使用卷不会增加使用容器的容器的大小,并且容器的内容存在于给定容器的生命周期之外。
如果您的容器生成非持久状态数据,请考虑使用 tmpfs 挂载以避免将数据永久存储在任何地方,并通过避免写入容器的可写层来提高容器的性能。
卷使用rprivate
绑定传播,并且卷的传播不可配置。
最初,-v
或--volume
用标志独立的容器和--mount
用于群服务标志。但是,从 Docker 17.06 开始,您也可以使用--mount
独立容器。一般来说,--mount
更明确和详细。最大的区别在于,-v
语法将所有选项组合在一个字段中,而--mount
语法将它们分开。这是每个标志的语法比较。
提示:新用户应使用
--mount
语法。有经验的用户可能更熟悉这个语法-v
或--volume
语法,但鼓励使用--mount
,因为研究表明它更易于使用。
如果您需要指定音量驱动程序选项,则必须使用--mount
。
-v
或者 --volume
:由三个由冒号(:
)分隔的字段组成。这些字段必须按正确的顺序排列,每个字段的含义并不明显。
对于命名卷,第一个字段是卷的名称,并且在给定主机上是唯一的。对于匿名卷,第一个字段被省略。
第二个字段是文件或目录将被安装在容器中的路径。
第三个字段是可选的,并且是逗号分隔的选项列表,例如ro
。这些选项在下面讨论。
--mount
:由多个键值对组成,由逗号分隔,每个由一个<key>=<value>
元组组成。该--mount
语法比更详细的-v
或--volume
,但按键的顺序并不显著,并且标志的价值更容易理解。
该type
安装件,其可以是bind
,volume
,或tmpfs
。本主题讨论卷,所以类型将始终如此volume
。
该source
安装的。对于命名卷,这是卷的名称。对于匿名卷,该字段被省略。可能被指定为source
或src
。
的destination
作为其值,其中的文件或目录将被安装在容器的路径。可以指定为destination
,dst
或target
。
该readonly
选项(如果存在)将导致绑定挂载以只读方式挂载到容器中。
volume-opt
可以多次指定的选项采用由选项名称和值组成的键值对。
以下示例在可能的地方显示了语法--mount
和-v
语法,并--mount
首先给出。
-v
与--mount
行为之间的差异与绑定挂载相反,卷的所有选项都可用于标志--mount
和-v
标志。
将卷与服务一起使用时,仅--mount
支持。
与绑定挂载不同,您可以创建和管理任何容器范围之外的卷。
创建一个卷:
$ docker volume create my-vol
清单卷:
$ docker volume ls local my-vol
检查卷:
$ docker volume inspect my-vol[ { "Driver": "local", "Labels": {}, "Mountpoint": "/var/lib/docker/volumes/my-vol/_data", "Name": "my-vol", "Options": {}, "Scope": "local" }]
删除卷:
$ docker volume rm my-vol
如果您启动的卷尚未存在的容器,Docker 将为您创建卷。以下示例将卷myvol2
装入/app/
容器中。
所述-v
和--mount
以下实施例产生相同的结果。除非在运行第一个devtest
容器和容器myvol2
之后移除容器和容量,否则无法运行它们。
--mount
-v
$ docker run -d \ -it \ --name devtest \ --mount source=myvol2,target=/app \ nginx:latest
$ docker run -d \ -it \ --name devtest \ -v myvol2:/app \ nginx:latest
使用docker inspect devtest
验证创建卷并安装正确。寻找Mounts
部分:
"Mounts": [ { "Type": "volume", "Name": "myvol2", "Source": "/var/lib/docker/volumes/myvol2/_data", "Destination": "/app", "Driver": "local", "Mode": "", "RW": true, "Propagation": "" }],
这表明挂载是一个卷,它显示正确的源和目标,并且挂载是可读写的。
停止容器并移除卷。
$ docker container stop devtest $ docker container rm devtest $ docker volume rm myvol2
当您启动服务并定义一个卷时,每个服务容器将使用其自己的本地卷。如果使用local
卷驱动程序,则任何容器都不能共享此数据,但某些卷驱动程序确实支持共享存储。AWS 的 Docker 和 Azure 的 Docker 都使用 Cloudstor 插件支持持久存储。
以下示例启动一个nginx
具有四个副本的服务,每个副本使用一个称为的本地卷myvol2
。
$ docker service create -d \ --name devtest-service \ --mount source=myvol2,target=/app \ nginx:latest
使用docker service ps devtest-service
验证服务正在运行:
$ docker service ps devtest-service ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS 4d7oz1j85wwn devtest-service.1 nginx:latest moby Running Running 14 seconds ago
删除停止所有任务的服务:
$ docker service rm devtest-service
docker service create
命令不支持-v
或--volume
标志。将卷安装到服务的容器中时,必须使用该--mount
标志。
如果您启动一个创建新卷的容器(如上所述),并且容器在要装载的目录中具有文件或目录(/app/
如上所述),则该目录的内容将被复制到卷中。然后容器将安装并使用该卷,并且使用该卷的其他容器也将有权访问预填充的内容。
为了说明这一点,这个例子启动一个nginx
容器,并nginx-vol
用容器/usr/share/nginx/html
目录的内容填充新卷,这是 Nginx 存储其默认 HTML 内容的地方。
这个例子--mount
和-v
最后的结果是一样的。
--mount
-v
$ docker run -d \ -it \ --name=nginxtest \ --mount source=nginx-vol,destination=/usr/share/nginx/html \ nginx:latest
$ docker run -d \ -it \ --name=nginxtest \ -v nginx-vol:/usr/share/nginx/html \ nginx:latest
运行这些示例之一后,运行以下命令来清理容器和卷。
$ docker container stop nginxtest $ docker container rm nginxtest $ docker volume rm nginx-vol
对于某些开发应用程序,容器能够写入绑定安装非常有用,以便将更改传播回Docker主机。在其他时候,容器应该只能读取数据而不能修改它。请记住,多个容器可以安装相同的卷,并且可以同时对它们中的某些容器进行读写安装,也可以对其他容器进行只读。
这个例子修改了上面的例子,但是通过ro
在容器中的挂载点之后添加选项列表(默认为空),将目录挂载为只读卷。如果存在多个选项,请用逗号分隔它们。
在--mount
和-v
实例有同样的结果。
--mount
-v
$ docker run -d \ -it \ --name=nginxtest \ --mount source=nginx-vol,destination=/usr/share/nginx/html,readonly \ nginx:latest
$ docker run -d \ -it \ --name=nginxtest \ -v nginx-vol:/usr/share/nginx/html:ro \ nginx:latest
使用docker inspect nginxtest
验证绑定安装正确创建。寻找Mounts
部分:
"Mounts": [ { "Type": "volume", "Name": "nginx-vol", "Source": "/var/lib/docker/volumes/nginx-vol/_data", "Destination": "/usr/share/nginx/html", "Driver": "local", "Mode": "", "RW": false, "Propagation": "" }],
停止并移除容器,然后移除该容器:
$ docker container stop nginxtest $ docker container rm nginxtest $ docker volume rm nginx-vol
当您使用创建卷docker volume create
或启动使用尚未创建的卷的容器时,可以指定卷驱动程序。以下示例vieux/sshfs
首先在创建独立卷时使用卷驱动程序,然后在启动将创建新卷的容器时使用卷驱动程序。
此示例假定您有两个节点,其中第一个是 Docker 主机,可以使用 SSH 连接到第二个节点。
在 Docker 主机上安装vieux/sshfs
插件:
$ docker plugin install --grant-all-permissions vieux/sshfs
本示例指定了一个 SSH 密码,但如果两台主机配置了共享密钥,则可以省略该密码。每个卷驱动器可能有零个或多个可配置选项,每个选项都使用一个-o
标志来指定。
$ docker volume create --driver vieux/sshfs \ -o sshcmd=test@node2:/home/test \ -o password=testpassword \ sshvolume
本示例指定了一个 SSH 密码,但如果两台主机配置了共享密钥,则可以省略该密码。每个卷驱动可能有零个或多个可配置选项。如果卷驱动程序要求您传递选项,则必须使用此--mount
标志挂载卷,而不是-v
**。**
$ docker run -d \ --it \ --name sshfs-container \ --volume-driver vieux/sshfs \ --mount src=sshvolume,target=/app,volume-opt=sshcmd=test@node2:/home/test,volume-opt=password=testpassword \ nginx:latest
了解绑定挂载。
了解 tmpfs 挂载。
了解存储驱动程序。