一、Docker数据卷管理
Docker中的数据可以存储在类似于虚拟机磁盘的介质中,在Docker中称为数据卷(Data Volume)。数据卷可以用来存储Docker应用的数据,也可以用来在Docker容器间进行数据共享。数据卷呈现给Docker容器的形式就是一个目录,支持多个容器间共享,修改也不会影响镜像。使用Docker的数据卷,类似在系统中使用 mount 挂载一个文件系统。
1、为什么要用数据卷
docker分层文件系统:性能差、生命周期与容器相同,容器一旦删除,数据就没了;
docker数据卷:mount到主机中,绕开分层文件系统。那么数据和主机磁盘性能相同,容器删除后依然保留数据。缺点是仅限本地磁盘,不能随容器迁移;
2、docker提供了两种卷:bind mount、docker managed volume;
3、bind mount与docker managed volume的相同点:两者都是 host 文件系统中的某个路径。不同点如下表:
1.bind mount
bind mount 是将主机上的目录或文件mount到容器里,使用直观高效,易于理解。
使用 -v 选项指定路径,格式 < host path>:< container path>
首先需要停掉之前的服务,净化环境
使用nginx镜像后台运行一个容器,-v参数指定路径,表示将宿主机的 /data 目录挂载到容器的/usr/share/nginx/html目录下;
给data写入index.html文件
demo容器被分配到的ip如下,curl测试,显示了index.html文件的内容,说明读取的是挂载的/data的数据(bind mount的方式会直接覆盖原来的/usr/share/nginx/html的内容)
docker exec :在运行的容器中执行命令,在容器 demo 中开启一个交互模式的终端,可以看到容器的指定目录下与 /data目录的文件一致
进入demo,再次追加一个内容,curl测试,说明bind mount 默认权限是读写rw
也可以在挂载时指定只读ro,可以看到导入数据时被拒绝了;
-v选项指定的路径,如果不存在,挂载时会自动创建。
接着删除所创建的容器和文件
2.docker managed volume
1、bind mount必须指定host文件系统路径,限制了移植性;
2、docker managed volume 不需要指定mount源,docker自动为容器创建数据卷目录,默认创建的数据卷目录都在 /var/lib/docker/volumes 中;
3、如果挂载时指向容器内已有的目录,原有数据会被复制到volume中。
尽管可以不指定挂载源,但这样会生成一大串字符串,不利于记忆,所以先创建一个卷webdata,使用nginx镜像后台运行一个容器;
-v参数指定路径,表示 /var/lib/docker/volumes/webdata挂载到/usr/share/nginx/html
可以看到创建的卷会自动生成在 /var/lib/docker/volumes 目录下
进到webdata里面会发现数据就在这个目录下
当不指定mount源时
会生成很长的字符串子目录
进到所生成的数据卷目录下
可以看到这种挂载方式不是简单的覆盖,而是把原来的文件复制到现在的子目录里
某些镜像在构建过程中设定了数据卷,nginx无,registry有
二、卷插件简介
docker 卷默认使用的是local类型的驱动,只能存在宿主机,跨主机的volume就需要使用第三方的驱动。docker官方只提供了卷插件的api,开发者可以根据实际需求定制卷插件驱动。
1、Docker Plugin 是以Web Service的服务运行在每一台Docker Host上的,通过HTTP协议传输RPC风格的JSON数据完成通信。
2、Plugin的启动和停止,并不归Docker管理,Docker Daemon依靠在缺省路径下查找Unix Socket文件,自动发现可用的插件。
3、当客户端与Daemon交互,使用插件创建数据卷时,Daemon会在后端找到插件对应的 socket 文件,建立连接并发起相应的API请求,最终结合Daemon自身的处理完成客户端的请求。
4、Docker 以 C/S 模式工作,主要分为两个部分,Docker CLI 和 Docker Daemon 。Docker CLI ,也就是客户端,提供给用户命令行操作 Docker,例如 docker create/images/ps 等。Docker Damon ,也就是守护进程,负责接受用户指令,维护容器的生命周期。
1.convoy卷插件
convoy卷插件实现:
支持三种运行方式:devicemapper、NFS、EBS。
因为虚拟机支持nfs的方式,所以我们来用nfs的方式来实验;
1、NFS是Network File System的缩写,网络文件系统。它的主要功能是通过网络(一般是局域网)让不同的主机系统之间可以共享文件或目录。NFS客户端(一般为应用服务器,例如Web)可以通过挂载的方式,将NFS服务器端共享的数据目录挂载到NFS客户端本地系统中(就是某一个挂载点下)。从客户端本地看,NFS服务器端共享的目录就好像是客户端自己的磁盘分区或目录一样,而实际上确实远端的NFS服务器的目录。
2、NFS服务所使用的端口号在每次启动的时候是不同的,通过RPC(远程过程调用,英文Remote
Procedure Call简称RPC)协议/服务来实现,这个RPC服务的应用在门户级的网站有很多。例如:百度。NFS的RPC服务最主要的功能就是记录每个NFS功能所对应的端口号,并且在NFS客户端请求时将该端口和功能对应的信息传递给请求数据的NFS客户端,从而确保客户端可以连接到正确的NFS端口上去,达到实现数据传输交互数据目的。
server1、server2都要安装nfs-utils(必须在所有节点提前挂载NFS存储)
server1创建nfs目录,共享该目录下所有内容读写权限,不转换身份,赋予777权限,重启nfs;
showmount -e:显示NFS服务器上所有的共享目录
server2安装nfs-utils
server2创建nfs目录,挂载server1的/mnt/nfs
将真机的convoy卷插件安装包发给server1
server1解压,并放入/usr/local/bin,使其可执行
后台启动convoy插件
查看进程
当启动插件之后,可以在/var/run/convoy/下看到数据;
server1创建/etc/docker/plugins/目录,放置socket文件的路径;
echo “unix:///var/run/convoy/convoy.sock” > /etc/docker/plugins/convoy.spec:指定插件对应的 socket 文件,使得docker调用的时候可以检索到;
convoy list:列出卷,可以使用了,但是因为还没卷,所以是空的
创建卷vol1,会自动生成数据目录:/mnt/nfs/vol1/
server2进行同样的操作
server2在/mnt/nfs目录可以看到server1创建的数据卷
server2列出的卷
2.使用卷
可以在两个主机上同时运行容器,会发现数据目录中的数据是同步的;
server1后台运行容器,使用卷vol1
curl可以看到发布信息
向nginx默认发布目录写入数据
当我们做故障迁移,将server1上的demo容器删除掉
server2后台运行容器,使用卷vol1
server2又可以看到数据了
完成后删除卷
但是docker delete vol1 这种方式删除卷之后,再次查看存在的卷,docker volume ls的时候会很卡;
需要将convoy进程杀死
删除 /etc/docker/plugins
删除 /var/lib/volumes 下的文件(元数据)
重启docker 服务,此时 docker volume ls速度变快
在server1上和server2上一样的方式删除卷只不过最好把docker-compose停掉
cd harbor/
docker-compose stop
docker-compose rm
docker delete vol1
docker volume prune
ps ax
kill ****
cd /etc/dicker/plugins
rm -f *
cd /var/lib/volumes
rm -f metdata.db
最后实现数据卷清空即可
convoy卷插件子命令
convoy list 列出卷
convoy delete 删除卷
convoy snapshot create 创建快照
convoy snapshot delete 删除快照
convoy backup create 创建备份
convoy create res1 --backup < url> 还原备份