使用volumes

卷是保存Docker容器生成和使用的数据的首选机制。mount binds依赖于主机的目录结构,而卷完全由Docker管理。卷绑定安装有几个优点:

  • 与绑定装入相比,卷更易于备份或迁移。
  • 您可以使用Docker CLI命令或Docker API管理卷。
  • 卷适用于Linux和Windows容器。
  • 可以在多个容器之间更安全地共享卷。
  • 卷驱动程序允许您在远程主机或云提供程序上存储卷,加密卷的内容或添加其他功能。
  • 新卷可以通过容器预先填充其内容。

此外,卷通常是用在容器的可写层中持久数据更好的选择,因为卷不会增加使用它的容器的大小,并且卷的内容存在于给定容器的生命周期之外。

如果容器生成非持久状态数据,请考虑使用 tmpfs挂载以避免将数据永久存储在任何位置,并通过避免写入容器的可写层来提高容器的性能。

卷使用rprivate绑定传播,并且卷不可配置绑定传播。

选择-v或--mount标志

最初,-v或者--volume标志用于独立容器,--mount标志用于群集服务。但是,从Docker 17.06开始,您还可以使用--mount挂载独立容器。一般来说, --mount更明确和冗长。最大的区别在于-v 语法将所有选项组合在一个字段中,而--mount 语法将它们分开。以下是每个标志的语法比较。

新用户应该尝试--mount--volume语法更简单的语法。

如果需要指定卷驱动程序选项,则必须使用--mount

  • -v--volume:由三个字段组成,用冒号字符(:)分隔。字段必须按正确的顺序排列,并且每个字段的含义不是很明显。

    • 对于命名卷,第一个字段是卷的名称,并且在给定主机上是唯一的。对于匿名卷,省略第一个字段。
    • 第二个字段是文件或目录在容器中安装的路径。
    • 第三个字段是可选的,是逗号分隔的选项列表,例如ro。这些选项将在下面讨论。
  • --mount:由多个键值对组成,以逗号分隔,每个键<key>=<value>组由一个元组组成。--mount语法比-v--volume更详细的,但键的顺序并不明显,并且标志的键值更容易理解。
    • 类型挂载,其可以是bindvolume,或 tmpfs。本主题讨论卷,因此类型始终是 volume
    • source挂载方式。对于命名卷,值是卷的名称。对于匿名卷,省略此字段。可以指定为source 或src
    • destination将挂载在容器中的文件或目录路径作为其值。可以指定为destinationdsttarget
    • readonly选项(如果存在)导致绑定装入以只读方式装入容器中
    • volume-opt选项可以多次指定,它采用由选项名称及其值组成的键值对。

转义外部CSV解析器的值

