docker swarm

简介:
      docker swarm 是 docker 推出的一款用于多主机的容器编排工具
 
 
特性:
      集成 docker Engine: 与 docker 集成的集群管理工具
 
      声明性服务模型: 使用声明性方法来定义应用程序中各种服务的所需状态
 
      分散式设计: Docker Engine 在运行时处理任何专门化, 而不是在部署时处理节点角色之间的差异, 您可以使用DOCKER Engine 部署 managers 和 nodes
 
      动态伸缩: 对于每个服务, 您可以声明要运行的任务数. 当您向上或向下扩展时, swarm 管理器会通过添加或删除任务来自动调整容器数量
 
      期望的状态协调: swarm 管理器持续监视群集状态, 并协调实际状态与表达的所需状态之间的任何差异, 直到实际状态与期望状态相同
 
      多主机网络: 您可以为服务指定覆盖网络, swarm 管理器在初始化或更新应用程序时自动为覆盖网络上的容器分配地址
 
      服务发现: Swarm 管理器节点为 swarm 中的每个服务分配一个唯一的 DNS 名称, 并负载均衡正在运行的容器
 
      负载均衡: 您可以将服务端口公开给外部负载均衡器. 在内部 swarm 允许您指定如何在节点之间分发服务容器
 
      默认安全: swarm 中的每个节点都强制执行 TLS 相互身份验证和加密,以保护自身与所有其他节点之间的通信
 
      滚动更新: 在更新时, 您可以逐步将服务更新应用于节点. 通过 swarm 管理器, 您可以控制服务部署到不同节点之间的延迟. 出现问题,您可以将任务回滚到以前的版本

 
 
关键概念:
      什么是 swarm:
           一个 swarm 群集由多个 Docker 主机组成, 这些主机以群集模式运行, 并充当 managers 和 workers
           给定的 Docker 主机可以是 manager 或 worker 这两种角色
           创建服务时, 您可以定义其最佳状态(可用的副本数量, 网络和存储资源, 服务暴露给外部的端口等)
           Docker 努力维持所需的状态. 例如, 如果工作节点变得不可用, Docker 将该节点上的容器调度到其他节点上运行
 
 
      任务:
           一个任务是一个运行的容器, 是一个 swarm 服务的一部分, 并通过 swarm manager 管理, 而不是一个独立的容器
           群集服务相对于独立容器的一个主要优点是, 您可以修改服务的配置, 包括其连接的网络和卷, 而无需手动重新启动服务, Docker 将更新配置
           当 Docker 以群集模式运行时, 您仍然可以在 swarm 节点上运行独立容器和群集服务
           独立容器和群集服务之间的关键区别在于, 只有群集管理器可以管理群集, 而独立容器可以在任何守护程序上启动
           与使用 Docker Compose 定义和运行容器的方式相同, 您可以定义和运行 swarm service stacks

 
 

      节点:
           一个节点是一个装有 Docker Engine 的主机, 要将应用程序部署到 swarm 请将服务定义提交给 manager 节点, manager 节点将任务分派给 work 节点
           manager 节点维护群集状态所需的编排和集群管理功能. manager 节点选择单个 leader 来执行编排任务
           worker 节点接收并执行从 manager 节点分派的任务
           默认情况下 manager 节点还将作为 worker 节点运行, 但您可以将它们配置为仅作为 manager 节点
           agent 程序在每个 worker 节点上运行, 并报告分配给它的任务
           worker节点向 manager 节点通知其分配的任务和当前状态, 以便 manager 可以维持每个 worker 的期望状态

 
 

      服务和任务:
           服务是在 manager 或 worker 节点上执行的任务的定义. 它是 swarm 系统的中心, 是用户与 swarm 交互的主要根源
           在创建服务时, 指定要使用的容器镜像以及在运行容器中执行的命令
           在 replicated 服务模型中, swarm 管理器根据您在所需状态中设置的比例在节点之间分配特定数量的 replica 任务

 
 
      负载均衡:
           swarm 管理器使用入口负载均衡来发布可被外部主机访问的服务
           swarm 管理器可以自动为发布的端口分配服务, 或者可以为服务发布端口
           在发布端口时, 您可以指定任何未使用的端口, 如果您没有指定端口, swarm 管理器将为服务分配给一个在 30000-32767 范围内的端口

 
 
 

安装 swarm 的前提:

1、安装 docker
        # 建议安装 docker 1.12 以上版本
        https://docs.docker.com/install/linux/docker-ce/centos/#prerequisites

2、配置 docker 监听 TCP 2375端口
        mkdir /etc/systemd/system/docker.service.d/
        cat > /etc/systemd/system/docker.service.d/tcp.conf <<EOF
        [Service]
        ExecStart=
        ExecStart=/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2375
        EOF

