美文网首页Awesome DockerDocker容器虚拟化技术
使用 Docker Swarm 管理 Docker 集群

使用 Docker Swarm 管理 Docker 集群

作者: anyesu | 来源:发表于2018-03-26 22:35 被阅读92次

    前言


    之前介绍了使用 Docker Compose 在一台 Docker 主机下对多服务多容器进行编排,本文来介绍使用 Docker Swarm 实现对多台 Docker 主机的集群管理。

    什么是 Docker Swarm


    Swarm 是 Docker 公司在2014年12月初发布的一套用来管理 Docker 集群的较为简单的工具,由于 Swarm 使用标准的Docker API接口作为其前端访问入口,所以各种形式的Docker Client(dockerclient in go, docker_py, docker等)都可以直接与Swarm通信。老的 Docker Swarm 使用独立的外部KV存储(比如Consul、etcd、zookeeper),搭建独立运行的Docker主机集群,用户像操作单台Docker 机器一样操作整个集群,Docker Swarm 把多台 Docker 主机当做一台 Docker 主机来管理。新的 Swarm mode 是在docker 1.12版本中集成到 Docker 引擎中的,引入服务的概念,提供了众多的新特性,比如:具有容错能力的去中心化设计、内置服务发现、负载均衡、路由网格、动态伸缩、滚动更新、安全传输等。使得 Docker 原生的 Swarm mode 集群具备与 Mesos、Kubernetes 叫板的实力。

    配置说明


    有两台主机(主机1、主机2),都已安装docker。当然也可以使用三剑客之一的 Docker Machine 来创建一批运行 Docker 的虚拟机。

    创建集群


    在主机1上创建 swarm 集群,主机1作为 manager 节点

    $ docker swarm init --listen-addr 0.0.0.0:2377 --advertise-addr 主机1的IP
    Swarm initialized: current node (kwsp26dy6gwjhocl6nxbez0bu) is now a manager.
    
    To add a worker to this swarm, run the following command:
    
        docker swarm join --token SWMTKN-1-1023ixl3yabjyws8tjdyvob7r40mljsu8atzsmlju18wz2itlj-br6gzae8focpm0ccpjaquz251 主机1的IP:2377
    
    To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
    

    注意:主机1的防火墙要开放对应的端口

    加入集群


    主机2作为 worker 节点加入上面创建的集群

    # 也就是上面创建完集群提示的命令
    docker swarm join --token SWMTKN-1-1023ixl3yabjyws8tjdyvob7r40mljsu8atzsmlju18wz2itlj-br6gzae8focpm0ccpjaquz251 主机1的IP:2377
    

    当然,主机2也可作为 manager 节点加入上面创建的集群,当主机1挂掉的时候它可以晋升为 Leader。

    在主机1上查询对应的 token

    $ docker swarm join-token manager
    To add a manager to this swarm, run the following command:
    
        docker swarm join --token SWMTKN-1-1023ixl3yabjyws8tjdyvob7r40mljsu8atzsmlju18wz2itlj-07q9wti67nkvqixykkcbi1ge8 119.27.177.81:2377
    

    主机2上执行对应的命令,可以添加 --listen-addr 和 --advertise-addr 参数(同创建集群)

    docker swarm join --token SWMTKN-1-1023ixl3yabjyws8tjdyvob7r40mljsu8atzsmlju18wz2itlj-07q9wti67nkvqixykkcbi1ge8 119.27.177.81:2377
    

    查看集群节点


    $ docker node ls
    ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
    kwsp26dy6gwjhocl6nxbez0bu *   主机1               Ready               Active              Leader              18.03.0-ce
    19nnijmzs16o1f92e6wdmltsf     主机2               Ready               Active              Reachable           18.03.0-ce
    

    创建一个 overlay 网络


    docker network create --driver overlay network_swarm
    

    在 swarm 集群上创建服务,并指定使用的网络


    docker service create --replicas 2 --name service_test --network=network_swarm nginx:alpine
    

    查看服务状态


    $ docker service ls
    ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
    yp2tn16eqaqc        service_test        replicated          2/2                 nginx:alpine
    
    $ docker service ps service_test
    ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE           ERROR               PORTS
    8mgu08gmy0bf        service_test.1      nginx:alpine        主机1               Running             Running 4 minutes ago
    310uv4k6aro8        service_test.2      nginx:alpine        主机2               Running             Running 4 minutes ago
    

    主机1上查看容器

    $ docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS               NAMES
    d9df9c365d68        nginx:alpine        "nginx -g 'daemon of…"   About a minute ago   Up About a minute   80/tcp              service_test.1.8mgu08gmy0bf9pxovz5zxn8ih
    

    主机2上查看容器

    $ docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
    43704a7989ed        nginx:alpine        "nginx -g 'daemon of…"   About a minute ago   Up 2 minutes        80/tcp                   service_test.2.310uv4k6aro8n47c37zj0w1c8
    

    可以看到有一个服务名为 service_test,有两个实例(service_test.1.xxx 和 service_test.2.xxx)分别部署在两台机器上。

    调整服务的实例个数


    $ docker service scale service_test=3
    service_test scaled to 3
    overall progress: 3 out of 3 tasks
    1/3: running   [==================================================>]
    2/3: running   [==================================================>]
    3/3: running   [==================================================>]
    verify: Service converged
    
    # 主机1
    $ docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
    ed226d0dc795        nginx:alpine        "nginx -g 'daemon of…"   24 seconds ago      Up 23 seconds       80/tcp              service_test.3.u6iop1v2gup15asywx6g927vo
    d9df9c365d68        nginx:alpine        "nginx -g 'daemon of…"   2 minutes ago       Up 8 minutes        80/tcp              service_test.1.8mgu08gmy0bf9pxovz5zxn8ih
    

    服务发现与自动恢复


    手动删除或关闭运行中的容器,过几秒之后就能发现 Swarm 会创建新的容器来顶替失效的容器。

    负载均衡


    在单机模式下进行测试,情况会简单点

    1. 删除已有的服务
    docker service rm service_test
    
    1. worker 节点退出集群,使 manager 节点成为单节点的集群
    docker swarm leave
    
    1. 创建带端口映射的服务 service_test
    docker service create --replicas 2 --name service_test -p 80:80 --network=network_swarm nginx:alpine
    
    1. 创建作为干扰的服务 service_test2 (和 service_test 共用一个网络)
    docker service create --replicas 1 --name service_test2 -p 81:80 --network=network_swarm nginx:alpine
    
    1. 查看所有容器
    $ docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS               NAMES
    c2d9a5111659        nginx:alpine        "nginx -g 'daemon of…"   19 seconds ago       Up 17 seconds       80/tcp              service_test2.1.rdseqv5oq2cli3vojsk5unibm
    cf09fa224a32        nginx:alpine        "nginx -g 'daemon of…"   About a minute ago   Up About a minute   80/tcp              service_test.2.xdl050dxdrzfpdzjwjf40mook
    1b998a72b03b        nginx:alpine        "nginx -g 'daemon of…"   About a minute ago   Up About a minute   80/tcp              service_test.1.fgu08x9mi33xd002ctdjoeyv0
    
    1. 修改每个nginx的页面内容
    # 注意:容器id修改为实际的容器id
    # service_test.1
    docker exec -i 1b sed -i 's$<title>Welcome to nginx!</title>$<title>Welcome to nginx-1!</title>$' /usr/share/nginx/html/index.html
    # service_test.2
    docker exec -i cf sed -i 's$<title>Welcome to nginx!</title>$<title>Welcome to nginx-2!</title>$' /usr/share/nginx/html/index.html
    # service_test2.1
    docker exec -i c2 sed -i 's$<title>Welcome to nginx!</title>$<title>Welcome to nginx-3!</title>$' /usr/share/nginx/html/index.html
    
    1. 查看效果
    $ curl 127.0.0.1:81|grep title
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100   614  100   614    0     0   181k      0 --:--:-- --:--:-- --:--:--  199k
    <title>Welcome to nginx-3!</title>
    $ curl 127.0.0.1|grep title
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100   614  100   614    0     0   196k      0 --:--:-- --:--:-- --:--:--  299k
    <title>Welcome to nginx-2!</title>
    $ curl 127.0.0.1|grep title
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100   614  100   614    0     0   164k      0 --:--:-- --:--:-- --:--:--  299k
    <title>Welcome to nginx-1!</title>
    curl 127.0.0.1|grep title
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100   614  100   614    0     0   174k      0 --:--:-- --:--:-- --:--:--  299k
    <title>Welcome to nginx-2!</title>
    ...
    

    可以看出访问80端口会交替访问 service_test.1 和 service_test.2 且不会转发到 service_test2.1 上,说明负载均衡成功。

    1. 查看宿主机的 NAT 映射情况
    $ sudo iptables -t nat -nL
    ...
    Chain DOCKER-INGRESS (2 references)
    target     prot opt source               destination
    DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:81 to:172.18.0.2:81
    DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:80 to:172.18.0.2:80
    RETURN     all  --  0.0.0.0/0            0.0.0.0/0
    

    可以看出宿主机的80端口被映射到了 172.18.0.2 的80端口上,而这个 172.18.0.2 的ip就属于 overlay 网络 network_swarm。对于 overlay 网络的原理不是很清楚,也没深入研究下去,有了解的小伙伴欢迎指教。不过,我猜测应该是 overlay 网络内部实现了某种一对多的端口映射从而实现负载均衡的效果。

    使用Docker Stack 部署多服务集群(参考


    Docker Swarm 只能实现对单个服务的简单部署,如果要实现和 Docker-compose 一样的多服务编排就需要用到 Docker Stack 命令,具体用法请看另一篇文章

    Swarm的不足


    • 功能简单有限
    • 当集群中某台机器的资源(cpu、内存等)不足时,Swarm在部署服务的时候还是会傻傻地平均分配容器到这台机器上。

    常用命令


    • docker swarm 命令用于管理 Swarm 群集
    命令 描述
    docker swarm init 初始化一个 swarm 群集
    docker swarm join 加入群集作为节点或管理器
    docker swarm join-token 管理用于加入群集的令牌
    docker swarm leave 离开 swarm 群集
    docker swarm unlock 解锁 swarm 群集
    docker swarm unlock-key 管理解锁钥匙
    docker swarm update 更新 swarm 群集
    • docker node 命令用于管理 Swarm 群集中的机器节点
    命令 描述
    docker node demote 从 swarm 群集管理器中降级一个或多个节点
    docker node inspect 显示一个或多个节点的详细信息
    docker node ls 列出 swarm 群集中的节点
    docker node promote 将一个或多个节点推入到群集管理器中
    docker node ps 列出在一个或多个节点上运行的任务,默认为当前节点
    docker node rm 从 swarm 群集删除一个或多个节点
    docker node update 更新一个节点
    • docker service 命令用于管理服务
    命令 描述
    docker service create 创建服务
    docker service inspect 显示一个或多个服务的详细信息
    docker service logs 获取服务的日志
    docker service ls 列出服务
    docker service rm 删除一个或多个服务
    docker service scale 设置服务的实例数量
    docker service update 更新服务
    docker service rollback 恢复服务至update之前的配置

    系列文章


    Docker 学习总结

    使用Dockerfile构建镜像

    使用Docker-compose构建容器

    Docker Daemon连接方式详解

    Docker下的网络模式


    转载请注明出处:https://www.jianshu.com/p/47fa426ff767

    相关文章

      网友评论

        本文标题:使用 Docker Swarm 管理 Docker 集群

        本文链接:https://www.haomeiwen.com/subject/qtddcftx.html