美文网首页
10、Swarm容器集群管理

10、Swarm容器集群管理

作者: 六弦极品 | 来源:发表于2019-05-18 22:03 被阅读0次

    1、 Swarm介绍

    Swarm是Docker公司自研发的容器集群管理系统,Swarm在早期是作为一个独立服务存在,在Docker Engine v1.12中集成了Swarm的集群管理 和编排功能。可以通过初始化Swarm或加入现有Swarm来启用Docker引擎的Swarm模式。
    Docker Engine CLI和API包括了管理Swarm节点命令,比如添加、删除节点,以及在Swarm中部署和编排服务。 也增加了服务栈(Stack)、服务(Service)、任务(Task)概念。


    swarm架构.png

    处理逻辑流程:
    docker客户端发送服务请求---->API接收请求并创建对象--->创建对象服务任务--->给任务分配IP地址--->将任务分配到某个节点--->将任务下发到某个工作节点----> 创建容器
    Swarm两个角色:
    Manager:接收客户端服务定义,将任务发送到worker节点;维护集群期望状态和集群管理功能及Leader选举。默认情况下manager节点也会运行任务,也可以配置只做管理任务。利用RAFT协议保持Manager状态一致性。
    Worker:接收并执行从管理节点分配的任务,并报告任务当前状态,以便管理节点维护每个服务期望状态。

    3nginx_replicas.png

    创建一个3个副本nginx 的服务发送到manager节点,然后manager节点将三个副本分配到可用到节点上,nginx.1就是第一个任务。

    Swarm特点:
    1⃣️. Docker Engine集成集群管理
    使用Docker Engine CLI 创建一个Docker Engine的Swarm模式,在集群中部署应用程序服务。
    2⃣️. 去中心化设计
    Swarm角色分为Manager和Worker节点,Manager节点故障不影响应用使用。
    3⃣️. 扩容缩容
    可以声明每个服务运行的容器数量,通过添加或删除容器数自动调整期望的状态。
    4⃣️. 期望状态协调
    Swarm Manager节点不断监视集群状态,并调整当前状态与期望状态之间的差异。
    5⃣️. 多主机网络
    可以为服务指定overlay网络。当初始化或更新应用程序时,Swarm manager会自动为overlay网络上的容器分配IP地址。
    6⃣️. 服务发现
    Swarm manager节点为集群中的每个服务分配唯一的DNS记录和负载均衡VIP。可以通过Swarm内置的DNS服务器查询集群中每个运行的容器。
    7⃣️. 负载均衡
    实现服务副本负载均衡,提供入口访问。
    8⃣️. 安全传输
    Swarm中的每个节点使用TLS相互验证和加密,确保安全的其他节点通信。
    9⃣️. 滚动更新
    升级时,逐步将应用服务更新到节点,如果出现问题,可以将任务回滚到先前版本。

    Manager Worker
    Manager 10.40.6.167
    Worker01 10.40.6.166
    Worker02 10.40.6.165

    在三个节点防火墙对网段开放:iptables -I INPUT -s 10.40.6.0/23 -j ACCEPT
    初始化swarm:docker swarm init --help

    2、集群部署

    使用Swarm前提:
    1⃣️.Docker版本1.12+
    2⃣️.集群节点之间保证TCP 2377(集群管理)、TCP/UDP 7946(容器网络发现)和UDP 4789(Overlay网络)端口通信 节点规划:
    操作系统:CentOS7.4_x64

    管理节点初始化Swarm:

    # docker swarm init --advertise-addr 10.40.6.167
    Swarm initialized: current node (y7kvs1pl3ydu990k0lv2j846m) is now a manager.
    
    To add a worker to this swarm, run the following command:
    
        docker swarm join --token SWMTKN-1-2ya3gjj6z8hdz8kraebib9v194t4fqjqyu3imjtcnax9awk7dk-7gmmejuor1vodojqwdb5y8r13 10.40.6.167:2377
    
    To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
    

    工作节点加入Swarm:docker swarm join --token SWMTKN-1-XXX 10.40.6.167:2377

    # docker swarm join --token SWMTKN-1-2ya3gjj6z8hdz8kraebib9v194t4fqjqyu3imjtcnax9awk7dk-7gmmejuor1vodojqwdb5y8r13 10.40.6.167:2377
    This node joined a swarm as a worker.
    
    ###注意主机时间保持一致,免得出现证书过期问题:
    Error response from daemon: error while validating Root CA Certificate: x509: certificate has expired or is not yet valid
    

    在管理节点上查看节点:

    # docker node ls
    ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
    y7kvs1pl3ydu990k0lv2j846m *   docker-manager01    Ready               Active              Leader              18.09.6
    gv4r5k331flafgeedre6btwkh     docker-work01       Ready               Active                                  18.09.6
    lci41ilcev8jyjit4pbtslufv     docker-work02       Ready               Active                                  18.09.6
    

    3、 节点管理

    docker node COMMAND 管理Swarm节点:

    # docker node --help
    
    Usage:  docker node COMMAND
    
    Manage Swarm nodes
    
    Commands:
      demote      Demote one or more nodes from manager in the swarm
      inspect     Display detailed information on one or more nodes
      ls          List nodes in the swarm
      promote     Promote one or more nodes to manager in the swarm
      ps          List tasks running on one or more nodes, defaults to current node
      rm          Remove one or more nodes from the swarm
      update      Update a node
    
    Run 'docker node COMMAND --help' for more information on a command.
    

    4、 服务管理

    docker service --help
    配置docker镜像源文件:/etc/docker/daemon.json

    ### 创建服务
    # docker service create --replicas 1 --name hello busybox ping www.baidu.com
    
    ### 显示服务详细信息
    # docker service inspect --pretty hello 
    
    ### 易于阅读显示 
    # docker service inspect hello # json格式返回
    
    ### 扩展服务实例数
    # docker service scale hello=3
    
    ### 查看服务任务 
    # docker service ls
    # docker service ps hello
    # docker service ps -f 'desired-state=running' hello
    
    ### 滚动更新服务 
    # docker service create --replicas 3 --name redis --update-delay 10s redis:3.0.6 
    # docker service update --image redis:3.0.7 redis
    
    ### 创建服务时设定更新策略
    # docker service create \
    --name my_web \
    --replicas 10 \
    --update-delay 10s \ 
    --update-parallelism 2 \ 
    --update-failure-action continue \
    nginx:1.12
    
    ### 创建服务时设定回滚策略
    # docker service create \
    --name my_web \
    --replicas 10 \ 
    --rollback-parallelism 2 \
    --rollback-monitor 20s \
    --rollback-max-failure-ratio .2 \
    nginx:1.12
    
    ### 服务更新
    # docker service update --image nginx:1.13 my_web
    
    ### 手动回滚
    # docker service update --rollback my_web
    

    5、管理应用程序数据

    (1) Volume
    创建数据卷:

    # docker service create \
      --mount type=volume,src=<VOLUME-NAME>,dst=<CONTAINER-PATH> \
      --name myservice \
      <IMAGE>
    

    查看数据卷详细信息:

    # docker volume inspect <VOLUME-NAME>
    

    (2) Bind Mounts
    读写挂载:

    # 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>,ro \
      --name myservice \
      <IMAGE>
    

    NFS数据持久存储:

    ###安装一个NFS服务:
    # yum install nfs-utils -y
    # cat # cat /etc/exports
    /nfs_data/     10.40.6.0/23(rw,sync,no_root_squash,no_all_squash)
    # mkdir  /nfs_data
    ###每个结果都安装一下客户端:
    # yum install nfs-utils -y
    
    
    ### 格式:
    # docker service create --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"' \
     --name myservice <IMAGE>
    
    ### 实例:
    # # docker service create --mount 'type=volume,src=nfs-vol,dst=/usr/share/nginx/html,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/nfs_data,"volume-opt=o=addr=10.4.4.151,vers=4,soft,timeo=180,bg,tcp,rw"' --name nfs-nginx 10.40.6.165/library/nginx:v1
    
    # docker service ps nfs-nginx
    ID                  NAME                IMAGE                          NODE                DESIRED STATE       CURRENT STATE            ERROR               PORTS
    j81r9oh3xgrs        nfs-nginx.1         10.40.6.165/library/nginx:v1   docker-work01       Running             Running 30 seconds ago
    
    # df -h   ### nfs共享目录挂载到节点上
       .....
    :/nfs_data                76G  8.7G   67G  12% /var/lib/docker/volumes/nfs-vol/_data
    
    # docker volume ls
    DRIVER              VOLUME NAME
    local               nfs-vol
    
    # docker ps -l
    CONTAINER ID        IMAGE                          COMMAND                  CREATED              STATUS              PORTS               NAMES
    8774783e0cac        10.40.6.165/library/nginx:v1   "nginx -g 'daemon of…"   About a minute ago   Up About a minute   80/tcp              nfs-nginx.1.j81r9oh3xgrsyudujxzfss0kw
    # docker exec -it 8774783e0cac bash
    [root@8774783e0cac nginx]# ls /usr/share/nginx/html/
    aaa
    
    ### 增加到三个实例
    # docker service scale nfs-nginx=3
    nfs-nginx scaled to 3
    overall progress: 3 out of 3 tasks 
    1/3: running   [==================================================>] 
    2/3: running   [==================================================>] 
    3/3: running   [==================================================>] 
    verify: Service converged 
    
    # docker service ps nfs-nginx
    ID                  NAME                IMAGE                          NODE                DESIRED STATE       CURRENT STATE            ERROR               PORTS
    j81r9oh3xgrs        nfs-nginx.1         10.40.6.165/library/nginx:v1   docker-work01       Running             Running 4 minutes ago                        
    matq9qdwx12r        nfs-nginx.2         10.40.6.165/library/nginx:v1   docker-work02       Running             Running 26 seconds ago                       
    tklrm734ukkm        nfs-nginx.3         10.40.6.165/library/nginx:v1   docker-manager01    Running             Running 26 seconds ago
    
    ###缩容到2个实例
    # docker service scale nfs-nginx=2
    nfs-nginx scaled to 2
    overall progress: 2 out of 2 tasks 
    1/2: running   [==================================================>] 
    2/2: running   [==================================================>] 
    verify: Service converged 
    # docker service ps nfs-nginx
    ID                  NAME                IMAGE                          NODE                DESIRED STATE       CURRENT STATE           ERROR               PORTS
    j81r9oh3xgrs        nfs-nginx.1         10.40.6.165/library/nginx:v1   docker-work01       Running             Running 7 minutes ago                       
    matq9qdwx12r        nfs-nginx.2         10.40.6.165/library/nginx:v1   docker-work02       Running             Running 3 minutes ago       
    

    注意缩容后,去掉实例的节点的系统数据挂载随之卸载,节点的docker数据卷volume不会除掉,但节点数据卷volume的数据会移除掉

    6、集群服务发布

    Docker Swarm,主要包含以下概念:

    • Swarm
    • Node
    • Stack
    • Service
    • Task
    • Load balancing

    Swarm本身就是“群”的意思,人群、蜂群。 这里就是指计算机集群(cluster)在用Docker连接后的状态。 docker swarm命令可以创建、加入、离开一个集群。

    Node就是计算机节点,也可以认为是一个Docker节点。 Node分为两类:Manager和Worker。 一个Swarm至少要有一个Manager,部分管理命令只有在Manager上才能使用。 两类Node都可以运行Service,但只有Manager上才能执行运行命令。 比如,在Manager才能使用docker node命令可以查看、配置、删除Node。

    Stack是一组Service,和docker-compose类似。 默认情况下,一个Stack共用一个Network,相互可访问,与其它Stack网络隔绝。 这个概念只是为了编排的方便。 docker stack命令可以方便地操作一个Stack,而不用一个一个地操作Service。

    Service是一类容器。 对用户来说,Service就是与Swarm交互的最核心内容。 Service有两种运行模式,一是replicated,指定一个Service运行容器的数量; 二是global,在所有符合运行条件的Node上,都运行一个这类容器。docker service命令可以操作Swarm中的Service。

    Task就是指运行一个容器的任务,是Swarm执行命令的最小单元。 要成功运行一个Service,需要执行一个或多个Task(取决于一个Service的容器数量),确保每一个容器都顺利启动。 通常用户操作的是Service,而非Task。

    Load balancing即负载均衡,也包含反向代理。 Swarm使用的是Ingress形式的负载均衡,即访问每个节点的某个Published端口,都可自动代理到真正的服务。 大致原理如下图所示。

    Load balancing.png
    docker_task_service.png
    docker service create --name my_web -p 88:80 --replicas 3 nginx
    # docker service ps my_web
    ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE               ERROR               PORTS
    kva9nlhj1xbz        my_web.1            nginx:latest        docker-manager01    Running             Running 45 minutes ago                          
    eni1a9jquvgh        my_web.2            nginx:latest        docker-work01       Running             Running about an hour ago                       
    xonfhfxxizfx        my_web.3            nginx:latest        docker-work02       Running             Running 45 minutes ago 
    
    # docker service logs my_web -f  ## 查看访问日志
    # docker service inspect my_web   ## 查看服务的详细信息
         ...
                "Ports": [
                    {
                        "Protocol": "tcp",    ##默认启动的是TCP协议,如果要指定UDP,则 -p 88:80/udp
                        "TargetPort": 80,
                        "PublishedPort": 88,
                        "PublishMode": "ingress"
                    }
                ],
                "VirtualIPs": [
                    {
                        "NetworkID": "m4c12supk4prtsb46osiep2rz",
                        "Addr": "10.255.0.13/16"     ### VIP地址
                    }
                ]
            }
         ...
    
    # docker network ls
    NETWORK ID          NAME                DRIVER              SCOPE
        ....
    m4c12supk4pr        ingress             overlay             swarm
        ...
    
    # docker network inspect ingress  ##查看详细的网络服务的网络  
    
    # iptables-save |grep 88   ##其实是通过iptables 做目标地址转发实现
    -A DOCKER-INGRESS -p tcp -m tcp --dport 88 -j DNAT --to-destination 172.19.0.2:88
    -A DOCKER-INGRESS -p tcp -m tcp --dport 88 -j ACCEPT
    -A DOCKER-INGRESS -p tcp -m state --state RELATED,ESTABLISHED -m tcp --sport 88 -j ACCEPT
    

    在三个节点前面加一个haproxy或nginx对暴露的端口做负载均衡:


    ingress_network.png

    7、服务发现与负载均衡

    服务发现与负载均衡.png

    swarm集群内置类似分布式存储,记录一下集群的状态信息和创建服务信息,比如创建的副本IP、对外暴露的访问端口,访问到具体哪些节点。

    服务发现:Swarm模式内置DNS组件,自动为每个服务分配DNS记录,然后服务的DNS名称在集群内的服务直接分发请求。
    负载均衡:在Swarm集群中创建服务时,Ingress网络会自动为其分配一个虚拟IP(VIP),在DNS解析时返回VIP,流入该VIP的流量将自动发送(IPVS)该服务的所以健康任务(容器)。

    # docker network create --driver overlay my-web
    s9blzb8nvymwpqxfk4c4sp7qw
    # docker network ls
    NETWORK ID          NAME                DRIVER              SCOPE
    76158eb5c5a9        bridge              bridge              local
    12c813b82062        docker_gwbridge     bridge              local
    35e935d201b0        host                host                local
    m4c12supk4pr        ingress             overlay             swarm
    s9blzb8nvymw        my-web              overlay             swarm
    5c110c0bd687        none                null                local
    

    将多个服务加入同一个自定义网络,服务之间通信可以通过服务名通信

    # docker service create --replicas 3 --network my-web --name web01 nginx
    # docker service create --replicas 3 --network my-web --name redis01 redis
    # docker service create --replicas 3 --network my-web --name bs2 busybox ping www.baidu.com
    # docker ps -l
    CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS              PORTS               NAMES
    ab73f288a741        busybox:latest      "ping www.baidu.com"   2 minutes ago       Up 2 minutes                            bs2.2.r4bv8tf8sgl6z3fzwek3e2rrn
    # docker exec -it ab73f288a741 sh
    / # ping web01     ###web01服务的VIP为 10.0.0.2
    PING web01 (10.0.0.2): 56 data bytes
    64 bytes from 10.0.0.2: seq=0 ttl=64 time=0.220 ms
    
    / # ping redis01    ###redis01服务的VIP为 10.0.0.2
    PING redis01 (10.0.0.9): 56 data bytes
    64 bytes from 10.0.0.9: seq=0 ttl=64 time=0.197 ms
    

    负责均衡的模式:VIP和DNS

    ### 默认通过VIP模式,得经过负载均衡VIP再转发:
    # docker service inspect web01
       ...
                "EndpointSpec": {
                    "Mode": "vip"   ##默认通过VIP模式,得经过负载均衡VIP再转发
                }
       ...
    
    ### 默认通过内部DNS模式将请求转发:
    # docker service create --replicas 3 --network my-web --endpoint-mode dnsrr --name web02 nginx
    # docker service inspect web02
       ...
      "EndpointSpec": {
            "Mode": "dnsrr"
       }
       ...
    
    / # nslookup web02
    Server:     127.0.0.11
    Address:    127.0.0.11:53
    
    Non-authoritative answer:
    Name:   web02
    Address: 10.0.0.17    ###容器的IP
    Name:   web02
    Address: 10.0.0.18    ###容器的IP
    Name:   web02
    Address: 10.0.0.19     ###容器的IP
    
    # docker inspect rwji4rwdejy4(容器ID)  可以看到对应容器的IP
    

    常用命令:

    # 进容器查看DNS记录
    nslookup hello
    
    # 获取虚拟IP
    docker service inspect -f '{{json .Endpoint.VirtualIPs}}' hello
    
    # 设置DNS轮询模式
    docker service create \
    --replicas 3 \
    --name my-web \
    --network my-network \
    --endpoint-mode dnsrr \
    nginx
    
    

    8、高可用架构

    swarm集群即使managers节点挂了也不影响集群其他节点的容器的业务访问(去中心化设计),Internal distributed state store 为swarm manager 内置分布式存储,利用RAFT协助保持manager节点的数据一致性,manager主要是维护集群的状态;创建请求调度服务;提供swarm API。

    高可用架构.png
    manager_nodes.png
    #将work节点升级为manager节点:
    # docker node ls
    ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
    y7kvs1pl3ydu990k0lv2j846m *   docker-manager01    Ready               Active              Leader              18.09.6
    gv4r5k331flafgeedre6btwkh     docker-work01       Ready               Active                                  18.09.6
    lci41ilcev8jyjit4pbtslufv     docker-work02       Ready               Active                                  18.09.6
    
    # docker node promote docker-work01
    # docker node promote docker-work02
    # docker node ls
    ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
    y7kvs1pl3ydu990k0lv2j846m *   docker-manager01    Ready               Active              Leader              18.09.6
    gv4r5k331flafgeedre6btwkh     docker-work01       Ready               Active              Reachable           18.09.6
    lci41ilcev8jyjit4pbtslufv     docker-work02       Ready               Active              Reachable           18.09.6
    

    9、配置文件管理

    docker config --help
    (1)、生成一个基本的Nginx配置文件

    # cat site.conf
    server {
    listen 80;
    server_name localhost;
    location / {
    root /usr/share/nginx/html;
    index index.html index.htm;
    }
    }
    

    (2)、将site.conf保存到docker配置中,data是做加密存储的

    # docker config create nginx-v1.conf site.conf
    # docker config ls
    ID                          NAME                CREATED             UPDATED
    p9572lxwcb0hffh6pz5rlulrs   nginx-v1.conf       22 seconds ago      22 seconds ago
    
    # docker config inspect ID或者NAME
    # docker config inspect nginx-v1.conf
    [
        {
            "ID": "p9572lxwcb0hffh6pz5rlulrs",
            "Version": {
                "Index": 1278
            },
            "CreatedAt": "2019-05-20T12:08:51.54970674Z",
            "UpdatedAt": "2019-05-20T12:08:51.54970674Z",
            "Spec": {
                "Name": "nginx-v1.conf",
                "Labels": {},
                "Data": "c2VydmVyIHsKICAgIGxpc3RlbiA4MDsKICAgIHNlcnZlcl9uYW1lIGxvY2FsaG9zdDsKICAgIGxvY2F0aW9uIC8gewogICAgICAgIHJvb3QgL3Vzci9zaGFyZS9uZ2lueC9odG1sOwogICAgICAgIGluZGV4IGluZGV4Lmh0bWwgaW5kZXguaHRtOwogICAgfQp9Cg=="
            }
        }
    ]
    

    (3)、创建一个Nginx并应用这个配置

    # docker service create \
    --name nginx_test \
    --config source=nginx-v1.conf,target=/etc/nginx/conf.d/nginx-v1.conf \
    --publish 8080:80 \
    nginx 
    

    10、应用案例–集群部署LNMP网站平台

    相关文章

      网友评论

          本文标题:10、Swarm容器集群管理

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