文章目录
1.docker 数据卷管理
为什么用数据卷?
docker 分层文件系统性能差,生命周期与容器相同(容器删除,文件也丢失)
而 docker 数据卷是 mount 到宿主机中,绕开了分层文件系统,和主机磁盘性能相同,容器
删除后依然保留,但是仅限本地磁盘,不能随容器迁移
docker 官方提供两种卷:1.bind mount 2.docker managed volume
1.1.bind mount:将主机上的目录或文件直接 mount 到容器里,使用直接,高效
[root@server2 ~]# docker run -d --name web1 -p 80:80 -v /opt/website:/usr/share/nginx/html nginx ##容器里/usr/share/nginx/html 是 nginx
的默认发布目录
[root@server2 ~]# curl localhost
[root@server2 ~]# docker exec web1 mount ##在容器里执行 mount 命令
/dev/mapper/rhel-root on /usr/share/nginx/html type xfs
(rw,relatime,attr2,inode64,noquota) ##看到/dev/mapper/rhel-root,也就是我们的根
目录,挂接到容器的/usr/share/nginx/html
在宿主机 cd /opt/website 编辑页面
还可以在容器内修改
docker exec -it web1 bash
cd /usr/share/nginx/html
echo hahaha >> index.html
[root@server2 ~]# curl localhost #数据也已经更改,在容器内更改的数据其实就是宿主机上的数据
‘这种方式,不存在的目录会自动新建(无论容器还是宿主机),但是会以宿主机为准,绑定挂接到容器后,容器中的对应目录如果有数据,就会被覆盖’
1.1.1 bind mount 挂载时权限–.rw.ro
'bind mount 方式挂载时默认权限是 rw,可以在挂载时指定只读(ro)
[root@server2 ~]# docker run -it --name vm1 -v /opt/data1:/data1 -v /opt/data2:/data2:ro ubuntu #这些目录在宿主机和容器内都是没有的
在宿主机 cd /opt/data1 &/opt/data2上建立文件
1.1.2挂载 yum 源
[root@server1 ~]# docker run -it --name vm2 -v
/etc/yum.repos.d/dvd.repo:/etc/yum.repos.d/dvd.repo rhel7 bash ##要给一个bash
/etc/yum.repos.d/dvd.repo:/etc/yum.repos.d/dvd.repo:ro rhel7 bash ##加上只读
选项,让 yum 源不能被更改
1.2.docker managed volume(docker 管理卷)
bind mount 必须指定宿主机文件系统路径,移植性差(如果容器在 A 主机上 crash 掉,B
主机上如果没有对应路径,无法进行移植)
而 docker managed volume 不需要指定,docker 自动为容器创建,默认数据卷目录都在
/var/lib/docker/volumes
如果挂载时指向容器内已有的目录,原数据会被复制到 volume 中
[root@server1 ~]# docker run -d --name vm1 -p 80:80 -v /usr/share/nginx/html
nginx
[root@server1 ~]# curl localhost ##发现可以访问,看到 nginx 主页
[root@server1 ~]# docker inspect web1
可以重新命名
[root@server1 ~]# docker run -d --name web2 -p 80:80 -v website2:/usr/share/nginx/html nginx
[root@server1 ~]# curl localhost
[root@server1 ~]# docker inspect web2
重新run一个镜像 还是使用website2
[root@server1 ~]# docker volume rm
b29ea012d9b02b3fc410834c6da4d0bd4bca3e1cf4ae95e5b3bda71cfe0e85a1 #
删除
[root@server1 ~]# docker volume prune ##删除所有没有被容器使用的卷,如果容器较
多,一个一个删除麻烦
‘还可以使用这种方式让多个容器挂载同一个目录’ [root@server1 ~]# docker run -d --name web3 -v webdata:/usr/share/nginx/html
nginx #再新建一个容器,去掉端口映射
[root@server1 ~]# docker inspect web3
“IPAddress”: “172.17.0.3”
[root@server1 ~]# curl 172.17.0.3
www.westos.org
2.卷插件
docker 卷默认使用的是 local 类型的驱动,只能存在于宿主机,跨主机的 volume 就需要第
三方驱动
https://docs.docker.com/engine/extend/legacy_plugins/
docker 官方只提供了插件 api,开发者可以根据实际需求定制插件驱动
工作流程:docker engine(daemon) --> volume plugin --> storage platform;引
擎调用插件,插件操作存储
docker plugin 是以 web 服务的方式运行在 docker 主机上,是独立的
plugin 的启动和停止,并不依赖于 docker,docker daemon 依靠在默认路径下查找 unix
socket 文件来自动发现插件
当客户端与 daemon 交互并使用插件创将数据卷时,daemon 会在后端找到插件对应的
socket 文件,建立连接并发起相应的 API 请求,最终结合 daemon 自身的处理完成客户端请
求
2.1convoy 卷插件实践
2.1.1 NFS文件共享
底层存储支持三种模式:devicemapper、NFS、EBS(亚马逊的弹性化存储)
需要在所有 docker 节点提前挂载 NFS 存储
#server12和 server5都安装 nfs
[root@server2 ~]# yum install -y nfs-utils
[root@server2 ~]# systemctl start rpcbind
[root@server2 ~]# vim /etc/exports
/mnt/nfs*(rw,no_root_squash) ##root 在操作是不切换身份,默认会切换到 nfs 用户
[root@server2 ~]# mkdir /mnt/nfs
[root@server2 ~]# systemctl start nfs
[root@server2 ~]# exportfs -rv #输出共享目录
exporting *:/mnt/nfs
#在 server5上
[root@server5 ~]# mkdir /mnt/nfs
[root@server5 ~]# showmount -e 172.25.0.1
Export list for 172.25.0.1:
/mnt/nfs *
[root@server2 ~]# mount 172.25.0.1:/mnt/nfs /mnt/nfs #挂载
2.1.2配置 convoy
server1 和 server2 都获取 convoy 包并解压
[root@server1 ~]# tar zxf convoy.tar.gz
[root@server1 convoy]# cp convoy convoy-pdata_tools /usr/local/bin/
[root@server1 ~]# convoy --help
[root@server1 ~]# convoy daemon --drivers vfs --driver-opts vfs.path=/mnt/nfs &
[root@server1 ~]# mkdir /etc/docker/plugins ##插件目录,docker 程序默认会在这个
目录下查找 convoy 套接字
[root@server1 plugins]# echo “unix:///var/run/convoy/convoy.sock” > convoy.spec
##把 convoy.sock 文件路径写入 convoy.spec,必须以 spec 结尾,convoy 是插
件名
‘server2 上也做上面操作’
2.1.3创建卷
[root@server1 plugins]# convoy create vol1
列出当前有哪些卷
[root@server1 plugins]# convoy list #可以看到卷路径为/mnt/nfs/vol1,同时/mnt/nfs
下还会有一个 config 目录,里面的东西不要删除,否则客户端命令可能就用不了
[root@server2 ~]# docker run -it --name vm1 -v vol1:/data ubuntu##运行容器,挂
载到容器内的 data 目录
root@8580e0ab9bb3:/data# touch hounan
root@8580e0ab9bb3:/data# ls
file1 file10 file2 file3 file4 file5 file6 file7 file8 file9
[root@server1 ~]# ls /mnt/nfs/vol1/ #退出容器可以看到创建的文件在本地,在 server2
上也可以看到
hounan
#这个时候容器就算 crash 掉,数据也已经保存在了本地,可以随时迁移容器
[root@server2~]# docker rm -f vm1 #假设 vm1 挂了
[root@server5 ~]# docker run -it --name vm1 -v vol1:/data ubuntu##在 server2 上
恢复,这里不用再次去新建 convoy 是因为插件是通过 nfs 同步的,一个节点新建,其他节点
都能看到
这是在server5上出现的结果
#怎么清理存储?
#先删除所有占用存储的容器
[root@server2 ~]# convoy delete vol1
[root@server2 ~]# convoy list #在 server1 上也看不到了
{}