3、重启 docker 
        systemctl daemon-reload
        systemctl restart docker

 
 
 

创建 swarm 集群:

    # 初始化 master 节点, 192.168.5.11 为 master 和其他节点进行通信的 IP
    # 初始化完成后输出 docker swarm join --token ... 的一条命令, 在节点执行, 将节点加入 swarm 集群 
    docker swarm init --advertise-addr 192.168.5.11

    # 查看 swarm 集群状态
    docker info

    # 查看和节点相关的信息
    docker node ls

    # 查看端口监听情况
    ss -tunl

    # docker swarm 需要监听的端口
    # tcp/2377                  # swarm 集群管理端口
    # tcp/7946 udp/7946         # 节点间通信
    # udp/4789                  # 网络流量传输

 
 
 

节点加入集群:

    # 将 master端 执行 docker swarm init 后输出的命令在 node 节点上运行即可
    docker swarm join --token \ 
        SWMTKN-1-4xim2s11yxwlb1rz4pvbm9fsivjfgh5bssspalpdku4p1uk806-baaerpzmlgena74kvzh5dif3a \
        192.168.5.11:2377

    # 如果不小心忘记了, 可以使用此命令获取
    docker swarm join-token worker

    # 在 master 上运行此命令将看见 node 节点已经加入 swarm
    docker node ls

 
 
 

swarm 集群基础操作:

    # 在 maser 上运行此命令(对 swarm 集群的大多数操作都是在 master 上操作的, 下面的操作如无额外说明都是在 master 上执行)
    docker service create --replicas 1 --name helloworld alpine ping docker.com

    # docker service create     创建一个 swarm 服务
    # --replicas                服务的副本数(一共有多少个容器在运行)
    # --name                    服务名称
    # alpine ping docker.com    运行 alpine 镜像, 执行 ping docker.com 命令

    # 查看服务
    docker service ls

    # 输出 helloworld 服务基础信息
    docker service inspect --pretty helloworld

    # 输出 helloworld 服务详细信息
    docker service inspect helloworld

    # 查看正在运行服务的节点, 在节点对应节点上运行 docker container ls 可以看见该容器在运行
    docker service ps helloworld

    # 将 helloworld 的副本数更改为 10
    docker service scale helloworld=10

    # 查看服务副本数量(查看 REPLICAS 列)
    docker service ls

    # 将 helloworld 的副本数更改为 5
    docker service scale helloworld=5

    # 查看服务副本数量, 这次发现 REPLICAS 为 5/5 (有可能是 10/5 这是因为虽然服务器已经减少副本的数量了, 但是 docker 还没有将容器删除, 出现这种情况多等待一段时间即可)
    docker service ls

    # 查看各个副本所在的 node 节点
    docker service ps helloworld

    # 删除该服务
    docker service rm helloworld

 
 
 

swarm 滚动更新服务:

    # 创建一个 redis 服务
    docker service create --replicas 3 --name redis --update-delay 10s redis:3.0.6

    # --update-delay             指定服务在更新时的延迟时间, 将时间表示为T, 秒数Ts, 分钟数Tm, 小时数Th. 所以 10m30s 表示延迟10分30秒
    # --update-parallelism       默认情况下, 调度程序一次更新1个任务, 使用该参数指定同时更新的最大任务数

    # 默认情况下, 对单个任务更新返回的状态为 RUNNING 时, 调度程序会继续更新下一个任务, 直到所有任务更新完成. 如果在更新返回 FAILED 则调度程序会暂停更新
    # 可以使用 --update-failure-action 来控制 docker service create 或 docker service update 的行为
    # --update-failure-action 可接受的值 pause(默认值, 暂停), continue(继续), rollback(回滚)

    # 查看 redis 服务(这时 IMAGE 列的值为 redis:3.0.6)
    docker service ls

    # 更新 redis 服务(swarm 管理器将根据 UpdateConfig 策略将更新应用于节点)
    docker service update --image redis:3.0.7 redis

    # 查看 redis 服务(这时 IMAGE 列的值为 redis:3.0.7)
    docker service ls

    # 查看更新状态, 如果更新失败在 Message 列将显示和更新失败相关的内容
    docker service inspect --pretty redis

    # 重启暂停的更新任务
    docker service update redis

    # 查看服务更新信息(将看见所有的历史版本)
    docker service ps redis

 
 
 

