• Docker Swarm实现容器的复制均衡及动态管理:详细过程版


    Swarm简介

    Swarm是一套较为简单的工具,用以管理Docker集群,使得Docker集群暴露给用户时相当于一个虚拟的整体。Swarm使用标准的Docker API接口作为其前端访问入口,换言之,各种形式的Docker Client(dockerclient in go, docker_py, docker等)均可以直接与Swarm通信。
    Swarm的设计和其他Docker项目一样,遵循“batteries included but removable”原则

    笔者对该原则的理解是:batteries included代表设计Swarm时,为了完全体现分布式容器集群部署、运行与管理功能的完整性,Swarm和Docker协同工作,Swarm内部包含了一个较为简易的调度模块,以达到对Docker集群调度管理的效果;“but removable”意味着Swarm与Docker并非紧耦合,同时Swarm中的调度模块同样可以定制化,用户可以按照自己的需求,将其替换为更为强大的调度模块,如Mesos等。另外,这套管理引擎并未侵入Docker的使用,这套机制也为其他容器技术的集群部署、运行与管理方式提供了思路。

    Swarm 特点

    对外以Docker API接口呈现,这样带来的好处是,如果现有系统使用Docker Engine,则可以平滑将Docker Engine切到Swarm上,无需改动现有系统。

    Swarm对用户来说,之前使用Docker的经验可以继承过来。非常易上手,学习成本和二次开发成本都比较低。同时Swarm本身专注于Docker集群管理,非常轻量,占用资源也非常少。
    “Batteries included but swappable”,简单说,就是插件化机制,swarm中的各个模块都抽象出了api,可以根据自己一些特点进行定制实现。

    Swarm自身对docker命令参数支持的比较完善,Swarm目前与Docker是同步发布的。Docker的新功能,都会第一时间在Swarm中体现。

    实验开始

    实验环境

    主机 IP 系统 角色

    153 192.168.121.153 centos7 manager

    154 192.168.121.154 centos7 worker

    155 192.168.121.155 centos7 worker

    命令介绍:

    -d 后台运行
    –name 指定server 名,不是容器名(容器命令默认 服务名.编号.随机id串)
    -p 指定service映射的端口
    –network 指定网络
    –mode 指定容器分配的模式(replicated: 随机分配,可由 constraint约束分配到哪些节点 global:全局,确保每个节点都会有该服务的容器)
    –constraint 约束容器分配到哪些节点
    –replicas 指定当前services 下创建的 容器的数量
    –replicas-max-per-node 指定每个节点可创建给service的容器的最大数
    –restart-condition 重启条件,类似于 容器run的 --restart
    –user 指定运行用户身份
    –endpoint-mode 负载均衡模式 vip dns
    nginx:latest 创建容器使用的镜像

    首先准备好三台机子 ,我是用153、154 、155

    每台主机都配置A记录相互解析

    cat /etc/hosts
    127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
    ::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
    192.168.121.153 server153
    192.168.121.154 server154
    192.168.121.155 server155
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    dcoker的安装

    先卸载本机原来的docker,如果主机是干净的就不用执行这步,我是还原的机子,所以这步不执行也没什么

    yum remove docker \
                      docker-client \
                      docker-client-latest \
                      docker-common \
                      docker-latest \
                      docker-latest-logrotate \
                      docker-logrotate \
                      docker-engine
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    然后去官方下载docker的yum源

    sudo yum install -y yum-utils
    sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
    
    • 1
    • 2

    然后下载docker

    sudo yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
    
    • 1

    启动docker

    sudo systemctl start docker
    
    • 1

    swarm集群的创建

    然后我们指定一台153主机构建一个集群并成为管理节点

    [root@server153 ~]# docker swarm init
    Swarm initialized: current node (cul5m5m456oq9wwrbw91i5vsu) is now a manager.
    
    To add a worker to this swarm, run the following command:
    
        docker swarm join --token SWMTKN-1-15p6qvh2u2znrrcslz53inkdhleubl8x9m5xlcm27f9q2eimyl-enul5wbhb6qepej1nod6jdrq2 192.168.121.153:2377
    
    To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    集群构建好以后我们去154和155主机加入这个集群

    [root@server154 ~]# docker swarm join --token SWMTKN-1-15p6qvh2u2znrrcslz53inkdhleubl8x9m5xlcm27f9q2eimyl-enul5wbhb6qepej1nod6jdrq2 192.168.121.153:2377
    This node joined a swarm as a worker.
    
    • 1
    • 2
    [root@server154 ~]# docker swarm join --token SWMTKN-1-15p6qvh2u2znrrcslz53inkdhleubl8x9m5xlcm27f9q2eimyl-enul5wbhb6qepej1nod6jdrq2 192.168.121.153:2377
    This node joined a swarm as a worker.
    
    • 1
    • 2

    然后去153管理主机查看集群情况

    [root@server153 ~]# docker node   ls
    ID                            HOSTNAME    STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
    cul5m5m456oq9wwrbw91i5vsu *   server153   Ready     Active         Leader           24.0.7
    fh23wcmmfmt7vyayh7bzx28ls     server154   Ready     Active                          24.0.7
    5y468v8pk98ei79frycmz9fww     server155   Ready     Active  
    
    • 1
    • 2
    • 3
    • 4
    • 5

    可以看到集群情况都是健康的

    然后开始我们项目的部署

    首先在管理节点创建一个overlay网络给这个集群通信使用

    [root@server153 ~]# docker  network create  --driver overlay  nginx-net
    zwvmf0upuledjh2uarupfnzgt
    [root@server153 ~]# docker network ls
    NETWORK ID     NAME              DRIVER    SCOPE
    db5d2975dd04   bridge            bridge    local
    31eb2f0c4e92   docker_gwbridge   bridge    local
    52a372541a65   host              host      local
    ag7i6g1sb542   ingress           overlay   swarm
    zwvmf0upuled   nginx-net         overlay   swarm
    b95fd0863462   none              null      local
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    service的构建

    然后在每个节点都拉取一个nginx的最新镜像

    当然只在管理节点拉也行,管理节点会将镜像分发给其它节点来保证镜像的一致性

    不过分发镜像需要时间,所以还是先拉取一样的镜像比较好

    为了验证我故意在155节点不拉取镜像

    [root@server153 ~]# docker pull nginx:latest
    [root@server153 ~]# docker images
    REPOSITORY   TAG       IMAGE ID       CREATED      SIZE
    nginx        latest    c20060033e06   3 days ago   187MB
    
    • 1
    • 2
    • 3
    • 4

    然后开始构建service,其中参数不懂得可以对照上面写的,上面开头介绍了用到的参数

    [root@server153 ~]# docker  service  create  -d  --name web -p80:80  --network nginx-net --replicas 3  --replicas-max-per-node 10  --restart-condition  any  --user root  --mode  replicated  nginx:latest
    
    • 1

    然后查看service web下容器的情况

    因为我们指定创建三个容器,刚好每个节点一台

    然后这里注意看155节点容器的运行时间比其它两个节点少一分钟

    那就是因为分发镜像要花时间,他启动的就比其它两个节点晚一分钟,镜像越大分发的时间越长

    [root@server153 ~]# docker service ps web 
    ID             NAME      IMAGE          NODE        DESIRED STATE   CURRENT STATE           ERROR     PORTS
    u4cxfrcd2t4q   web.1     nginx:latest   server153   Running         Running 9 minutes ago             
    w22cnbrdjo24   web.2     nginx:latest   server154   Running         Running 9 minutes ago             
    n2g4nma52mtg   web.3     nginx:latest   server155   Running         Running 8 minutes ago   
    
    • 1
    • 2
    • 3
    • 4
    • 5

    起来了以后我们访问去浏览器访问试试

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    可以看到访问每台机子都是可以的,而且还实现了负载均衡,因为内容一样看不出来,下面我来实验一下

    给三台机子里的文件index.html编辑不同的内容

    [root@server153 ~]# echo 33333333333333333 > ./index.html
    [root@server153 ~]# docker cp ./index.html web.1.qydzc04d6vt4q2ux4uzokir6z:/usr/share/nginx/html/index.html
    Successfully copied 2.05kB to web.1.qydzc04d6vt4q2ux4uzokir6z:/usr/share/nginx/html/index.html
    
    • 1
    • 2
    • 3
    [root@server154 ~]# echo 44444444444444 > ./index.html
    [root@server154 ~]# docker cp ./index.html web.2.d2qto723yk3hqlb76leaps3u5:/usr/share/nginx/html/index.html
    Successfully copied 2.05kB to web.2.d2qto723yk3hqlb76leaps3u5:/usr/share/nginx/html/index.html
    
    • 1
    • 2
    • 3
    [root@server155 ~]# echo 55555555555 > index.php
    [root@server155 ~]# docker cp ./index.php web.3.b41rsxvjxw7br5vxk5d6i74ve:/usr/share/nginx/html/index.html
    Successfully copied 2.05kB to web.3.b41rsxvjxw7br5vxk5d6i74ve:/usr/share/nginx/html/index.html
    
    • 1
    • 2
    • 3

    因为浏览器有缓存,测试不了,我直接用curl测试

    [root@server153 ~]# curl 192.168.121.153
    44444444444444
    [root@server153 ~]# curl 192.168.121.153
    55555555555
    [root@server153 ~]# curl 192.168.121.153
    33333333333333333
    [root@server153 ~]# curl 192.168.121.153
    44444444444444
    [root@server153 ~]# curl 192.168.121.153
    55555555555
    [root@server153 ~]# curl 192.168.121.153
    33333333333333333
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    可以看到我只是访问了153节点,但是却能访问到其它节点的docker的内容

    所以这就是负载均衡的实现,swarm集群会自动实现负载均衡

    docker service scale 的扩展

    docker swarm还可以扩展或缩小容器服务

    下面也展示一下,一开始我们不是指定三个容器而已吗,现在我们扩展为5个,并查看容器情况

    [root@server153 ~]# docker service scale web=5
    web scaled to 5
    overall progress: 5 out of 5 tasks 
    1/5: running   
    2/5: running   
    3/5: running   
    4/5: running   
    5/5: running   
    verify: Service converged 
    [root@server153 ~]# docker service ps web 
    ID             NAME      IMAGE          NODE        DESIRED STATE   CURRENT STATE                ERROR     PORTS
    qydzc04d6vt4   web.1     nginx:latest   server153   Running         Running 46 minutes ago                 
    d2qto723yk3h   web.2     nginx:latest   server154   Running         Running 46 minutes ago                 
    b41rsxvjxw7b   web.3     nginx:latest   server155   Running         Running 46 minutes ago                 
    6tfah9y7hsvi   web.4     nginx:latest   server153   Running         Running about a minute ago             
    a4jxhcyn33ui   web.5     nginx:latest   server155   Running         Running about a minute ago   
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    可以看到我们多出了两个容器,并且由swarm随机分配到其它节点上

    我们去访问试试

    [root@server153 ~]# curl 192.168.121.154
    55555555555
    [root@server153 ~]# curl 192.168.121.154
    33333333333333333
    [root@server153 ~]# curl 192.168.121.154
    44444444444444
    [root@server153 ~]# curl 192.168.121.154
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    <style>
    html { color-scheme: light dark; }
    body { width: 35em; margin: 0 auto;
    font-family: Tahoma, Verdana, Arial, sans-serif; }
    </style>
    </head>
    <body>
    <h1>Welcome to nginx!</h1>
    <p>If you see this page, the nginx web server is successfully installed and
    working. Further configuration is required.</p>
    
    <p>For online documentation and support please refer to
    <a href="http://nginx.org/">nginx.org</a>.<br/>
    Commercial support is available at
    <a href="http://nginx.com/">nginx.com</a>.</p>
    
    <p><em>Thank you for using nginx.</em></p>
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    可以看到不仅访问到了原来我们修改的信息,还访问到了其它信息

    那是因为我们扩展容器节点是创建新的容器,容器里的内容就是原本镜像生成的,所以内容就会变为原来的页面信息,后面真实生产环境中挂volume载数据券就可以保持数据一致了

    docker service scale 的缩小

    当然还有缩小docker服务,这个在高峰访问流量下来以后还是很有用的

    [root@server153 ~]# docker service scale web=2
    web scaled to 2
    overall progress: 2 out of 2 tasks 
    1/2: running   [==================================================>] 
    2/2: running   [==================================================>] 
    verify: Service converged 
    [root@server153 ~]# docker service ps web 
    ID             NAME      IMAGE          NODE        DESIRED STATE   CURRENT STATE               ERROR     PORTS
    qydzc04d6vt4   web.1     nginx:latest   server153   Running         Running about an hour ago             
    d2qto723yk3h   web.2     nginx:latest   server154   Running         Running about an hour ago             
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    可以看到将5个docker服务缩小为2个以后,155节点上的就没有了,这样就减少了资源的消耗

    docker swarm的基本用法就是这样了

    希望对大家有帮助

  • 相关阅读:
    FinalReference 如何使 GC 过程变得拖拖拉拉
    easyexcel升级3.3.4失败的经历
    半监督学习介绍(为什么半监督学习是机器学习的未来)
    c/c++反汇编 | 逆向 | 初级小牛犊
    《永劫无间》找不到ffmpeg.dll无法继续执行怎么办,永劫无间找不到ffmpeg.dll解决方案
    基于springboot爱心捐赠小程序毕业设计-附源码211711
    数据结构学习笔记
    springcloudalibaba架构(7):Sentinel授权规则和系统规则
    代码坏味道与重构之可变数据和发散式变化
    行业洞察 | 谁动了艺术家的奶酪?
  • 原文地址:https://blog.csdn.net/m0_58833554/article/details/134218856