玩转Docker-------第五部-----------数据卷管理&convoy卷插件

玩转Docker-------第五部-----------数据卷管理&convoy卷插件

1.什么是Docker数据卷

  1. 数据卷是一个或多个容器中专门指定的目录,它能够绕过联合文件系统。
    卷被设计用作数据持久化、并且是独立于容器的生命周期的。

  2. 因此,Docker不会在删除容器时自动删除数据卷卷,也不会主动“垃圾回收”掉容器不再使用的卷。

  3. 数据卷的存在就是想让的容器的数据持久化存在,而且可以实现容器之间的数据共享。

  4. 通俗地来说,docker容器数据卷可以看成使我们生活中常用的u盘,它存在于一个或多个的容器中,由docker挂载到容器,但不属于联合文件系统,Docker不会在容器删除时删除其挂载的数据卷。

2.为什么要用数据卷

docker分层文件系统:

  1. 性能差
  2. 生命周期与容器相同

docker数据卷:

  1. mount到主机中,绕开分层文件系统
  2. 和主机磁盘性能相同,容器删除后依然保留
  3. 仅限本地磁盘,不能随容器迁移

3.docker数据卷提供两种卷

bind mount

是将主机上的目录或文件mount到容器里

  1. 使用直观高效,易于理解。
  2. 使用 -v 选项指定路径,格式 :
  3. bind mount 默认权限是读写rw,可以在挂载时指定只读ro。
  4. -v选项指定的路径,如果不存在,挂载时会自动创建。

docker managed volume

bind mount必须指定host文件系统路径,限制了移植性。
docker managed volume 不需要指定mount源

bind mount 和docker managed volume对比

相同点:两者都是host文件系统中的某个路径

不同点

bind mountdocker managed volume
volnme位置可任意指定/var/lib/docker/volumes/…
对已有mount point 影响隐藏并替换为volume原有数据复制到volume
是否支持单个文件支持不支持,只能是目录
权限控制可设置为只读无控制,均为读写模式
移植性移植性弱,与host path 绑定移植性强,无需指定host 目录

4.bind mount应用

bind mount 卷直接将将主机上的目录或文件直接 mount 到容器里,使用直接,高效


[root@server1 ~]# docker run -d --name web1 -p 80:80 -v /opt/website:/usr/share/nginx/html nginx
## 使用-V 参数将server1上的/opt/website 挂载到容器中的 nginx默认发布目录,就是/usr/share/nginx/html
109d379bec099b62853adbe1e01b790ce8c47bd9ba31f4dea17fe9e64b50a1f3

[root@server1 ~]# curl localhost  #访问时被拒绝的,因为我们里面还没有资源
<html>
<head><title>403 Forbidden</title></head>
<body bgcolor="white">
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.13.9</center>
</body>
</html>
[root@server1 ~]# 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

[root@server1 ~]# vim /opt/website/index.html   现在在server1上写一个资源
[root@server1 ~]# curl localhost
www.westos.org
[root@server1 ~]# echo www.westos.org >> /opt/website/index.html    #追加
[root@server1 ~]# curl localhost
www.westos.org
www.westos.org

还可以在容器中进行更改:
[root@server1 website]# docker container attach web1 
## 这样的方式是登陆不进去的,因为nginx是一个应用容器,但是之前的 ubuntu 为什么可以?

