目录
3.bind mount与docker managed volume对比
Docker容器产生的数据,如果不通过docker commit生成新的镜像,使得数据做为镜像的一部分保存下来, 那么当容器删除后,数据自然也就没有了,为了能保存数据在docker中我们使用卷。
数据卷的特点
卷的设计目的就是数据的
持久化
,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷特点:
数据卷可在容器之间共享或重用数据卷中的更改可以直接生效数据卷中的更改不会包含在镜像的更新中数据卷的生命周期一直持续到没有容器使用它为止。
一、Docker数据卷管理
•
为什么要用
数据卷
•
docker分层文件系统
•
性能差
•
生命周期与容器相同
•
docker数据卷
•
mount到主机中,绕开分层文件系统
•
和主机磁盘性能相同,容器删除后依然保留
•
仅限本地磁盘,不能随容器迁移
•
docker
提供了两种卷:
•
bind mount
•
docker
managed volume
首先清理一下实验环境。server1和server2执行相同的操作。
docker network prune
docker ps
docker rm -f demo1
docker rm -f affectionate_jones
docker ps -a
docker network prune
1、
bind mount
•
bind mount
•
是将主机上的目录或文件
mount
到容器里。
•
使用直观高效,易于理解。
•
使用
-v
选项指定路径,格式
<host path>:<container path>
docker run --rm -it -v /data1:/data1 busybox ##-v 是指定将宿主机的/data1挂接到容器内的/data1,再容器内建立文件(宿主机的目录可以不用创建,会自动创建)
cd /data1 在宿主机的/data1中也可以看到
ls
docker history registry:latest #当某些应用的卷的位置确定时,就不可以随意指定挂载位置
•
bind mount
默认权限是读写
rw
,可以在挂载时指定只读
ro
。
•
-v
选项指定的路径,如果不存在,挂载时会自动创建。
docker attach mystifying_chaum
docker ps -a
docker run --rm -it -v /data1:/data1 -v /data2:/data2:ro -v /etc/yum.repos.d/dvd.repo:/dvd.repo:ro busybox
#-v可以指定多个,也可控制权限(默认情况下权限是读写)
在/data2中不能创建只有只读权限。/下dvd.repo不能删除,也是只读。
2、
docker
managed volume
•
bind mount必须指定host
文件系统路径,限制了移植性。
•
docker
managed volume
不需要指定
mount
源
,docker自动为容器创建数据卷目录。
•
默认创建的数据卷目录都在 /var/lib/docker/volumes 中。
•
如果挂载时指向
容器内
已有
的
目录,原有数据会被复制到
volume
中。
docker自动为容器创建数据卷,会读取镜像的VOLUME参数。只有有这个参数才会自动创建。
还是先清理一下之前的环境。
docker volume ls
docker volume prune
docker run -d --name demo nginx ##运行dmeo
docker ps
docker volume ls #没有产生卷信息——容器没有自动创建卷,因为容器没有定义卷的挂载
docker rm -f demo
docker run -d --name demo registry ##运行registry
docker volume ls ##产生卷信息
docker inspect demo ##可以看到容器内卷的位置
注意:该方式只能支持目录的挂载,不能支持文件的挂载
docker rm -f demo
docker volume prune
docker volume create vol1 ##创建卷vol1
docker inspect vol1 ##查看卷的路径
cd /var/lib/docker/volumes/vol1/_data ##目录为容器内的目录
ls
pwd
docker run -d --name demo -v vol1:/var/lib/registry registry ##将docker管理卷vol1挂到/var/lib/registry,不用指定绝对路径,系统会自动识别
docker inspect demo
上面的方式就会简单很多。目录指定。
cd
docker ps -a
docker rm -f demo
docker run -d --name demo -v vol1:/usr/share/nginx/html nginx ##将卷vol1挂到nginx 中
cd /var/lib/docker/volumes/vol1/_data #可以看到出现两个文件,这两个文件是容器内的挂载路径
ls
docker exec -it demo bash 进入容器看到/usr/share/nginx/html nginx的内容复制到卷中
由上可知:docker管理卷在挂载的时候会将容器内的路径下的文件拷贝出来。
但如果用下面
bind mount
方式。内容会被覆盖。
docker rm -f demo
docker run -d --name demo -v /data1:/usr/share/nginx/html nginx ##用bind mount方式挂载到容器目录下
cd /data1 #看到之前创建的文件
ls
docker exec -it demo bash ##进入容器内看到目录底下内容被覆盖
以宿主机路径为主,bind mount方式会直接覆盖 ,docker 管理卷不会。当考虑目录中有文件时,不要选用bind mount方式会直接覆盖。
3.bind mount与docker managed volume
对比
相同点:两者都是 host 文件系统中的某个路径。
不同点:
存在问题:容器原有数据只存在宿主机,没有办法同步到其他节点。默认的上面几种方式都不支持跨节点共享数据。下面解决数据卷的集群共享问题。
二、 convoy卷插件
1.
卷插件
简介
•
docker
卷默认使用的是
local
类型的驱动,只能存在宿主机,跨主机的
volume
就需要使用第三方的驱动,可以查看
以下
链接
:
•
https://docs.docker.com/engine/extend/legacy_plugins/#volume-plugins
•
docker
官方只提供了卷插件的
api
,开发者可以根据实际需求定制卷插件驱动。
•
https://docs.docker.com/engine/extend/plugins_volume/#volume-plugin-protocol
•
Docker Plugin 是以Web Service的服务运行在每一台Docker Host上的,通过HTTP协议传输RPC风格的JSON数据完成通信。
•
Plugin的启动和停止,并不归Docker管理,Docker Daemon依靠在缺省路径下查找Unix Socket文件,自动发现可用的插件。
•
当客户端与Daemon交互,使用插件创建数据卷时,Daemon会在后端找到插件对应的 socket 文件,建立连接并发起相应的API请求,最终结合Daemon自身的处理完成客户端的请求。
2.convoy
卷插件
•
convoy
卷插件实现
•
支持三种运行方式:devicemapper、NFS、EBS。
•
以下实验使用
nfs
方式。
•
下载软件:
https://github.com/rancher/convoy/releases/download/v0.5.2/convoy.tar.gz
•
在所有节点提前挂载
NFS
存储。
首先准备两台独立且干净的机器。
docker ps
docker rm -f demo
docker volume prune
然后在server1端:
mkdir /nfsshare #创建共享目录
cd /nfsshare
yum install -y nfs-utils
chmod 777 /nfsshare/ #将权限给够
vim /etc/exports ##访客以root用户访问NFS服务端时,被映射为root用户。以其他用户访问时同样映射为对应uid的用户,因为no_all_squash是默认选项。
##############
/nfsshare *(rw,no_root_squash) #路径由自己指定读写,不转换身份
#############
systemctl enable --now nfs ##设置开机自启动
showmount -e ##在nfs服务端本机查看共享目录
在server2端做一下数据同步:
mkdir /nfsshare ##同样建立共享目录
yum install -y nfs-utils
showmount -e 172.25.254.1 ##使用showmount 加服务器IP查看共享情况
mount 172.25.254.1:/nfsshare/ /nfsshare/ ##挂载
df 查看挂载情况
此时两个数据节点数据同步。
测试:在服务端docker1的/nfsshare中建立文件在客户端也能看到。
在server1下载插件,然后解压。
tar axf convoy-v0.5.2.tar.gz ##解压
cd convoy/
cp convoy convoy-pdata_tools /usr/local/bin/ #将可执行文件添加到PATH路径:在环境变量中也可以调用
cd /usr/local/bin/
mkdir -p /etc/docker/plugins/ ##创建插件配置文件目录
cd /etc/docker/plugins/
ls
echo "unix:///var/run/convoy/convoy.sock" > /etc/docker/plugins/convoy.spec #创建Convoy插件配置文件
cat /etc/docker/plugins/convoy.spec
convoy daemon --drivers vfs --driver-opts vfs.path=/nfsshare & #启动convoy插件,驱动是vfs,定义vfs的输出路径
cd /var/run/convoy/
ll #启动之后,这个路径就会有sock
在server2执行相同的操作。
tar zxf convoy-v0.5.2.tar.gz #先下载,下载后解压
cd convoy/
ls
cp convoy convoy-pdata_tools /usr/local/bin/
cd
which convoy
df ##查看挂载信息
mkdir -p /etc/docker/plugins/
echo "unix:///var/run/convoy/convoy.sock" > /etc/docker/plugins/convoy.spec
convoy daemon --drivers vfs --driver-opts vfs.path=/nfsshare &
cd /var/run/convoy/
ll
创建卷
在server1端创建卷
convoy list
docker volume ls
convoy create vol1 ##创建卷vol1
convoy list ##查看系统中所有卷
cd
cd /nfsshare ##创建的卷在此目录下
ls
docker volume ls ##也可以查看卷
数据会在server2中同步。查看
convoy list
docker volume ls
docker volume create -d convoy vol2 ##创建卷vol2,定义驱动为convoy
ls
此时server1中查看也同步过去了:
cd /nfsshare
ls 看到创建的卷
docker volume ls ##docker volume 也可以查看卷信息
下面就是应用一下。
测试:
docker run -d --name dmeo -v vol1:/usr/share/nginx/html nginx #将卷vol1挂到容器内
docker ps
docker inspect dmeo ##查看容器信息
curl 172.17.0.2可以访问到nginx发布页
cd /nfsshare/
cd vol1
ls
echo www.westos.org > index.html ##修改发布页
curl 172.17.0.2
此时我们模拟出现故障,删除server1的demo
此时在server2上挂载vol1卷到容器
docker run -d --name dmeo -v vol1:/usr/share/nginx/html nginx##将卷挂到容器内
docker ps
curl 172.17.0.2 ##可以看到之前修改的发布页
systemctl status docker
整个过程如下:
docker client -> docker daemon -> convoy plugins -> nfs
回收卷
server2客户端:
docker rm -f dmeo ##先删除容器
docker volume ls ##再回收卷
docker volume rm vol2
docker volume rm vol1
docker ps
docker volume ls
convoy list
fg 因为convoy没有提供停止守护进程的功能 ,调回前端结束
ps ax
cd /etc/docker/
ls
cd plugins/
ls
rm -f convoy.spec ##删除插件
systemctl restart docker##重启docker 速度会很快
server1服务端回收
docker ps
docker volume ls
fg
cd /etc/docker/
ls
cd plugins/
ls
rm -fr convoy.spec
ls
systemctl restart docker
如果回收过程出现问题时删除下面的.db文件。