volumes是保存Docker容器生成和使用的数据的首选机制。bind mounts依赖于主机的目录结构,而卷则完全由Docker管理。卷比bind mounts有几个优点:
个人觉得volume就像是给bind mount模式起了个名字,并且作为一个整体被Docker管理。
具体操作一下,卷的创建方式有很多种,比如直接使用:
docker volume create my-vol
或是在容器启动时使用-v
docker run -d --name test01 -v my-vol2:/app nginx:latest
还可以使用–mount
docker run -d --name test02 --mount src=my-vol3,target=/app nginx:latest
这里简单解释一下-v、-mount的参数含义。
-v 后面可以跟三个值,分别用“:”冒号隔开,当然–volume和-v是一样的。
-mount 后跟若干个key=val,也就是键值对,用","逗号隔开。分别有如下一些key:
我们还可以使用:docker volume ls
查看列表,使用:docker inspect my-vol3
查看详情。
[
{
"CreatedAt": "2018-11-22T04:22:37-05:00", # 卷的创建时间
"Driver": "local", # 卷的驱动
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/my-vol3/_data", # 卷在文件系统的存储位置
"Name": "my-vol3", # 卷名
"Options": null,
"Scope": "local"
}
]
删除volume:docker volume rm my-vol3
,这里注意,删除volume之前删除使用了该volume的容器。
当然也可以在同主机中的容器之间共享volume,做个简单的示例。
启动俩个nginx容器,使用同一个volume,volume在容器中的挂载位置是:/usr/share/nginx/html
这个位置是Nginx默认存储HTML的文件夹。
启动第一个Nginx容器:
docker run -d --name nginx01 -p 10080:80 -v nginx-vol:/usr/share/nginx/html nginx:latest
启动成功后我们到nginx-vol卷的目录下修改index.html内容,删除body中
以外的全部内容,访问Nginx首页:Welcome to nginx!
再启动第二个容器:
docker run -d --name nginx02 -p 10081:80 -v nginx-vol:/usr/share/nginx/html nginx:latest
访问首页:
没有修改第二个容器,它使用了我在第一个容器中修改后的首页。
同主机下的容器共享volume实现还是比较简单,接下来搞一下不同主机下的容器共享volume。
这里需要改变volume driver了,不能使用之前的local。
官方文档中的例子使用的是vieux/sshfs
,这里先安装一下插件
docker plugin install --grant-all-permissions vieux/sshfs
这里我们启动俩个机器,ip分别是:
前面的内容都是在192.168.1.164这台主机上操作的,这里我继续使用之前创建的nginx01容器,启动容器并查看一下容器的Mounts:
Source是nginx-vol卷在文件系统中的存储位置,待会会用到。
切换到192.168.1.130主机,之前的插件只需要安装在这台主机上,同样运行一个nginx容器,但这里要使用vieux/sshfs
驱动创建卷:
docker run -d --name nginx-sshvol \
-p 10080:80 \
--mount src=sshvol,target=/usr/share/nginx/html,type=volume,volume-driver=vieux/sshfs,[email protected]:/var/lib/docker/volumes/nginx-vol/_data,volume-opt=password=**** \
nginx:latest
启动成功后访问192.168.1.130:10080,不出意外的话应该和之前一样,页面只有一个欢迎标题。可实际显示的是403,Bug可能会迟到,但永远不会缺席。
查看容器启动日志:
[root@localhost ~]# docker logs nginx-sshvol
192.168.1.157 - - [23/Nov/2018:02:29:17 +0000] "GET / HTTP/1.1" 403 571 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36" "-"
2018/11/23 02:29:17 [error] 6#6: *1 "/usr/share/nginx/html/index.html" is forbidden (13: Permission denied), client: 192.168.1.157, server: localhost, request: "GET / HTTP/1.1", host: "192.168.1.130:10080"
2018/11/23 02:29:17 [error] 6#6: *1 open() "/usr/share/nginx/html/favicon.ico" failed (13: Permission denied), client: 192.168.1.157, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "192.168.1.130:10080", referrer: "http://192.168.1.130:10080/"
192.168.1.157 - - [23/Nov/2018:02:29:17 +0000] "GET /favicon.ico HTTP/1.1" 403 571 "http://192.168.1.130:10080/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36" "-"
这是一个很常见的Nginx权限不足问题,我们将nginx.conf配置中的user改为root即可。由于容器中没有vi命令,我们用docker cp
命令将nginx.conf复制到宿主机中,修改后同样使用docker cp
再给它覆盖回去。
复制配置到宿主机:docker cp nginx-sshvol:/etc/nginx/nginx.conf ./nginx.conf
覆盖容器中的配置:docker cp ./nginx.conf nginx-sshvol:/etc/nginx/nginx.conf