设置 swarm 节点状态:

    # 当节点处于 Active 状态时(docker node ls 的 AVAILABILITY 列), swarm 管理器可以将任务分配给任何 ACTIVE 状态的节点
    # 有时, 例如服务器维护, 需要将节点状态设置为 DRAIN
    # DRAIN 状态阻止节点从 swarm 管理器接收新任务, 并且 swarm 管理器将停止此节点上运行的任务(一个任务通常就是一个容器), 将其上的任务分配给其他状态为 ACTIVE 的节点

    # 查看节点(获取节点 NODE 名称)
    docker node ls

    # 将节点状态设置为 drain, docker-2 是我 docker 节点的名称
    docker node update --availability drain docker-2

    # 查看节点状态
    docker node inspect --pretty docker-2 | grep Availability

    # 查看 swarm 管理器将其任务的分配情况
    docker service ps redis

    # 将节点状态设置为 active
    docker node update --availability active docker-2

    # 查看节点状态
    docker node inspect --pretty docker-2 | grep Availability

 
 
 
swarm 网络:

    docker swarm 通过发布端口使得外部主机可以访问集群资源, 所有节点都参入到 ingress 路由网格
    路由网格使得集群中每个节点都能够接收集群中已发布的服务端口的连接, 即使节点上没有运行该任务
    路由网格将所有传入请求路由到发布端口的可用节点的可用容器上
    docker 的路由网格在 Linux 上使用 iptables 实现

    # 在新版本的 docker swarm 中, 使用 --publish 暴露端口, published 为暴露的端口(即宿主机端口), target 为容器端口
    # 如果不指定 published 参数 docker swarm 会随机分配一个高编号的端口
    docker service create --name my-web --publish published=8080,target=80 --replicas 2 nginx

    # 在任何节点上访问 8080 端口时, docker 会将请求路由到活动容器(状态健康并且运行了该任务的容器)
    # 在 swarm 节点本身上, 8080 端口实际上可能不受约束, 但路由网格知道如何路由流量并防止发生任何端口冲突
    # 路由网格节点上的发布端口的所有地址(0.0.0.0:<port>), 对于外网地址, 该端口可以在外部访问, 对于其他 IP 地址只能在内部访问

    访问测试:
        # 查看容器所在的节点
        docker service ps my-web

        # 修改 node 2 节点上的 index.html
        [root@docker-2 ~]# docker container exec -it 4a998a01a9d4 bash                  # 进入 my-web 的任务容器
        root@4a998a01a9d4:/# echo "node2" > /usr/share/nginx/html/index.html            # 修改页面内容

        # 修改 node 3 节点上的 index.html
        [root@docker-3 ~]# docker container exec -it f1aedec1c1db bash                  # 进入 my-web 的任务容器
        root@f1aedec1c1db:/# echo "node3" > /usr/share/nginx/html/index.html            # 修改页面内容

        # 在任意节点访问, 路由网格会自动进行负载均衡
        curl http://127.0.0.1:8080/

    # 对现有的服务进行端口发布
    docker service update --publish-add published=2222,target=22 my-web

    # 查看已发布的端口    
    docker service inspect --format="{{json .Endpoint.Spec.Ports}}" my-web | python -m json.tool

    默认情况下, docker swarm 发布的端口为 TCP 端口, 需要发布 UDP 的端口需要使用 protocol 参数设置
    # 发布 TCP 端口
    docker service create --name dns-cache --publish published=53,target=53 dns-cache

    # 发布 TCP 和 UDP 端口
    docker service create --name dns-cache --publish published=53,target=53 --publish published=53,target=53,protocol=udp dns-cache

    # 发布 UDP 端口
    docker service create --name dns-cache --publish published=53,target=53,protocol=udp dns-cache

            绕过路由网格:
                    您可以绕过路由网格, 以便在访问给定节点上的绑定端口时, 始终访问在该节点上运行的服务实例, 这被称为 host 模式
                    host 和 ingress 的区别:
                            1、如果一个任务启动了两节点上的容器, 那么在 ingress 模式下, 不管访问那个 node 其都会对请求做负载均衡, 将请求负载到两个节点上的容器
                            2、在 host 模式中必须使用 IP 地址访问运行了该任务的节点, 其访问是和 IP 地址绑定的
                            3、在 host 模式中, 如果节点没有运行指定任务则不会简单指定端口, 或者是其他不同的任务在监听
                            4、在 host 模式中, 创建服务时不能指定 --replicas 选项
                            5、如果您希望在每个节点上运行多个服务任务(例如: 当您有5个节点但运行10个副本时), 则无法指定静态目标端口, Docker 会随机分配高编号端口

                    # 要绕过路由网格, 将 --publish 的 mode 设置为 host, mode 默认为 ingress
                    docker service create --name web --publish published=8000,target=80,mode=host --mode global nginx

转载于:https://blog.51cto.com/hongchen99/2310378

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值