## 查看构建历史
[root@server1 ~]# docker history nginx:latest 
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
e548f1a579cf        2 years ago         /bin/sh -c #(nop)  CMD ["nginx" "-g" "daemon…   0B                  
<missing>           2 years ago         /bin/sh -c #(nop)  STOPSIGNAL [SIGTERM]         0B                  
<missing>           2 years ago         /bin/sh -c #(nop)  EXPOSE 80/tcp                0B                  
<missing>           2 years ago         /bin/sh -c ln -sf /dev/stdout /var/log/nginx…   22B                 
<missing>           2 years ago         /bin/sh -c set -x  && apt-get update  && apt…   53.4MB              
<missing>           2 years ago         /bin/sh -c #(nop)  ENV NJS_VERSION=1.13.9.0.0B                  
<missing>           2 years ago         /bin/sh -c #(nop)  ENV NGINX_VERSION=1.13.9-0B                  
<missing>           2 years ago         /bin/sh -c #(nop)  LABEL maintainer=NGINX Do…   0B                  
<missing>           2 years ago         /bin/sh -c #(nop)  CMD ["bash"]                 0B                  
<missing>           2 years ago         /bin/sh -c #(nop) ADD file:27ffb1ef53bfa3b9f…   55.3MB              
[root@server1 ~]# docker history ubuntu:latest 
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
07c86167cdc4        4 years ago         /bin/sh -c #(nop) CMD ["/bin/bash"]             0B                  
<missing>           4 years ago         /bin/sh -c sed -i 's/^#\s*\(deb.*universe\)$…   1.9kB               
<missing>           4 years ago         /bin/sh -c echo '#!/bin/sh' > /usr/sbin/poli…   195kB               
<missing>           4 years ago         /bin/sh -c #(nop) ADD file:b9504126dc5590898…   188MB     
对比发现,nginx 镜像只最后只运行了 nginx,没有交互式进入 shell,而 ubuntu 有 /bin/bash

[root@server1 ~]# docker start web1 
web1
[root@server1 ~]# docker exec -it web1  bash  #-it 是 exec 的选项,bash 表示在容器内执行的操作,打开一个 bash
root@109d379bec09:/# ls
bin   dev  home  lib64	mnt  proc  run	 srv  tmp  var
boot  etc  lib	 media	opt  root  sbin  sys  usr
root@109d379bec09:/# cd /usr/share/nginx/html/
root@109d379bec09:/usr/share/nginx/html# ls
index.html
root@109d379bec09:/usr/share/nginx/html#  echo www.westos.org >> index.html
root@109d379bec09:/usr/share/nginx/html# cat index.html 
www.westos.org
www.westos.org
www.westos.org
root@109d379bec09:/usr/share/nginx/html# 
 
 [root@server1 ~]# curl localhost
www.westos.org
www.westos.org
www.westos.org    # 更改了
[root@server1 ~]# cat /opt/website/index.html
www.westos.org
www.westos.org
www.westos.org    # 而且容器上的数据其实只是更改了宿主机的数据

         

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

bind mount 方式挂载时默认权限是 rw,可以在挂载时指定只读(ro)。

[root@server1 ~]# ls /opt/
containerd  data  website
# 此时宿主机时没有 /opt/data1 和 /opt/data2 的,而且容器中没有/data1,data2的目录

[root@server1 ~]# docker run -it --name vm1 -v /opt/data1:/data1 -v /opt/data2:/data2:ro ubuntu
root@0ad999a9ad2f:/# ls
bin   data1  dev  home  lib64  mnt  proc  run   srv  tmp  var
boot  data2  etc  lib   media  opt  root  sbin  sys  usr  #自动创建了data1和data2的目录
root@0ad999a9ad2f:/# cd data1/
root@0ad999a9ad2f:/data1# touch file1     #data1中可以创建文件
root@0ad999a9ad2f:/data1# cd ../data2     #data2中不可以,因为我们刚才设置了只读挂载
root@0ad999a9ad2f:/data2# touch file2
touch: cannot touch 'file2': Read-only file system

[root@server1 ~]# cd /opt/data2
[root@server1 data2]# touch file2         #但是我们在宿主机中却可以创建
[root@server1 data2]# docker attach vm1
root@0ad999a9ad2f:/data2# 
root@0ad999a9ad2f:/data2# ls
file2

5.docker managed volume

查看现有的管理卷:

docker volume ls

我们有些是时候在删除了容器后会有残存的管理卷存在,这是我们就需要去清理它,不然会占用我们的资源:

docker volume prune 
docker volume ls