如果您的卷驱动程序接受以逗号分隔的列表作为选项,则必须从外部CSV解析器中转义该值。要转义一个 volume-opt,用双引号括起来(")并用单引号括起整个mount参数(')。

例如,local驱动程序接受mount选项作为o参数中以逗号分隔的列表。此示例显示了转义列表的正确方法。

$ docker service create \
--mount 'type=volume,src=<VOLUME-NAME>,dst=<CONTAINER-PATH>,volume-driver=local,volume-opt=type=nfs,volume-opt=device=<nfs-server>:<nfs-path>,"volume-opt=o=addr=<nfs-address>,vers=4,soft,timeo=180,bg,tcp,rw"'
--name myservice \
<IMAGE>

下面的示例首先给出 --mount语法,并给出了--mount-v语法

-v--mount行为之间的差异

与绑定挂载相反,卷的所有选项都可用于--mount 标记和-v标记。

使用具有服务的卷时,仅--mount支持。

创建和管理卷

与bind mounts不同,您可以创建和管理任何容器范围之外的卷。

创建一个卷

[root@benjamincloud ~]# docker volume create my-vol
my-vol

列出卷:

[root@benjamincloud ~]# docker volume ls
DRIVER VOLUME NAME
local my-vol

检查卷:

[root@benjamincloud ~]# docker volume inspect my-vol
[
{
"CreatedAt": "2018-08-21T13:36:33+08:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/my-vol/_data",
"Name": "my-vol",
"Options": {},
"Scope": "local"
}
]

删除卷:

[root@benjamincloud ~]# docker volume rm my-vol
my-vol

启动具有卷的容器

如果启动具有尚不存在的卷的容器,Docker会为您创建卷。以下示例将卷myvol2装入 /app/容器中。

所述-v--mount以下实验产生相同的结果。只有在删除第一个容器和卷才能执行下一个testdev,否则不能同时运行它们。

--mount 方式:

[root@benjamincloud ~]# docker run -d --name devtest --mount source=myvol2,target=/app nginx:latest
c7e40bded7d029a9523bd8e0aa145741509c81dff54780adfd4e79aba5d92eb8

使用docker inspect devtest验证创建卷并安装正确。寻找Mounts部分:

这表明mount是一个卷,它显示正确的源和目标,并且mount是可读写的。

停止容器并移除卷。注意删除卷是一个单独的步骤。

[root@benjamincloud ~]# docker stop devtest
devtest
[root@benjamincloud ~]# docker rm devtest
devtest
[root@benjamincloud ~]# docker volume rm myvol2
myvol2

使用 -v or  --volume 的方式:

[root@benjamincloud ~]# docker run -d --name devtest -v myvol2:/app nginx:latest
27ecdae2edc59bcd7521ec257913fb70586d49aa014e45240a7c468289ac7849

使用docker inspect devtest验证创建卷并安装正确。寻找Mounts部分:

结果是和 --mount 挂载方式是一致的。

停止删除容器,删除卷

使用卷启动服务

启动服务并定义卷时,每个服务容器都使用自己的本地卷。如果使用local 卷驱动程序,则所有容器都不能共享此数据,但某些卷驱动程序确实支持共享存储。Docker for AWS和Docker for Azure都使用Cloudstor插件支持持久存储。

以下示例启动nginx具有四个副本的服务,每个副本使用一个名为的本地卷myvol2

[root@benjamincloud ~]# docker service create -d --replicas= --name dev-test-service --mount src=myvol2,dst=/app nginx:latest

使用docker service ps devtest-service验证服务正在运行:

删除服务,停止其所有任务:

[root@benjamincloud ~]# docker service rm dev-test-service
dev-test-service

删除服务不会删除该服务创建的任何卷。去除卷是一个单独的步骤。

[root@benjamincloud ~]# docker volume rm myvol2
myvol2

服务的语法差异

docker service create命令不支持-v--volume标志。将卷安装到服务的容器中时,必须使用该--mount 标志。

使用容器填充卷

如果启动一个创建新卷的容器(如上所述),并且容器在要挂载的目录中具有文件或目录(/app/如上所述),则将目录的内容复制到卷中。然后容器安装并使用该卷,而使用该卷的其他容器也可以访问预先填充的内容。

为了说明这一点,此示例启动一个nginx容器,并nginx-vol使用容器/usr/share/nginx/html目录的内容 填充新卷,这是Nginx存储其默认HTML内容的位置。

这些--mount-v示例具有相同的最终结果。

--mount 方式:

[root@benjamincloud ~]# docker run -d --name nginxtest --mount source=nginx-vol,target=/usr/share/nginx/html nginx:latest

停止删除容器,删除卷之后演示 -v 或者--volume 方式

[root@benjamincloud _data]# docker stop nginxtest
nginxtest
[root@benjamincloud _data]# docker rm nginxtest
nginxtest

[root@benjamincloud _data]# docker volume rm nginx-vol
 nginx-vo

 

-v --volume 方式:

[root@benjamincloud _data]# docker run -d --name nginx --volume nginx-vol:/usr/share/nginx/html nginx:latest
728cf9b2d7a0b3bc563e11767c09b188d8fcfc19098d238aa123788458b0f24c

使用 docker inspect nginxtest 查看mount 数据

},
"Mounts": [
{
"Type": "volume",
"Name": "nginx-vol",
"Source": "/var/lib/docker/volumes/nginx-vol/_data",
"Destination": "/usr/share/nginx/html",
"Driver": "local",
"Mode": "z",
"RW": true,
"Propagation": ""
}
],
root@benjamincloud ~]#  cd  /var/lib/docker/volumes/nginx-vol/_data
[root@benjamincloud _data]# ls
50x.html index.html

两种标志的挂载  达到的效果是一致的。

使用只读卷

对于某些开发应用程序,容器需要写入bind mounts,以便将更改传播回Docker主机。在其他时候,容器只需要对数据的读访问权。请记住,多个容器可以安装相同的卷,并且可以为其中一些容器以读写方式挂载,同时为其他容器以只读方式挂载。

此示例修改上面的一个,但通过在容器中的挂载点之后添加 ro(默认为空)选项列表,将目录挂载为只读卷。如果存在多个选项,请用逗号分隔。

这些--mount-v示例具有相同的结果。

[root@benjamincloud ~]# docker run -d --name nginx-test --mount source=nginx-vol,target=/usr/share/nginx/html,readonly nginx:latest
85848e9a91176323ed8ee954c4663bf039889037648b360e374822b71cd0a487
[root@benjamincloud ~]# docker run -d --name nginx-test --volume nginx-vol:/usr/share/nginx/html:ro nginx:latest
9e314ab6058c968c39ae713367dfb87e9ef6bac7706e32168cf40bcb143c2f80

