zoukankan      html  css  js  c++  java
  • DockerSwarm 集群环境搭建

    一、简介

    1. 什么是docker swarm?

    Swarm 在 Docker 1.12 版本之前属于一个独立的项目,在 Docker 1.12 版本发布之后,该项目合并到了 Docker 中,成为 Docker 的一个子命令。目前,Swarm 是 Docker 社区提供的唯一一个原生支持 Docker 集群管理的工具。它可以把多个 Docker 主机组成的系统转换为单一的虚拟 Docker 主机,使得容器可以组成跨主机的子网网络。

    Docker Swarm 是一个为 IT 运维团队提供集群和调度能力的编排工具。用户可以把集群中所有 Docker Engine 整合进一个「虚拟 Engine」的资源池,通过执行命令与单一的主 Swarm 进行沟通,而不必分别和每个 Docker Engine 沟通。在灵活的调度策略下,IT 团队可以更好地管理可用的主机资源,保证应用容器的高效运行。

    Swarm的基本架构如下图所示:

    2. Docker Swarm 优点

    任何规模都有高性能表现
    对于企业级的 Docker Engine 集群和容器调度而言,可拓展性是关键。任何规模的公司——不论是拥有五个还是上千个服务器——都能在其环境下有效使用 Swarm。
    经过测试,Swarm 可拓展性的极限是在 1000 个节点上运行 50000 个部署容器,每个容器的启动时间为亚秒级,同时性能无减损。

    灵活的容器调度

    Swarm 帮助 IT 运维团队在有限条件下将性能表现和资源利用最优化。Swarm 的内置调度器(scheduler)支持多种过滤器,包括:节点标签,亲和性和多种容器部策略如 binpack、spread、random 等等。

    服务的持续可用性

    Docker Swarm 由 Swarm Manager 提供高可用性,通过创建多个 Swarm master 节点和制定主 master 节点宕机时的备选策略。如果一个 master 节点宕机,那么一个 slave 节点就会被升格为 master 节点,直到原来的 master 节点恢复正常。
    此外,如果某个节点无法加入集群,Swarm 会继续尝试加入,并提供错误警报和日志。在节点出错时,Swarm 现在可以尝试把容器重新调度到正常的节点上去。

    和 Docker API 及整合支持的兼容性

    Swarm 对 Docker API 完全支持,这意味着它能为使用不同 Docker 工具(如 Docker CLI,Compose,Trusted Registry,Hub 和 UCP)的用户提供无缝衔接的使用体验。

    Docker Swarm 为 Docker 化应用的核心功能(诸如多主机网络和存储卷管理)提供原生支持

    开发的 Compose 文件能(通过 docker-compose up )轻易地部署到测试服务器或 Swarm 集群上。Docker Swarm 还可以从 Docker Trusted Registry 或 Hub 里 pull 并 run 镜像。

    二、相关概念

    1. 节点

    有两种类型的节点: managersworkers.

    管理节点(managers)

    管理节点用于 Swarm 集群的管理,docker swarm 命令基本只能在管理节点执行(节点退出集群命令 docker swarm leave 可以在工作节点执行)。一个 Swarm 集群可以有多个管理节点,但只有一个管理节点可以成为 leader,leader 通过 raft 协议实现。

    为了利用swarm模式的容错功能,Docker建议您根据组织的高可用性要求实现奇数个节点。当您拥有多个管理器时,您可以从管理器节点的故障中恢复而无需停机。

    • N个管理节点的集群容忍最多损失 (N-1)/2 个管理节点。
    • Docker建议一个集群最多7个管理器节点。

    重要说明:添加更多管理节点并不意味着可扩展性更高或性能更高。一般而言,情况正好相反。

    工作节点(workers)

    工作节点是任务执行节点,管理节点将服务 (service) 下发至工作节点执行。管理节点默认也作为工作节点。你也可以通过配置让服务只运行在管理节点。下图展示了集群中管理节点与工作节点的关系。

    2. 服务和任务

    任务 (Task)是 Swarm 中的最小的调度单位,目前来说就是一个单一的容器。
    服务 (Services) 是指一组任务的集合,服务定义了任务的属性。服务有两种模式:

    • replicated services (复制服务)按照一定规则在各个工作节点上运行指定个数的任务。
    • global services (全局服务)每个工作节点上运行一个任务。

    两种模式通过 docker service create 的 --mode 参数指定。下图展示了容器、任务、服务的关系。

    三、Swarm 集群

    准备工作

    • 三个可以通过网络进行通信的Linux主机或虚拟机,并安装了Docker,或者使用docker-machine 创建三台虚拟机。
    • 已安装Docker Engine 1.12或更高版本
    • 在主机之间打开端口(2377、7946、4789)

    创建一个集群

    1. 创建虚拟机(已经有Linux主机或虚拟机的跳过此步)

    本文通过docker-machine使用VirtualBox驱动程序创建3个VM (已经有Linux主机或虚拟机的跳过此步):

    docker-machine create --driver virtualbox myvm-1
    docker-machine create --driver virtualbox myvm-2
    docker-machine create --driver virtualbox myvm-3
    

    列出虚拟机并获取其IP地址:

    docker-machine ls
    

    以下是此命令的示例输出:

    $docker-machine ls
    NAME     ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER           ERRORS
    myvm-1   -        virtualbox   Running   tcp://192.168.99.100:2376           v18.09.1-beta2   
    myvm-2   -        virtualbox   Running   tcp://192.168.99.101:2376           v18.09.1-beta2   
    myvm-3   -        virtualbox   Running   tcp://192.168.99.102:2376           v18.09.1-beta2  
    

    2. 初始化swarm

    把第一台机器myvm-1充当管理节点,第二台myvm-2 、第三台myvm-3为工作节点。

    使用 docker-machine ssh 连接 myvm-1,Linux主机直接ssh连接就行。

    docker-machine ssh myvm-1 
    

    初始化swarm

    docker swarm init --advertise-addr 192.168.99.100
    Swarm initialized: current node (4a8mo8cekpe0vpk0ze963avw9) is now a manager.
    
    To add a worker to this swarm, run the following command:
    
        docker swarm join --token SWMTKN-1-4lzr2216s61ecbyayyqynjwybmxy5y5th5ru8aal2a0d1t2vn3-ekdgf4swlz8fiq4nnzgnbhr5u 192.168.99.100:2377
    
    To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
    

    上面输出的这一段就是工作节点加入集群的命令:

    docker swarm join --token SWMTKN-1-4lzr2216s61ecbyayyqynjwybmxy5y5th5ru8aal2a0d1t2vn3-ekdgf4swlz8fiq4nnzgnbhr5u 192.168.99.100:2377
    

    如果你的 Docker 主机有多个网卡,拥有多个 IP,必须使用 --advertise-addr 指定 IP。
    执行 docker swarm init 命令的节点自动成为管理节点。

    命令 docker info 可以查看 swarm 集群状态:

    Server Version: 18.09.1-beta2
    Storage Driver: overlay2
     Backing Filesystem: extfs
     Supports d_type: true
     Native Overlay Diff: true
    Logging Driver: json-file
    Cgroup Driver: cgroupfs
    Plugins:
     Volume: local
     Network: bridge host macvlan null overlay
     Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
    Swarm: active
     NodeID: ib1498ex2q18i7gznb2zgicqq
     Is Manager: true
     ClusterID: fbyxxjzrtcxc53op35jnyzl7t
     Managers: 3
     Nodes: 3
     Default Address Pool: 10.0.0.0/8  
    

    命令 docker node ls 可以查看集群节点信息:

    $docker node ls
    ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
    ib1498ex2q18i7gznb2zgicqq *   myvm-1              Ready               Active              Leader              18.09.1-beta2
    

    3. 工作节点加入 swarm 集群

    连接机器myvm-2

    docker-machine ssh myvm-2
    

    加入 swarm 集群

    $docker swarm join 
        --token SWMTKN-1-4lzr2216s61ecbyayyqynjwybmxy5y5th5ru8aal2a0d1t2vn3-ekdgf4swlz8fiq4nnzgnbhr5u 
        192.168.99.100:2377
    
    This node joined a swarm as a worker.
    

    节点myvm-3,执行myvm-2相同的操作加入集群。

    集群的大部分命令需要在管理节点中才能运行

    我们进入管理节点 myvm-1 ,查看集群的节点信息。

    docker node ls
    ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
    ib1498ex2q18i7gznb2zgicqq *   myvm-1              Ready               Active              Leader              18.09.1-beta2
    vels0fe3eh5s5cxj1s573v9wx     myvm-2              Ready               Active                                  18.09.1-beta2
    obxnnqelh4p16wajrwvyn6j8v     myvm-3              Ready               Active                                  18.09.1-beta2
    

    为了高可用,我们升级工作节点为管理节点。

    docker node promote myvm-2
    docker node promote myvm-3
    

    这时我们再看集群的节点信息

    $ docker node ls
    ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
    ib1498ex2q18i7gznb2zgicqq *   myvm-1              Ready               Active              Leader              18.09.1-beta2
    vels0fe3eh5s5cxj1s573v9wx     myvm-2              Ready               Active              Reachable           18.09.1-beta2
    obxnnqelh4p16wajrwvyn6j8v     myvm-3              Ready               Active              Reachable           18.09.1-beta2
    

    myvm-2、myvm-3的 集群状态变为 Reachable(选举者),因为集群中节点Leader只能有一个,这个类似zookeeper,只不过zookeepers用的算法是paxos,Swarm用的算法是raft。

    4. 退出 Swarm 集群

    如果 Manager 想要退出 Swarm 集群, 在 Manager Node 上执行如下命令:

    docker swarm leave
    

    如果集群中还存在其它的 Worker Node,还希望 Manager 退出集群,则加上一个强制选项,命令行如下所示:

    docker swarm leave --force
    

    工作节点进行退出集群,需要在工作节点上执行命令:

    docker swarm leave
    

    退出后的节点,依然可以使用 上面的 docker swarm join --token 重新加入集群。

    集群上部署应用

    命令

    $ docker service create --replicas 1 --name 别名  镜像ID
    

    replicas 指定运行服务的数量。

    实例1

    创建一个alpine服务(alpine是一个小型liunx系统)

    #运行一个alpine镜像,并执行ping命令
    docker service create --replicas 1 --name test1 alpine ping docker.com
    

    查看集群上的服务

    $docker service ls
    ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
    rnu10rprrwzv        test1               replicated          1/1                 alpine:latest
    

    实例2

    以下命令将nginx容器中的端口80发布到群集中任何节点的端口8080

    docker service create 
      --name my-web 
      --publish published=8080,target=80 
      --replicas 2 
      nginx
    

    查看集群上的服务

    $ docker service ls
    ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
    q6wfiizzosmd        nginx               replicated          3/3                 nginx:latest        *:8080->80/tcp
    rnu10rprrwzv        test1               replicated          1/1                 alpine:latest 
    

    service 通过 ingress load balancing 来发布服务,且 swarm 集群中所有 node 都参与到 ingress 路由网格(ingress routing mesh) 中,访问任意一个 node+PublishedPort 即可访问到服务。

    当访问任何节点上的端口8080时,Docker将您的请求路由到活动容器。在群节点本身,端口8080可能并不实际绑定,但路由网格知道如何路由流量,并防止任何端口冲突的发生。

    路由网格在发布的端口上监听分配给节点的任何IP地址。对于外部可路由的IP地址,该端口可从主机外部获得。对于所有其他IP地址,只能从主机内部访问。

    所以访问 192.169.99.100:8080、192.169.99.101:8080、192.169.99.102:8080 ,都可以访问到nginx,这样就实现了负载均衡。因为我们指定--replicas 3 启动了3个运行nginx的容器 ,所以三个节点myvm-1、myvm-2、myvm-3 上都运行了一个 nginx 的容器,可以通过改其中一个节点上的nginx的欢迎页 ,然后再访问,来检查是否实现了负载均衡。

    可以通过scale 来指定运行容器的数量。

     docker service scale nginx=2
    

    我通过docker service ls 可以看出 nginx 的副本变成了2个

    $docker service ls
    ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
    q6wfiizzosmd        nginx               replicated          2/2                 nginx:latest        *:8080->80/tcp
    

    overlay 网络

    1. 概述

    初始化swarm或将Docker主机加入现有swarm时,会在该Docker主机上创建两个新网络:

    • ingress:称为覆盖网络ingress,处理与群集服务相关的控制和数据流量。创建群组服务并且不将其连接到用户定义的覆盖网络时,ingress 是默认连接的网络。
    • docker_gwbridge:称为桥接网络docker_gwbridge,它将各个Docker守护程序连接到参与该群集的其他守护进程。

    在管理节点上查看网络

    $ docker network ls
    NETWORK ID          NAME                DRIVER              SCOPE
    cb0ccb89a988        bridge              bridge              local
    0174fb113496        docker_gwbridge     bridge              local
    541b62778c0e        host                host                local
    8n7xppn5z4j2        ingress             overlay             swarm
    369d459f340d        none                null                local
    

    overlay网络驱动程序会创建多个Docker守护主机之间的分布式网络。该网络位于(覆盖)特定于主机的网络之上,允许连接到它的容器(包括群集服务容器)安全地进行通信。Docker透明地处理每个数据包与正确的Docker守护程序主机和正确的目标容器的路由。

    2. 自定义 overlay 网络

    创建用于swarm服务的overlay网络,使用如下命令:

    docker network create -d overlay my-overlay
    

    我们再次查看网络,发现可以看到自定义 overlay了。

    $docker network ls
    NETWORK ID          NAME                DRIVER              SCOPE
    cb0ccb89a988        bridge              bridge              local
    0174fb113496        docker_gwbridge     bridge              local
    541b62778c0e        host                host                local
    8n7xppn5z4j2        ingress             overlay             swarm
    a23htz7n0pvp        my-overlay          overlay             swarm
    369d459f340d        none                null                local
    

    集群中部署了两个服务 nginx、alpine,现在我们进入alpine,去访问nginx。

     docker exec -it test1.1.oonwl8c5g4u3p17x8anifeubi bash
    
    / # ping nginx
    ping: bad address 'nginx'
    
    wget 192.168.99.100:8080
    Connecting to 192.168.99.100:8080 (192.168.99.100:8080)
    index.html           100% |*************************************************************************************************************|   612   0:00:00 ETA
    
    

    我们发现集群中的各个服务不能用名称访问的,只能用集群服务发现的路由网络访问,那么集群中的服务怎么能通过名称进行访问呢,这就需要用到上面自定义的 overlay 网络。

    删除我们启动的服务,重新创建指定使用自定义网络的服务。

    docker service rm nginx test1
    
    docker service create --name nginx -p 8080:80 --network my-overlay --replicas 3 nginx
    docker service create --name test1 --network my-overlay alpine ping www.baidu.com
    

    进入test1容器中,重新测试下:

    / # ping nginx
    PING nginx (10.0.0.2): 56 data bytes
    64 bytes from 10.0.0.2: seq=0 ttl=64 time=0.120 ms
    64 bytes from 10.0.0.2: seq=1 ttl=64 time=0.094 ms
    64 bytes from 10.0.0.2: seq=2 ttl=64 time=0.108 ms
    
    / # wget nginx
    Connecting to nginx (10.0.0.2:80)
    index.html           100% |*************************************************************************************************************|   612   0:00:00 ETA
    

    发现可以通过名称进行集群中的容器间的访问了。




    欢迎扫码或微信搜索公众号《程序员果果》关注我,关注有惊喜~

  • 相关阅读:
    JavaScript进阶-BOM和DOM
    JavaScript基础
    CSS2-属性
    CSS1-选择器
    HTML-常用标签
    判断回文
    课堂作业
    动手动脑
    原码反码补码
    Java第一次考试作业
  • 原文地址:https://www.cnblogs.com/huanchupkblog/p/10851195.html
Copyright © 2011-2022 走看看