在这里插入图片描述

docker run -d --name registry registry
cd /var/lib/docker/volumes/
ls
docker history registry:latest 

在这里插入图片描述
通过docker volume可以将容器内的内容复制到挂载点:

[root@server1 volumes]# docker run -d --name vm2 -v /usr/share/nginx/html nginx
19a0084bd2802d8388940f2eff0a94bdd62e3b29f47d4138b0064b16df77181a
[root@server1 volumes]# ls
5dccd42f7717a7db4fdb821e60891c991447b5d0f94513b70d22e633083631a7  metadata.db
d0d3d2a058b6da2e1ac7f7c51ee8bbe473b5fcfc18acd84ae0876be662a8f08a
[root@server1 volumes]# cd 5dccd42f7717a7db4fdb821e60891c991447b5d0f94513b70d22e633083631a7/
[root@server1 5dccd42f7717a7db4fdb821e60891c991447b5d0f94513b70d22e633083631a7]# ls
_data
[root@server1 5dccd42f7717a7db4fdb821e60891c991447b5d0f94513b70d22e633083631a7]# cd _data/
[root@server1 _data]# ls
50x.html  index.html

在这里插入图片描述

docker inspect vm2
curl 172.17.0.4	   #nginx默认发布页

在这里插入图片描述

echo hello docker! > index.html
curl 172.17.0.4	    #可以直接在挂载的目录修改默认发布页

在这里插入图片描述

6.docker卷插件简介

docker卷默认使用的是local类型的驱动,只能存在宿主机,跨主机的volume就需要使用第三方的驱动

可以查看链接:
https://docs.docker.com/engine/extend/legacy_plugins/#volume-plugins

在这里插入图片描述

在这里插入图片描述
Docker Plugin 是以Web Service的服务运行在每一台Docker Host上的,通过HTTP协议传输RPC风格的JSON数据完成通信。Plugin的启动和停止,并不归Docker管理,Docker Daemon依靠在缺省路径下查找Unix Socket文件,自动发现可用的插件。
当客户端与Daemon交互,使用插件创建数据卷时,Daemon会在后端找到插件对应的 socket 文件,建立连接并发起相应的API请求,最终结合Daemon自身的处理完成客户端的请求。

7.convoy卷插件

convoy卷插件支持三种运行方式:devicemapper、NFS、EBS。下面的实验以nfs的运行方式来演示

实验目的:在server1和2底层用nfs来实现数据共享

step1 首先在server1和server2上搭建nfs文件系统:

server1:

yum install -y nfs-utils
systemctl start rpcbind	
mkdir /nfs	#创建共享目录
chmod 777 /nfs	#修改共享目录权限
vim /etc/exports	#编辑共享目录文件,否则将不会被共享出去
/nfs	*(rw,no_root_squash)
systemctl start nfs

在这里插入图片描述
注意:rpcbind服务必须是开启的。这是因为:他是一个RPC服务,主要是在nfs共享时候负责通知客户端,服务器的nfs端口号的。简单理解rpc就是一个中介服务。

server2:

yum install -y nfs-utils
systemctl start nfs-server.service
showmount -e server1	          #寻找server1的挂载目录
mkdir /nfs
mount server1:/nfs /nfs
df

在这里插入图片描述

测试:

在server2中:

cd /nfs/
touch file

在这里插入图片描述
在server1中:

cd /nfs/
ls	#查看到file

在这里插入图片描述
说明两个节点的/nfs实现同步了

step2 配置convoy环境:

docker官方只提供了卷插件的api,开发者可以根据实际需求定制卷插件驱动。

在server1中:

tar zxf convoy.tar.gz 
cd convoy/
cp convoy* /usr/local/bin/  #将二进制文件加入到PATH路径
mkdir /etc/docker/plugins	#创建docker的插件目录
convoy daemon --drivers vfs --driver-opts vfs.path=/nfs &> /dev/null &
cd /nfs
ls

