企业 docker数据卷

docker 数据卷管理

为什么用数据卷?

因为docker本身的文件系统性能差,每次关闭容器后,操作的文件也会全部删除,而docker数据卷是 mount 到宿主机中,绕开了分层文件系统,和主机磁盘性能相同,容器删除后依然保留,但是仅限本地磁盘,不能随容器迁移

docker 官方提供两种卷:1.bind mount 2.docker managed volume

bind mount 绑定挂载

开启容器,容器里/usr/share/nginx/html 是 nginx的默认发布目录,将容器的默认发布目录挂载到宿主机的/opt/webdata下

[root@server1 ~]# docker run -d --name web1 -p 80:80 -v /opt/webdata:/usr/share/nginx/html nginx

这时候访问localhost会报错,因为挂载的/opt/webdata里面是空的,
可以直接在挂载目录里建立index.html 写入一个内容可以访问到

[root@server1 ~]# echo www.redhat.com > /opt/webdata/index.html
[root@server1 ~]# curl localhost
www.redhat.com

在容器里也可以进行修改内容,因为nginx 容器没有交互式的界面所以打开它需要执行

[root@server1 ~]# docker exec -it web1 bash
root@e7b12a47d559:/# cd /usr/share/nginx/html/           
root@e7b12a47d559:/usr/share/nginx/html# echo www.redhat.com >> index.html 

[root@server1 ~]# curl localhost
www.redhat.com
www.redhat.com

这种方式进行的挂载,不存在的目录会自动新建(无论容器还是宿主机),但是会以宿主机为准,绑定挂接到容器后,容器中的对应目录如果有数据,就会被覆盖。

同时挂载也可以指定挂载类型,默认是rw读写,可以指定为ro只读

[root@server1 ~]# docker run -it --name vm1 -v /opt/data:/mnt/:ro busybox	#运行容器指定挂载为只读
/ # cd /mnt
/mnt # touch file1	#无法建立文件
touch: file1: Read-only file system

[root@server1 ~]# cd /opt/data/	#在宿主机里就可以去建立文件
[root@server1 data]# touch file1

还可以挂载 yum 源

将宿主机yum源挂载到容器里,rhel7没有界面所以加bash
[root@server1 data]# docker run -it --name vm2 -v /etc/yum.repos.d/test.repo:/etc/yum.repos.d/test.repo rhel7 bash
bash-4.2# yum repolist
Skipping unreadable repository '///etc/yum.repos.d/rhel7.repo'
repo id                                      repo name                                     status
rhel7.6                                      rhel7.6                                       5152
repolist: 5152

可以加上ro只读让yum源不可被更改


docker managed volume

bind mount 必须指定宿主机文件系统路径,移植性差,如果需要从a主机移植到b主机,但是b主机上没有这个路径,就无法移植
而 docker managed volume 不需要指定,docker 自动为容器创建,默认数据卷目录都在/var/lib/docker/volumes

[root@server1 _data]# docker run -d --name web1 -p 80:80 -v /usr/share/nginx/html nginx
#切换到数据储存的目录
[root@server1 _data]# cd /var/lib/docker/volumes/fb37c38b6bcc77445714d4d306545a654a14363e16856044388b175914d13108/_data
#重写入默认页的内容
[root@server1 _data]# echo www.redhat.com > index.html 
[root@server1 _data]# curl localhost
www.redhat.com

并且还可以自定义指定数据目录的名称,因为系统生成的目录太常了也不好区分

[root@server1 _data]# docker run -d --name web2 -p 8080:80 -v website:/usr/share/nginx/html nginx #指定数据存放目录是website
[root@server1 _data]# docker inspect web2	#查看容器信息
"Source": "/var/lib/docker/volumes/website/_data",	#数据路径还是/var/lib/docker/volumes/里

[root@server1 _data]# docker rm -f web2
[root@server1 _data]# ls /var/lib/docker/volumes/	#删除容器后数据还是存在的
website

