跟陈sir一起玩转docker卷 一

docker volume 详解

卷是持久化由Docker容器生成和使用的数据的首选机制。虽然绑定挂载依赖于主机的目录结构,但卷完全由Docker管理。与绑定挂载相比,卷有几个优点:

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

另外,与使容器的可写层保存数据相比,容量通常是一个更好的选择,因为使用容量不会增加使用容器的容器的大小,而容器的内容存在于给定容器的生命周期之外。


types-of-mounts-volume.png

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

卷使用rprivate绑定传播,并且绑定传播对于卷来说是不可配置的。

选择 -v or –mount 标志

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

提示:新用户应该使用--mount语法。有经验的用户可能更熟悉-v或--volume语法,但是鼓励使用--mount,因为研究表明它更易于使用。

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

  • - v或- volume:由三个字段组成,由冒号分隔(:)。字段必须按照正确的顺序书写,并且每个字段的含义都不是立刻确定。

    • 在命名卷的情况下,第一个字段是卷的名称,在给定的主机上是惟一的。对于匿名卷,省略了第一个字段。
    • 第二个字段是在容器中安装文件或目录的路径。
    • 第三个字段是可选的,并且是一个逗号分隔的选项列表,如ro。下面讨论这些选项。
  • --mount:由多个键-值对组成,由逗号分隔,每一对由< key>= <value> tuple(元组)组成。--mount 语法比- v或—volume 更详细,其中键对的顺序并不重要,而且标记的值更容易理解。

    • 挂载的类型(type),可以是绑定(bind)、卷(volume)或tmpfs。本主题讨论卷,因此类型将始终是卷。
    • 挂载源(source)。对于命名卷,是卷的名称。对于匿名卷,该字段被省略。可以指定为source 或src。
    • 挂在目标(destination)的值是将文件或目录安装在容器中的路径。可以指定为destination、dst或target。
    • 如果存在readonly选项,则将绑定挂载安装到容器中作为只读。
    • 可以使用键值对多次指定的volume-opt选项.

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

与绑定挂载相反,所有的卷的选项对于 --mount 和 -v 标志 都可以使用。
当卷(volume)作为服务时,只支持--mount。

创建和管理卷

与绑定挂载(bind 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 中。

--mount

$ docker run -d \
  -it \
  --name devtest \
  --mount source=myvol2,target=/app \
  nginx:latest

-v

$ docker run -d \
  -it \
  --name devtest \
  -v myvol2:/app \
  nginx:latest

使用docker inspect devtest来验证卷的创建和挂载是否正确。查找 mount 部分:

"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

服务中使用卷

当您启动一个服务并定义一个卷时,每个服务容器将使用它自己的本地卷。如果您使用本地卷驱动程序,则没有一个容器可以共享这些数据,但是一些卷驱动程序确实支持共享存储。AWS的Docker和Azure的Docker都支持使用Cloudstor插件的持久性存储。
下面的示例启动一个带有四个副本的nginx服务,每个副本使用一个名为myvol2的本地卷。

$ docker service create -d \
  --replicas=4 \
  --name devtest-service \
  --mount source=myvol2,target=/app \
  nginx:lates

使用docker service ps devtest来验证服务是否正在运行:

$ 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服务创建命令不支持 - v或 --volume 语法。当将卷安装到服务的容器时,必须使用 --mount 语法

将容器原本的内容放到卷中

如果您启动一个容器,该容器创建一个新卷,如上所述,容器中包含的文件与目录正好与要挂载的卷中的目录一致(例如上面例子中的/app /),容器中的目录中的内容将被复制到卷中。然后容器将装入并使用卷,而使用此卷的其他容器也可以访问这些被copy的内容。

为了说明这一点,这个示例启动一个nginx容器,并将新卷nginx - vol填充到容器/ usr/share/nginx/html目录的内容中,这是nginx存储其默认HTML内容的地方。

The --mount and -v examples have the same end result.

$ 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

只读卷

对于一些开发中的应用,将数据写入卷中,并体现到宿主机上是非常有用的。另一方面,对于另一些应用,只允许读取卷中的内容则更加合适。毕竟一个卷可以被多个容器挂在,其中一些是读写方式,另一些是只读方式。
例子,注意mount option 使用逗号隔开

$ 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": [
    {
        "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

使用volume driver

当您使用 docker volume create 创建卷,或者当您创建一个容器,并与一个尚未创建的卷关联时,您可以使用volume driver

Initial set-up

这个例子假设您有两个节点,第一个节点是Docker主机,可以使用SSH连接到第二个节点。
在Docker主机上安装vieux/sshfs插件:

$ docker plugin install --grant-all-permissions vieux/sshfs

创建带volume driver 的卷

示例指定了SSH密码,但如果两个主机配置了免密码登陆(公钥免密),则可以忽略密码。每个卷驱动程序可能有零个或多个可配置选项,每个选项都使用- o标志指定。

$ docker volume create --driver vieux/sshfs \
  -o sshcmd=test@node2:/home/test \
  -o password=testpassword \
  sshvolume

创建容器时使用volume driver

如果卷驱动程序要求您传递选项,您必须使用- 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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容

  • 转载自 http://blog.opskumu.com/docker.html 一、Docker 简介 Docke...
    极客圈阅读 10,468评论 0 120
  • Docker — 云时代的程序分发方式 要说最近一年云计算业界有什么大事件?Google Compute Engi...
    ahohoho阅读 15,505评论 15 147
  • 五、Docker 端口映射 无论如何,这些 ip 是基于本地系统的并且容器的端口非本地主机是访问不到的。此外,除了...
    R_X阅读 1,734评论 0 7
  • 我爱 与你的缘 随天 你去 我送你到门口 不留 不愁 你来 无论春秋冬夏 我出门相迎 煮最好的茶 奉敬 我爱 来 ...
    烺叶之声阅读 277评论 1 0
  • 《再见了,可鲁》讲的是一只狗的一生。 看完才发现作者根本就没有和可鲁接触过,仅仅是在可鲁离开后才开始采访进行创作,...
    seike13阅读 470评论 0 2