标签:swarm swarm nfs swarm数据持久化 swarm bind swarm volume
1.前言?在上一篇文章 《"三剑客”之Swarm集群架构、集群管理 、服务管理》中,大家已了解swarm集群管理以及如何管理swarm集群中的服务。试想一下,如果swarm集群中运行了mysql、nginx等服务,这些服务的数据如果没有挂载到宿主机中,那么容器一旦停止运行,那就意味着数据丢失。
?有什么方法可以解决swarm集群中运行的服务能够数据持久化呢?我们可以通过volme、bind、nfs等方法来实现swarm集群应用数据持久化,其实也和docker数据持久化的形式是一样的,下面通过几个案例一起来了解一下。
本文的环境还是用上次的swarm集群环境,不过这一次多增加一台nfs服务器,如果你没有这么多服务器,可以把其中一台agent节点替换成nfs服务器也一样。
服务器 | 角色 | 运行服务 | 系统版本 |
---|---|---|---|
172.18.18.32 | Manager | docker 17.12.0-ce、nfs客户端 | centos7.4 x64 |
172.18.18.33 | agent01 | docker 17.12.0-ce 、nfs客户端 | centos7.4 x64 |
172.18.18.34 | agent02 | docker 17.12.0-ce 、nfs客户端 | centos7.4 x64 |
172.18.18.90 | nfs | docker 17.12.0-ce 、nfs服务端 | centos7.4 x64 |
卷是绕过联合文件系统的一个或多个容器内的特定目录。 卷被设计为保持数据,与容器的生命周期无关。 因此,Docker在删除容器时不会自动删除卷,也不会“垃圾收集”不再由容器引用的卷。 也称为:数据卷。
需要更详细了解volume可参考官方文档:https://docs.docker.com/storage/volumes/
#docker service create --replicas 1或2或3... --name SERVICE-NAME --mount type=volume,src=<VOLUME-NAME>,dst=<CONNTAINER-PATH> <IMAGE>
1、接下来,我们在Manager节点上,创建数据卷nginx-vol,并把卷挂载到新建的nginx服务中(/usr/share/nginx/html/),此目录为nginx容器默认首页的目录,nginx用的是docker hub的官方镜像。
[root@Manager ~]# docker service create --replicas 2 --name web_test --mount type=volume,src=nginx-vol,dst=/usr/share/nginx/html/ nginx
u2rhq6pn3hwf3wosmahtvy10u
overall progress: 2 out of 2 tasks
1/2: running [==================================================>]
2/2: running [==================================================>]
verify: Service converged
参数说明:
2、查看一下创建的nginx副本
[root@Manager ~]# docker service ps web_test
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
xcpbgz473trl web_test.1 nginx:latest Manager Running Running 32 seconds ago
qxvmgvgijtyn web_test.2 nginx:latest agent01 Running Running 2 minutes ago
可以看出创建的nginx 2个副本分别在Manager和agnet01节点上运行了。
3、查看数据卷、挂载的数据
我们通过docker volumes ls可以看到nginx-vol数据卷也自动创建了。
[root@Manager ~]# docker volume ls
DRIVER VOLUME NAME
local nginx-vol
在通过docker volume inspect nginx-vol可以看到nginx-vol卷自动挂载到了/var/lib/docker/volumes/nginx-vol/_data目录下
[root@Manager ~]# docker volume inspect nginx-vol
[
{
"CreatedAt": "2018-03-26T15:03:43+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/nginx-vol/_data",
"Name": "nginx-vol",
"Options": {},
"Scope": "local"
}
]
然后,查看/var/lib/docker/volumes/nginx-vol/data目录下的数据同步了,从下面结果可以得到,nginx副本中/usr/share/nginx/html目录下的数据已经同步到了宿主机nginx-vol数据卷中了:
[root@Manager /]# ls /var/lib/docker/volumes/nginx-vol/_data
50x.html index.html
最后,在nginx-vol数据卷中随便创建个文件来验证是否会同步到nginx副本中:
[root@Manager /]# cd /var/lib/docker/volumes/nginx-vol/_data
[root@Manager _data]# touch a.txt
进入副本查看,之前创建了2个副本,我就随便进入1个副本查看,发现在宿主机nginx-vol卷中创建的a.txt已经同步到了副本的 /usr/share/nginx/html/目录下:
[root@Manager _data]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
92453ec5728f nginx:latest "nginx -g ‘daemon of…" 5 minutes ago Up 5 minutes 80/tcp web_test.2.gkt08hfffztue90pwfsgj5wn3
[root@Manager _data]# docker exec -it 92453ec5728f bash
root@92453ec5728f:/# ls /usr/share/nginx/html/
50x.html a.txt index.html
与卷相比,(bind)绑定挂到具有有限的功能。 当您使用绑定挂载时,宿主机上的文件或目录被挂载到容器中。 文件或目录由宿主机上的完整路径或相对路径引用(宿主机上的文件或目录要存在)。
相比之下,当您使用卷时,会在宿主机上的Docker存储目录中创建一个新目录,并且Docker会管理该目录的内容。该文件或目录不需要已经存在于Docker宿主机上。 如果它尚不存在,它会根据需求创建。 绑定挂载非常高效,但它们依赖于具有特定目录结构的主机的文件系统。
详细了解可参考官方文档:https://docs.docker.com/storage/bind-mounts/
1、读写挂载格式
#docker service create --replicas 1或2或3... --name SERVICE-NAME --mount type=bind,src=<VOLUME-NAME>,dst=<CONNTAINER-PATH> <IMAGE>
2、只读挂载格式
#docker service create --replicas 1或2或3... --name SERVICE-NAME --mount type=bind,src=<VOLUME-NAME>,dst=<CONNTAINER-PATH>,ro <IMAGE>
是不是发现和volume挂载一样的,只不过在type挂载类型变为bind而以,只读挂载还需要在上ro选项,默认为读写挂载,不需要加rw参数。
1、我们还是在Manager节点上,创建数据挂载目录/data/nginx,也是挂载到新建的nginx服务中(/usr/share/nginx/html/)。需要注意的是,我们需要在swarm集群所有节点上(Manager、agent)都要创建/data/nginx目录,因为Manager在创建nginx副本的时候是随机分配的。
[root@Manager ~]# mkdir -p /data/nginx/
[root@agent01 ~]# mkdir -p /data/nginx/
[root@agnet02 ~]# mkdir -p /data/nginx/
[root@Manager ~]#docker service create --replicas 2 --name web_test02 --mount type=bind,src=/data/nginx/,dst=/usr/share/nginx/html/ nginx
参数和volume挂载类似的,不做详细的说明了,大家一看就能明白。
2、查看一下创建的nginx副本
[root@Manager ~]# docker service ps web_test02
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
c2k6dnbzqct2 web_test02.1 nginx:latest agent01 Running Running 3 minutes ago
89gn5fjxzicr web_test02.2 nginx:latest agnet02 Running Running 3 minutes ago
可以看到,创建的2个副本根据默认策略分别分配到了agnet01和agnet02节点上。
3、进入agnet01或agnet02节点上查看下
[root@agent01 ~]# docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f2dbadb50332 nginx:latest "nginx -g ‘daemon of…" 5 minutes ago Up 5 minutes 80/tcp web_test02.1.c2k6dnbzqct2s2pftjed6ftvy
[root@agent01 ~]# docker exec -it f2dbadb50332 bash
root@f2dbadb50332:/# ls /usr/share/nginx/html/
在agent01节点上,进入副本后发现 /usr/share/nginx/html/目录为空,这是正常的,刚才我们在创建/data/nginx目录时只是空目录,并没有数据,所以现在来制造点数据验证一下。
4、制造数据
[root@agent01 ~]# cd /data/nginx/
[root@agent01 nginx]# touch bind.txt
[root@agent01 nginx]# docker exec -it f2dbadb50332 bash
root@f2dbadb50332:/# ls /usr/share/nginx/html/
bind.txt
在agent01宿主机/data/nginx/目录中新建了个文件,是不是发现副本中的目录也同步了;有些人可能会问了,那我是不是也要在agent02上也需要手动创建数据,如果还有其它节点(agent03、agnet04...等等),那岂不是每台swarm节点上要手动创建,多麻烦啊。接下来,我们通过nfs来解决这个麻烦,只需要搭建nfs服务器,swarm所有节点为nfs客户端。这样只需要在nfs服务端上创建数据即可。
NFS(Network File System)即网络文件系统,是FreeBSD支持的文件系统中的一种,它允许网络中的计算机之间通过TCP/IP网络共享资源。在NFS的应用中,本地NFS的客户端应用可以透明地读写位于远端NFS服务器上的文件,就像访问本地文件一样。
nfs服务器:创建/nfs目录
nfs客户端:不需要在nfs客户端提前mount,在Manager上创建副本的时候指定参数自动mount到nfs服务端
1、nfs服务端部署
[root@nfs ~]# yum -y install nfs-utils
[root@nfs ~]# mkdir /nfs
[root@nfs ~]# vim /etc/exports
/nfs 172.18.18.0/24(rw,sync,no_root_squash)
[root@nfs ~]# systemctl restart nfs
nfs参数说明:
2、nfs客户端部署
在swarm集群所有节点安装部署:
[root@Manager ~]# yum -y install nfs-utils
[root@agent01 ~]# yum -y install nfs-utils
[root@agent02 ~]# yum -y install nfs-utils
#docker service create --replicas 1或2或3... --name myservice --mount ‘type=volume,src=<VOLUME-NAME>,dst=<CONTAINER-PATH>, volume-driver=local,volume-opt=type=nfs,volume-opt=device=<nfs-server>:<nfs-path>, "volume-opt=o=addr=<nfs-address>,vers=4,soft,timeo=180,bg,tcp,rw"‘ <IMAGE>
1、我们还是在Manager上创建nginx副本来演示,同样把nfs共享目录:/nfs挂载到副本的(/ysr/share/nginx/html)目录中。
[root@Manager ~]# docker service create --replicas 3 --name web-nfs --mount ‘type=volume,src=nfs-vol,dst=/usr/share/nginx/html,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/nfs,"volume-opt=o=addr=172.18.18.90,vers=4,soft,timeo=180,bg,tcp,rw"‘ nginx
参数说明:
2、查看副本运行信息
[root@Manager ~]# docker service ps web-nfs
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
q67t67ucdba2 web-nfs.1 nginx:latest agent01 Running Running 12 minutes ago
3cs5jh8chegz web-nfs.2 nginx:latest Manager Running Running 10 minutes ago
0hykerf7n3a4 web-nfs.3 nginx:latest agnet02 Running Running 13 minutes ago
3个nginx副本分别分配到了swarm集群的3个节点上。
3、df 查看文件挂载信息,省略无用信息
[root@Manager ~]# df -h
Filesystem Size Used Avail Use% Mounted on
...
:/nfs 50G 9.6G 41G 20% /var/lib/docker/volumes/nfs-vol/_data
...
你在其它几个agnet节点上df查看也同样有这些信息。
4、回到nfs服务端,创建测试数据
[root@nfs nfs]# cd /nfs/
[root@nfs nfs]# touch nfs.html
5、进入swarm中所有节点,查看数据是否同步
进入Manager查看:
[root@Manager ~]# docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f176e66dc9f2 nginx:latest "nginx -g ‘daemon of…" 14 minutes ago Up 14 minutes 80/tcp web-nfs.2.3cs5jh8chegz4ncid8qd2as8q
[root@Manager ~]# docker exec -it f176e66dc9f2 bash
root@f176e66dc9f2:/# ls /usr/share/nginx/html/
50x.html index.html nfs.html
进入agnet01查看,agent02就不演示了,大家自己查看一下:
[root@agent01 ~]# docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b9b7dcc5bdfa nginx:latest "nginx -g ‘daemon of…" 17 minutes ago Up 17 minutes 80/tcp web-nfs.1.q67t67ucdba2c7b5srkm9b58n
[root@agent01 ~]# docker exec -it b9b7dcc5bdfa bash
root@b9b7dcc5bdfa:/# ls /usr/share/nginx/html/
50x.html index.html nfs.html
6、用docker volume ls验证数据卷
[root@Manager ~]# docker volume ls
DRIVER VOLUME NAME
local nfs-vol
local nginx-vol
[root@agent01 ~]# docker volume ls
DRIVER VOLUME NAME
local nfs-vol
local nginx-vol
7、通过rm删除副本验证
[root@Manager ~]# docker service rm web-nfs
[root@Manager ~]#df -h
我们把刚才创建的副本删除掉,然后通过df -h查看挂载的文件,发现也跟着不在了,其它节点也一样不存在了;然后你回到nfs服务端查看/nfs共享目录,数据是不变的。这就表现了,通过nfs挂载,副本被删除,不影响nfs服务端的源数据。只要数据在nfs服务端,就可实现数据的持久化。
在使用挂载类型上,一般优先建议使用volume(卷)挂载,不要使用bind(绑定)挂载,卷是持久化由Docker容器生成和使用的数据的首选机制。 虽然绑定挂载依赖于主机的目录结构,但卷由Docker完全管理。 与绑定安装相比,卷有几个优点:
本文的内容就到此结束,喜欢我的文章,请点击最上方右角处的《关注》!!!
"三剑客”之Swarm应用数据持久化管理(volume 、bind 、 nfs)
标签:swarm swarm nfs swarm数据持久化 swarm bind swarm volume
原文地址:http://blog.51cto.com/ganbing/2091292