想要删除数据目录里没有用的数据卷可以使用命令:docker volume prune

另一种用法

当运行一个容器web1用managed volume方式,,指定数据卷的名称为website,对默认发布页面进行改写,然后删除web1,再运行web2依然使用website数据卷,访问可以看到同样的内容

[root@server1 ~]# docker run -d --name web1 -p 80:80 -v website:/usr/share/nginx/html nginx
[root@server1 ~]# ehco www.redhat.com > /var/lib/docker/volumes/website/_data/index.html 

[root@server1 ~]# docker rm -f web1 
[root@server1 ~]# docker run -d --name web2 -p 80:80 -v website:/usr/share/nginx/html nginx
[root@server1 ~]# curl localhost
www.redhat.com

运行web3并且不指定端口映射,数据卷还是使用website

[root@server1 ~]# docker run -d --name web3 -v website:/usr/share/nginx/html nginx	
[root@server1 ~]# docker inspect web3
"IPAddress": "172.17.0.3",	#查看到web3的ip

[root@server1 ~]# curl 172.17.0.3	#访问web3,依然可以看到更改的页面
www.redhat.com

使用这种方式让多个容器挂载同一个目录,并且我们的数据卷是不会在容器被删除时被删除,如果需要恢复容器,运行时还是使用这个数据卷就可以了


卷插件

docker 卷默认使用的是 local 类型的驱动,只能存在于宿主机,跨主机的 volume 就需要第三方驱动
在官方网站里,提供了官方的插件API,开发者可以根据实际需求定制插件驱动
https://docs.docker.com/engine/extend/legacy_plugins/
在这里插入图片描述

卷插件的工作流程是docker engine(daemon) --> volume plugin --> storage platform,docker引擎调用卷插件,在由插件管理存储平台;
docker plugin 是以 web 服务的方式在 docker 主机上独立运行的,plugin 的启动和停止并不依赖于 docker,docker daemon 依靠在默认路径下查找 unixsocket 文件来自动发现插件。
当客户端与 daemon 交互并使用插件创将数据卷时,daemon 会在后端找到插件对应的socket 文件,建立连接并发起相应的 API 请求,最终结合 daemon 自身的处理完成客户端请求。

convoy卷插件操作

底层存储支持三种模式:devicemapper、NFS、EBS,需要在所有 docker 节点提前挂载 NFS 存储。
因为是操作共享存储所以需要两台主机来进行操作,server1和server2

配置nfs

在两台主机上安装docker服务和nfs-utils

[root@server2 ~]# yum insatll -y *.rpm
containerd.io-1.2.5-3.1.el7.x86_64.rpm   
container-selinux-2.21-1.el7.noarch.rpm  
docker-ce-18.09.6-3.el7.x86_64.rpm
docker-ce-cli-18.09.6-3.el7.x86_64.rpm

[root@server2 ~]# yum install -y nfs-utils
[root@server2 ~]# systemctl start rpcbind

在server1里编辑文件,指定共享目录的挂载路径

[root@server1 ~]# cat /etc/exports
/mnt/nfs 	*(rw,no_root_squash) #加参数保证root在操作时不切换身份,默认会切换到nfs用户

在server1里创建指定的目录/mnt/nfs

[root@server1 ~]# mkdir /mnt/nfs
[root@server1 ~]# systemctl start nfs	#启动nfs
[root@server1 ~]# exportfs -rv	#导出共享目录
exporting *:/mnt/nfs

在server2上同样进行操作

[root@server2 ~]# mkdir /mnt/nfs	#创建挂载目录
[root@server2 ~]# showmount -e 172.25.254.1	#可以查看到server1里的共享
Export list for 172.25.254.1:
/mnt/nfs *

然后测试把serve1上的/mnt/nfs,挂载到server2的/mnt/nfs

