docker数据卷管理()

前言:

docker数据卷

  • 数据卷是目录或文件,不是块设备。
  • 容器可以读写volume中的数据。
  • volume数据可以持久化保存。

docker提供了两种卷:

  • bind mount
  • docker managed volume

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

不同点:

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

一、实验环境(rhel7.3版本)

1.selinux和firewalld状态为disabled

2.各主机信息如下:

server1(安装好docker) 172.25.1.1
server2(安装好docker) 172.25.1.2

二、bind mount卷

是将主机上的目录或文件mount到容器里。
使用直观高效,易于理解。
使用 -v 选项指定路径,格式 <host path>:<container path>

注意:
bind mount 默认权限是读写rw,可以在挂载时指定只读ro,-v选项指定的路径,如果不存在,挂载时会自动创建

示例:

  • 创建容器:
[[email protected] ~]# docker run -it --name vm1 -v /tmp/data1:/data1 -v /tmp/data2:/data2:ro -v /etc/yum.repos.d/yum.repo:/yum.repo:ro ubuntu		
#data1目录默认权限 data2目录和yum.repo文件设置只读。
  • 测试几个目录及文件的权限
    docker数据卷管理()

三、docker managed volume

docker managed volume
bind mount必须指定host文件系统路径,限制了移植性。
docker managed volume 不需要指定mount源
跨主机的volume就需要使用第三方的驱动:https://docs.docker.com/engine/extend/legacy_plugins/#volume-plugins

  • 查看现有管理卷
[[email protected] ~]# docker volume ls
DRIVER              VOLUME NAME
local               4984ed1591713db2c8580fc0c58d199969439d8c4b00e1c1b3f2ea1b20e62a8b
  • 清除没有容器使用的管理卷
[[email protected] ~]# docker volume prune 
WARNING! This will remove all local volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Volumes:
4984ed1591713db2c8580fc0c58d199969439d8c4b00e1c1b3f2ea1b20e62a8b

Total reclaimed space: 1.106kB

下面的实验会用到registry镜像:

[[email protected] ~]# docker run -d --name registry registry:2

再次查看数据管理卷:发现生成了一个管理卷

[[email protected] ~]# docker volume ls
DRIVER              VOLUME NAME
local               b578d5f8715b85146555838467ef431c883495ac5477ddf0cec74435335f2156

查看registry的相关信息:

[[email protected] ~]# docker inspect registry

docker数据卷管理()
Source为管理卷在宿主机的目录,是docker为容器自动生成的目录,如果挂载时不指定目录,容器内挂载目录的原有数据会复制到宿主机的该目录中。注意,即使删除容器,管理卷也不会删除。
docker数据卷管理()
我们会发现,docker自动生成的目录名称会很长,不方便书写使用。我们可以在创建容器时自己定义目录名称。

[[email protected] ~]# docker run -d --name registry -v registry2:/var/lib/registry registry:2 
80b2f173dd4772b932fe3c91fcb210b1dcd180b4fbe589a17559674a08545e59
[[email protected] ~]# docker volume ls
DRIVER              VOLUME NAME
local               registry2

查看管理卷目录:
docker数据卷管理()
同样,我们也可以先创建管理卷,再创建目录时指定该目录为容器的管理卷

[[email protected] ~]# docker volume create vol1		#创建名为vol1的管理卷
vol1
[[email protected] ~]# docker volume ls
DRIVER              VOLUME NAME
local               registry2
local               vol1

创建容器并将管理卷挂载到容器内的指定目录:

[[email protected] ~]# docker run -d --name registry2 -v vol1:/var/lib/registry registry:2 
d3819888a9b9ae2b346780446e82b4d029874f3d23083b148ea816ba5c81c337
[[email protected] ~]# docker inspect registry2 | grep Source
                "Source": "/var/lib/docker/volumes/vol1/_data",

新建管理卷,创建容器时挂载管理卷可以指定目录读写权限:

[[email protected] ~]# docker volume create vol2
vol2
[[email protected] ~]# docker volume ls
DRIVER              VOLUME NAME
local               registry2
local               vol1
local               vol2
[[email protected] ~]# docker run -it --name registry3 -v vol2:/data:ro ubuntu
[email protected]:/# cd data/
[email protected]:/data# touch file
touch: cannot touch 'file': Read-only file system
[email protected]:/data# exit
[[email protected] ~]# docker inspect registry3 | grep Source                "Source": "/var/lib/docker/volumes/vol2/_data",

四、convoy卷插件

1、首先在server1和server2主机搭建nfs文件系统

server1:

[[email protected] ~]# yum install nfs-utils.x86_64 -y	#安装nfs服务对应的软件
[[email protected] ~]# systemctl start rpcbind			#启动相关服务	
[[email protected] ~]# mkdir /mnt/nfs		#创建共享目录
[[email protected] ~]# chmod 777 /mnt/nfs/   #赋予共享目录/mnt/nfs目录777的权限,这步必须做,因为运行容器时,是以普通用户的身份运行的。如果没有写的权限,会报错。
[[email protected] ~]# vim /etc/exports   	#编写共享目录的文件,这个文件是空的,需要自己填写
/mnt/nfs        *(rw,no_root_squash)
[[email protected] ~]# systemctl start nfs		

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

server2:

[[email protected] ~]# yum install -y nfs-utils.x86_64
[[email protected] ~]# systemctl start nfs-server.service		#启动nfs服务
[[email protected] ~]# showmount -e 172.25.1.1					#查看server1的共享文件
[[email protected] ~]# mkdir /mnt/nfs   #创建目录/mnt/nfs,便于挂载。
[[email protected] ~]# mount 172.25.1.1:/mnt/nfs /mnt/nfs   #将172.25.1.1下的/mnt/nfs目录挂载到本地的/mnt/nfs目录下
[[email protected] ~]# df   #查看挂载信息,以确保挂载成功
172.25.1.1:/mnt/nfs                  17811456 4411904  13399552  25% /mnt/nfs

docker数据卷管理()
docker数据卷管理()
测试nfs环境是否搭建完成:

#客户端(server2)上touch文件
[[email protected] ~]# cd /mnt/nfs
[[email protected] nfs]# ls
[[email protected] nfs]# touch file	#在挂载点/mnt/nfs目录中创建文件file
[[email protected] nfs]# ls
file

#在服务端(server1)上进行查看
[[email protected] ~]# cd /mnt/nfs/
[[email protected] nfs]# ls			#可以看到客户端写入的内容,表示nfs服务搭建成功
file

2、配置convoy环境

1、在server1端:下载convoy对应的压缩包(convoy.tar.gz),进行解压,并进行配置

docker官方提供了卷插件的api,在我知道的实现docker卷插件有flocker、convoy这两个插件。开发者可以根据实际需求定制卷插件驱动。

https://docs.docker.com/engine/extend/plugins_volume/#volume-plugin-protocol

[[email protected] ~]# tar zxf convoy.tar.gz 
[[email protected] ~]# cd convoy/
[[email protected] convoy]# ls
convoy  convoy-pdata_tools  SHA1SUMS
[[email protected] convoy]# cp convoy* /usr/local/bin/		#将二进制文件复制到PATH路径下
[[email protected] convoy]# mkdir /etc/docker/plugins		#创建docker的卷插件目录
[[email protected] convoy]# convoy daemon --drivers vfs --driver-opts vfs.path=/mnt/nfs &> /dev/null &		
#值的注意的是:第一次运行上面的convoy daemon命令的时候,会在/mnt/nfs目录下生成一个config文件夹,这个文件夹不要删除,不然客户端的convoy命令就会用不了
[[email protected] convoy]# cd /mnt/nfs/
[[email protected] nfs]# ls
config
[[email protected] nfs]# echo "unix:///var/run/convoy/convoy.sock" > /etc/docker/plugins/convoy.spec   #将convoy守护进程开启生成的.sock文件放入/etc/docker/plugins目录下的convoy.spec文件中,docker就可以识别。(其中convoy.spec文件之前是不存在的)
[[email protected] nfs]# cat /etc/docker/plugins/convoy.spec 
unix:///var/run/convoy/convoy.sock

docker数据卷管理()

2、创建卷

[[email protected] nfs]# docker volume ls
DRIVER              VOLUME NAME
[[email protected] nfs]# convoy create vol1
vol1
[[email protected] nfs]# ll /mnt/nfs/		#可以看到vol1目录
total 0
drwx------ 2 root root 34 May 31 20:56 config
drwx------ 2 root root  6 May 31 20:56 vol1

3、将解压convoy目录给server2复制一份,配置convoy环境

server1:

[[email protected] ~]# scp -r convoy server2:
[email protected]'s password: 
convoy-pdata_tools                                  100%   22MB  22.0MB/s   00:01    
convoy                                              100%   19MB  19.5MB/s   00:01    
SHA1SUMS

server2:

[[email protected] ~]# cd convoy/
[[email protected] convoy]# ls
convoy  convoy-pdata_tools  SHA1SUMS
[[email protected] convoy]# cp convoy* /usr/local/bin/
[[email protected] convoy]# mkdir /etc/docker/plugins
[[email protected] convoy]# echo "unix:///var/run/convoy/convoy.sock" > /etc/docker/plugins/convoy.spec
[[email protected] convoy]# convoy daemon --drivers vfs --driver-opts vfs.path=/mnt/nfs &> /dev/null &
[1] 2038

docker数据卷管理()

3、操作卷

  • 列出全部convoy卷:
[[email protected] ~]# convoy list

docker数据卷管理()

  • 创建卷
[[email protected] nfs]# convoy create vol1
vol1
  • 使用卷
[[email protected] ~]# docker run -it --name vm1 -v vol1:/data --volume-driver=convoy ubuntu
[email protected]:/# cd data/
[email protected]:/data# touch file{1..10}
[email protected]:/data# ls
file1  file10  file2  file3  file4  file5  file6  file7  file8  file9

可以在/mnt/nfs/vol1目录查看到文件:
docker数据卷管理()
docker数据卷管理()
由上可知server1和server2上看到的内容一致,即不同主机间实现了共享存储。

我们在server1上也使用该卷创建容器:

[[email protected] ~]# docker run -it --name vm2 -v vol1:/data --volume-driver=convoy ubuntu
[email protected]:/# cd data/
[email protected]:/data# ls
file1  file10  file2  file3  file4  file5  file6  file7  file8  file9

可以查看到server2上建立的文件。

  • 创建卷快照
[[email protected] ~]# convoy snapshot create vol1 --name vol1_pic
vol1_pic
--name前面的是卷名
加个--name起个名字,不然会是数字

docker数据卷管理()