停止并取出容器,然后取出卷。去除卷是一个单独的步骤。

$ docker container stop nginxtest

$ docker container rm nginxtest

$ docker volume rm nginx-vol

在机器之间共享数据

构建容错应用程序时,可能需要配置同一服务的多个副本才能访问相同的文件。

在开发应用程序时,有几种方法可以实现此目的。一种是为应用程序添加逻辑,以将文件存储在Amazon S3等云对象存储系统上。另一种方法是使用支持将文件写入NFS或Amazon S3等外部存储系统的驱动程序创建卷。

卷驱动程序允许您从应用程序逻辑中抽象底层存储系统。例如,如果您的服务使用具有NFS驱动程序的卷,则可以更新服务以使用其他驱动程序,例如在云中存储数据,而无需更改应用程序逻辑。

使用volume驱动程序

使用创建卷时docker volume create,或者启动使用尚未创建的卷的容器时,可以指定卷驱动程序。以下示例使用vieux/sshfs卷驱动程序,首先在创建独立卷时使用,然后在启动创建新卷的容器时使用。

初始设置

此示例假定您有两个节点,第一个节点是Docker主机,可以使用SSH连接到第二个节点。

在Docker主机上,安装vieux/sshfs插件:

[root@benjamincloud ~]# docker plugin install --grant-all-permissions vieux/sshfs
latest: Pulling from vieux/sshfs
52d435ada6a4: Download complete
Digest: sha256:1d3c3e42c12138da5ef7873b97f7f32cf99fb6edde75fa4f0bcf9ed277855811
Status: Downloaded newer image for vieux/sshfs:latest
Installed plugin vieux/sshfs

使用卷驱动程序创建卷

此示例指定SSH密码,但如果两台主机配置了共享密钥,则可以省略密码。每个卷驱动程序可以具有零个或多个可配置选项,每个选项都使用-o标志指定。

[root@benjamincloud ~]# docker volume create --driver vieux/sshfs -o sshcmd=test@node2:/home/test -o password=testpassword sshvolume
sshvolume

启动使用卷驱动程序创建卷的容器

此示例指定SSH密码,但如果两台主机配置了共享密钥,则可以省略密码。每个卷驱动程序可以具有零个或多个可配置选项。如果卷驱动程序要求您传递选项,则必须使用该--mount标志来装入卷,而不是-v

$ docker run -d \
--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

备份,还原或迁移数据卷

卷对备份,还原和迁移很有用。使用该 --volumes-from标志创建一个安装该卷的新容器

备份容器

例如,在下一个命令中,我们:

  • 启动新容器并从dbstore容器装入卷
  • 挂载本地主机目录为 /backup
  • 将/dbdata 目录下的数据备份到 /backup/backup.tar。
