暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Docker swarm(7)swarm数据持久化

运维笔记本 2020-01-24
4255

Docker swarm 数据持久化

Docker swarm 数据持久化是通过把宿主机的文件系统映射到容器中实现的。实现的方式主要有以下三种:


    1. 数据卷挂载(volume mounts)

    1. 绑定挂载(bind mounts)

    1. volume NFS共享存储模式(推荐)

一,数据卷挂载

  • 卷是绕过联合文件系统的一个或多个容器内的特定目录。卷被设计为保持数据,与容器的生命周期无关。因此,Docker在删除容器时不会自动删除卷,也不会“垃圾收集”不再由容器引用的卷。也称为:数据卷。
  • 需要更详细了解volume可参考官方文档[1]
  • 使用service的方式创建的volume数据卷,该service中的容器只会使用其所在节点服务器的中的volume。当使用本地数据卷驱动时,所用的容器都无法共享其数据。

创建数据卷

    docker@manager1:~$ docker volume create 321


    321
    复制
      docker@manager1:~$ docker volume ls                                                                                                                                 
      DRIVER VOLUME NAME
      local 279da60b1cfc623e3a728a9c0dddca06809105892d6c6c89dc18e077cb0ebdfc
      local 321
      复制

      查看数据卷详细信息

        docker volume inspect <VOLUME-NAME>
        复制
          docker@manager1:~$ docker volume inspect 321 
          [
          {
          "CreatedAt": "2020-01-13T09:27:17Z",
          "Driver": "local",
          "Labels": {},
          "Mountpoint": "/mnt/sda1/var/lib/docker/volumes/321/_data", # 本地位置
          "Name": "321",
          "Options": {},
          "Scope": "local"
          }
          ]


          复制
            docker@manager1:/mnt/sda1/var/lib/docker$ sudo -i                                 
            root@manager1:~# cd mnt/sda1/var/lib/docker/volumes/321/_data/
            root@manager1:/mnt/sda1/var/lib/docker/volumes/321/_data# ll
            root@manager1:/mnt/sda1/var/lib/docker/volumes/321/_data# ls -l
            total 0


            复制
              docker@manager1:~$ docker service create --name mysql_volume_test --mount type=volume,src=321,dst=/root/my_volume --network mynet --replicas 2 haoxy/mysql:5.6


              ms76afxdmswkrxhegdixwmm3i


              overall progress: 2 out of 2 tasks


              1/2: running [==================================================>]


              2/2: running [==================================================>]


              verify: Service converged
              复制
                docker@manager1:~$ docker ps


                CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES


                06ef0693cec6 haoxy/mysql:5.6 "/run.sh" 12 seconds ago Up 11 seconds 3306/tcp mysql_volume_test.2.si4z4ko1jw38uvsc7cquu54pd




                docker@manager1:~$ docker exec -it 06e bin/bash
                root@06ef0693cec6:/# df


                Filesystem 1K-blocks Used Available Use% Mounted on


                overlay 18714000 1750776 15974096 10%


                tmpfs 65536 0 65536 0% dev


                tmpfs 506608 0 506608 0% sys/fs/cgroup


                shm 65536 0 65536 0% dev/shm


                /dev/sda1 18714000 1750776 15974096 10% root/my_volume


                tmpfs 506608 0 506608 0% proc/asound


                tmpfs 506608 0 506608 0% proc/acpi


                tmpfs 506608 0 506608 0% /proc/scsi


                tmpfs 506608 0 506608 0% /sys/firmware


                root@06ef0693cec6:/# cd root/


                root@06ef0693cec6:~# ls


                my_volume


                root@06ef0693cec6:~# cd my_volume/
                root@06ef0693cec6:~/my_volume# ls -l
                total 0
                复制

                加入属性

                  docker service create --name mysql_volume_test --mount type=volume,src=321,dst=/root/my_volume,readonly --network mynet --replicas 2 haoxy/mysql:5.6


                  复制

                  readonly /root/my_volume 只可以读

                  为原来的服务添加volume

                    [root@docker ~]# docker service update website-test --mount-add type=volume,source=data,target=/var/lib/data
                    复制

                    二、 bind 方式

                    与卷相比,(bind)绑定挂到具有有限的功能。当您使用绑定挂载时,宿主机上的文件或目录被挂载到容器中。文件或目录由宿主机上的完整路径或相对路径引用(宿主机上的文件或目录要存在)。相比之下,当您使用卷时,会在宿主机上的Docker存储目录中创建一个新目录,并且Docker会管理该目录的内容。该文件或目录不需要已经存在于Docker宿主机上。如果它尚不存在,它会根据需求创建。绑定挂载非常高效,但它们依赖于具有特定目录结构的主机的文件系统。

                    读写挂载

                      docker service create \
                      --mount type=bind,src=<HOST-PATH>,dst=<CONTAINER-PATH> \
                      --name myservice \
                      <IMAGE>
                      复制

                      只读挂载

                        docker service create \
                        --mount type=bind,src=<HOST-PATH>,dst=<CONTAINER-PATH>,readonly \
                        --name myservice \
                        <IMAGE>
                        复制

                        例:

                          docker service create --name nginx --mount type=bind,target=/usr/share/nginx/html/,source=/opt/web/ --replicas 2 --publish 80:80/tcp nginx


                          docker service create --name bind --mount type=bind,src=/root/db_data,dst=/root/db_data --network mynet --replicas 2 website:7.7


                          docker service create --name bind --mount type=bind,src=/root/db_data,dst=/root/db_data,readonly --network mynet --replicas 2 website:7.7
                          复制

                          重要:虽然绑定挂载能用,但是也有可能导致一些问题:[2]

                          • 如果你挂载了一个主机路径到你的服务容器中,那么这个路径必须存在于 Swarm 集群中的每一个节点。Docker Swarm 调度器会把容器调度到任何满足资源可用性和满足你特定约束、位置偏好的节点上。
                          • 如果运行中的容器变得不健康或者不可用,那么 Docker Swarm 调度器可能会随时重新安排它。
                          • 主机绑定挂载是完全不可移植的。当你使用绑定挂载时,不能保证你的应用在开发中的运行方式与在生产中的运行方式相同。

                          三、通过nfs实现数据持久化

                          整理[3]

                          NFS(Network File System)即网络文件系统,是FreeBSD支持的文件系统中的一种,它允许网络中的计算机之间通过TCP/IP网络共享资源。在NFS的应用中,本地NFS的客户端应用可以透明地读写位于远端NFS服务器上的文件,就像访问本地文件一样。

                          3.1 环境部署

                          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参数说明:

                            • /nfs:nfs上的共享目录;
                            • 172.18.18.0/24:网络中可以访问这个NFS输出目录的主机;
                            • rw:共享目录的权限,rw 是可读写的权限,只读的权限是ro;
                            • sync:同步,数据更安全,速度慢;
                            • async:异步,速度快,效率高,安全性低;
                            • no_root_squash:NFS 服务共享的目录的属性, 如果用户是root, 对这个目录就有root的权限;

                            2、nfs客户端部署

                            在swarm集群所有节点安装部署:

                              [root@Manager ~]#  yum -y install nfs-utils
                              [root@agent01 ~]# yum -y install nfs-utils
                              [root@agent02 ~]# yum -y install nfs-utils
                              复制

                              3.2 使用格式

                                #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>
                                复制

                                3.3 案例演示

                                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
                                  复制

                                  参数说明:

                                  • --replicas:创建3个nginx副本;
                                  • --name:自定义命名为web-nfs;
                                  • type=volume:必须为volume挂载,不能用bind的挂载方式;
                                  • src:src挂载源为nginx-vol,相当于执行了docker volume nginx-vol;
                                  • dst:dst挂载目的路径为nginx容器中的路径/usr/share/nginx/html;
                                  • volume-opt=type=nfs:指定挂载卷类型为nfs模式;
                                  • volume-opt=device=:/nfs:这是nfs服务器共享目录的名称;
                                  • "volume-opt=o=addr=172.18.18.90:指定nfs服务器地址;
                                  • vers=4,soft,timeo=180,bg,tcp,rw:指定nfs版本号、超时时间、后台挂载、协议可选TCP/UDP、读写权限等信息;
                                  • nginx:通过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服务端,就可实现数据的持久化。

                                                参考资料

                                                [1]

                                                官方文档: https://docs.docker.com/storage/volumes/

                                                [2]

                                                重要:虽然绑定挂载能用,但是也有可能导致一些问题:: https://www.jianshu.com/p/b6d1a53f04dd

                                                [3]

                                                整理: https://blog.csdn.net/weixin_34162695/article/details/92978377


                                                最后修改时间:2020-01-25 11:33:51
                                                文章转载自运维笔记本,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                                                评论