注意:第一次运行上面的convoy daemon命令的时候,会在/nfs目录下生成一个config文件夹,这个文件夹不要删除,不然客户端的convoy命令就会用不了

echo "unix:///var/run/convoy/convoy.sock" > /etc/docker/plugins/convoy.spec
#将convoy守护进程开启生成的.sock文件放入/etc/docker/plugins目录下的convoy.spec文件中,docker就可以识别。(其中convoy.spec文件之前是不存在的)
cat /etc/docker/plugins/convoy.spec

在这里插入图片描述
在server2中同样配置convoy环境:

scp -r server1:convoy .
cd convoy/
cp convoy* /usr/local/bin/  #将二进制文件加入到PATH路径
mkdir /etc/docker/plugins	#创建docker的插件目录
echo "unix:///var/run/convoy/convoy.sock" > /etc/docker/plugins/convoy.spec
convoy daemon --drivers vfs --driver-opts vfs.path=/nfs &> /dev/null &
cd /nfs
ls

在这里插入图片描述

step3 创建卷:

docker volume ls
convoy create vol1

在这里插入图片描述
step4 操作卷:

在server2中运行容器,指定卷为刚才新创建的vol1:

[root@server1 nfs]# docker run -it --name vm5 -v vol1:/data ubuntu
root@b63cf80ce665:/# ls
bin   data  etc   lib    media  opt   root  sbin  sys  usr
boot  dev   home  lib64  mnt    proc  run   srv   tmp  var
root@b63cf80ce665:/# cd data/
root@b63cf80ce665:/data# ls 
50x.html  index.html
root@b63cf80ce665:/data# touch file{1..10}
root@b63cf80ce665:/data# ls
50x.html  file1  file10  file2  file3  file4  file5  file6  file7  file8  file9  index.html
root@b63cf80ce665:/data# [root@server1 nfs]# 
[root@server1 nfs]# cd /nfs/
[root@server1 nfs]# ls
config  file  vol1
[root@server1 nfs]# cd vol1/
[root@server1 vol1]# ls
50x.html  file1  file10  file2  file3  file4  file5  file6  file7  file8  file9  index.html
可以看到创建的文件在本地

在这里插入图片描述
而且server2也能看见了
这个时候容器就算 crash 掉,数据也已经保存在了本地,可以随时迁移容器

[root@server1 vol1]# docker rm -f vm5 		# 挂掉VM1 容器

[root@server2 ~]# docker run -it --name vm6 -v vol1:/data ubuntu
##在 server2 上恢复,这里不用再次去新建 convoy 是因为插件是通过 nfs 同步的,一个节点新建,其他节点都能看到
root@4bfc57f68d52:/# cd data/
root@4bfc57f68d52:/data# ls
file1  file10  file2  file3  file4  file5  file6  file7  file8  file9

清理convoy存储

先删除所有占用存储的容器。

[root@server2 ~]# umount /mnt/nfs/
[root@server2 ~]# docker rm -f vm1
dvm1
[root@server2 ~]# convoy list
{}
## server2上取消挂载后就不见这个卷了

[root@server1 vol1]# docker rm -f vm5 
[root@server1 ~]# convoy delete vol1
DEBU[12302] Calling: DELETE, /volumes/, request: DELETE, /v1/volumes/  pkg=daemon
DEBU[12302]                                               event=delete object=volume pkg=daemon reason=prepare volume=vol1
DEBU[12302] Cleaning up /mnt/nfs/vol1 for volume vol1     pkg=vfs
DEBU[12302]                                               event=delete object=volume pkg=daemon reason=complete volume=vol1

[root@server1 ~]# convoy list
{}
## server1上删除容器后 执行第二部删除操作,就看不到了
[root@server1 ~]# cd /mnt/nfs/
[root@server1 nfs]# ls
config  file1						## 数据目录也不见了

补充几条命令:

docker container prune	#删除停止的容器
docker volume prune	#删除没有被使用的卷
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值