[root@benjamincloud ~]#  docker run -v /dbdata --name dbstore ubuntu
[root@benjamincloud ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c4674f6fb834 ubuntu "/bin/bash" seconds ago Exited () seconds ago dbstore
[root@benjamincloud ~]# docker run --rm --volumes-from dbstore -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata
tar: Removing leading `/' from member names
/dbdata/

容器 /dbdata 的数据被备份到 docker主机的当前目录

从备份还原容器

使用刚刚创建的备份,您可以将其还原到同一容器或您在其他位置创建的另一个容器。

例如,创建一个名为的新容器dbstore2

[root@benjamincloud ~]# docker run -v /dbdata --name dbstore2 ubuntu /bin/bash

然后解压缩新容器的数据卷中的备份文件:

root@benjamincloud ~]# docker run --rm --volumes-from dbstore2 -v $(pwd):/backup ubuntu bash -c "cd /dbdata && tar xvf /backup/backup.tar --strip 1"

--strip 命令脱掉外衣,去掉一些符号文件

删除卷

删除容器后,Docker数据卷仍然存在。要考虑两种类型的卷:

  • 例如,命名卷在容器外部具有特定的源表单awesome:/bar
  • 匿名卷没有特定的源,因此在删除容器时,指示Docker Engine守护进程删除它们。

删除匿名卷

要自动删除匿名卷,请使用该--rm选项。例如,此命令创建匿名/foo卷。移除容器后,Docker Engine会删除/foo卷但不会删除awesome卷。

删除所有卷

要删除所有未使用的卷并释放空间:

docker从零开始 存储(二)volumes 挂载的更多相关文章

  1. docker从零开始 存储(五)存储驱动介绍

    关于存储驱动程序 要有效地使用存储驱动程序,了解Docker如何构建和存储镜像以及容器如何使用这些镜像非常重要.您可以使用此信息做出明智的选择,以确定从应用程序中保留数据的最佳方法,并避免在此过程中出 ...

  2. docker从零开始 存储(四)tmpfs挂载

    使用tmpfs挂载 volume和bind mounts允许您在主机和容器之间共享文件,以便即使在容器停止后也可以保留数据. 如果你在Linux上运行Docker,你有第三个选择:tmpfs moun ...

  3. docker从零开始 存储(三)bind mounts

    使用bind mounts 自Docker早期以来bind mounts 一直存在.与volumes相比,绑定挂载具有有限的功能.使用bind mounts时,主机上的文件或目录将装入容器中.文件或目 ...

  4. docker从零开始 存储(一)存储概述

    管理Docker中的数据 默认情况下,在容器内创建的所有文件都存储在可写容器层中.这意味着: 当该容器不再运行时,数据不会持久存在,如果另一个进程需要,则可能很难从容器中获取数据. 容器的可写层紧密耦 ...

  5. docker从零开始 存储(六)存储驱动如何选择

    Docker存储驱动程序 理想情况下,将非常少的数据写入容器的可写层,并使用Docker卷来写入数据.但是,某些工作负载要求您能够写入容器的可写层.这是存储驱动程序的用武之地. Docker使用可插拔 ...

  6. docker从零开始(二)容器初体验

    使用定义容器 Dockerfile Dockerfile定义容器内所需要的环境.对网络接口和磁盘驱动器等资源的访问在此环境中进行虚拟化,该环境与系统的其他部分隔离,因此您需要将端口映射到外部世界,并具 ...

  7. Docker 持久存储介绍(十三)

    目录 一.Docker 数据存储 二.Bind mount 1.详细介绍 2.如何使用 -v or --volume 语法 --mount 语法 两者区别 3.使用场景 4.使用案例 存在目录 bin ...

  8. Centos7——docker持久化存储和卷间状态共享(笔记)

    docker持久化存储和卷间状态共享(笔记)  本章介绍 存储卷的介绍 存储卷的两种类型 宿主机好额容器之间如何共享数据 容器之间如何共享数据 存储卷的声明周期 存储卷之间的数据管理和控制模式 就像在 ...

  9. 四个修改Docker默认存储位置的方法

    方法一.软链接 默认情况下Docker的存放位置为:/var/lib/docker 可以通过下面命令查看具体位置: sudo docker info | grep "Docker Root ...

随机推荐

  1. cocos2d-x环境搭建 摘自百度文库

    cocos2d-x环境搭建 引言:笔者在网上寻觅了很多资料,最终发现了这份实际可用的文档,供大家参考.源地址:http://wenku.baidu.com/view/93f7b0f1102de2bd9 ...

  2. centos tomcat开机自启

    在 /etc/rc.local 下 输入tomcat bin目录下的startup.sh  /usr/tomcat8/bin/startup.sh 即可

  3. No node available for block: blk

    刚才利用hadoop和mahout运行kmean是算法,一开始利用了10个节点,一个master,9个slave,运行了7分钟,我为了看速度的变化,就改用伪分布的形式,但是一开始运行就报错了: 17/ ...

  4. 第四次JAVA作业

    public class TvbDog { public static void main(String[] args) {  Dog per=new Dog("陈狗"," ...

  5. CodeForces Round #521 (Div.3) E. Thematic Contests

    http://codeforces.com/contest/1077/problem/E output standard output Polycarp has prepared nn competi ...

  6. capacilitys docker中的权限设置 privileged

    capacilities是docker 中对docker权限设置的重要方面: http://blog.csdn.net/wangpengqi/article/details/9821227 上面这篇文 ...

  7. RadioGroup和GroupBox有什么区别?

    我在RadioGroup中放RadioButton和GroupBox中一样,搞不明白. radiogroup有个item属性都是radio控件,不需要拖控件上去.groupbox需要自己拖控件 分组的 ...

  8. LeetCode -- Tiangle

    Question: Given a triangle, find the minimum path sum from top to bottom. Each step you may move to ...

  9. poj3375 Network Connection

    Description There are \(M\) network interfaces in the wall of aisle of library. And \(N\) computers ...

  10. 一个acm过来人的心得

    刻苦的训练我打算最后稍微提一下.主要说后者:什么是有效地训练? 我想说下我的理解.        很多ACMer入门的时候,都被告知:要多做题,做个500多道就变牛了.其实,这既不是充分条件.也不会是 ...