[root@server2 ~]# mount server1:/mnt/nfs /mnt/nfs
[root@server2 ~]# df	#查看挂载
server1:/mnt/nfs        8910848 2608384   6302464  30% /mnt/nfs

挂载成功后,测试在server1里建立文件

[root@server1 ~]# touch /mnt/nfs/testfile1	#server1创建文件

[root@server2 ~]# ls -l /mnt/nfs/testfile1 	#server2上同步可以看到
-rw-r--r--. 1 root root 0 Jun  3 11:23 /mnt/nfs/testfile1

这样就保证里nfs配置是成功的

安装配置convoy

在命令行里直接下载源码包
wget https://github.com/rancher/convoy/releases/download/v0.5.2/convoy.tar.gz

解压convoy包,并执行

[root@server1 ~]# tar xfz convoy.tar.gz 
[root@server1 ~]# cd convoy/
[root@server1 convoy]# ls
convoy  convoy-pdata_tools  SHA1SUMS
[root@server1 convoy]# cp convoy convoy-pdata_tools /usr/local/bin	#将convoy的命令放在命令库里

运行convoy,执行成功后回车可以回到shell界面,&符可以运行在后台
[root@server1 convoy]# convoy daemon --drivers vfs --driver-opts vfs.path=/mnt/nfs &
[root@server1 convoy]# mkdir /etc/docker/plugins #创建插件目录,docker程序默认会在这个目录下查找convoy套接字

把 convoy.sock 文件路径写入 convoy.spec,必须以 spec 结尾,convoy 是插件名
[root@server1 convoy]# cd /etc/docker/plugins/
[root@server1 plugins]# echo "unix:///var/run/convoy/convoy.sock" > convoy.spec

在server1操作完成后,server2进行同样的操作

[root@server2 convoy]# convoy daemon --drivers vfs --driver-opts vfs.path=/mnt/nfs &
[root@server2 convoy]# cd /etc/docker/plugins/
[root@server2 plugins]# echo "unix:///var/run/convoy/convoy.sock" > convoy.spec

docker引擎默认扫描 /etc/docker/plugins目录中的convoy.spec—>访问/run/convoy/convoy.sock文件—>发起响应的api请求—>把数据写入vol1中—>底层通过nfs进行主机间的数据同步

创建卷,并进行查看

[root@server1 convoy]# convoy create vol1	#创建一个vol1的卷
[root@server1 convoy]# convoy list	#列出所有卷信息
"vol1": {
		"Name": "vol1",
				"Driver": "vfs",
				"MountPoint": "",
				"Path": "/mnt/nfs/vol1",	#创建出的路径就在/mnt/nfs/
				"PrepareForVM": "false",
				"Size": "0",

同时还可以看到/mnt/nfs下还会有一个 config 目录,里面的东西不要删除,否则客户端命令可能就用不了

[root@server1 convoy]# ls /mnt/nfs
config  testfile1  vol1

开启一个容器,将vol1挂载到/data上,并进行操作测试

[root@server1 convoy]# docker run -it --name vm1 -v vol1:/data busybox
/ # cd data/
/data # touch file1 file2
/data # ls
file1  file2

[root@server1 ~]# ls /mnt/nfs/vol1/	#切换到宿主机shell可以看到建立的文件
file1  file2

[root@server2 nfs]# ls /mnt/nfs/vol1/	#server2上同样可以看到
file1  file2

就算是关闭容器数据同样可以看到,假设vm1这个容器挂了,在server2上再建立一个vm1里面的数据也是一样的

[root@server2 ~]# docker run -it --name vm1 -v vol1:/data busybox
/ # ls /data/
file1  file2

server2 上恢复,这里不用再次去新建 convoy 是因为插件是通过 nfs 同步的,一个节点新建,其他节点都能看到。

清理存储

想要清理储存,先删除所有占用存储的容器

[root@server2 ~]# convoy delete vol1	#删除卷
[root@server2 ~]# convoy list	#就无法查看到了,server1上同样也看不到里
{}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Howei__

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值