• Docker-Swarm速成


    节点管理

    更多高级操作:

    创建一个新的 Manager Node

    使用docker swarm init 命令创建一个 Manager Node.

    --advertise-addr 参数将 Manager Node 监听的IP设置为:192.168.99.100.

    注意,使用 --advertise-addr 默认监听的端口为 2377

    swarm 中的其他 Node 必须能访问 Manager Node 的 IP.

    输出包括将新节点加入 swarm 的命令。根据--token 标志的值,节点将作为Master或Worker加入。

    docker swarm init --advertise-addr ManagerIP地址
    
    • 1

    例:

    root@u2004:/home/ubuntu# docker swarm init --advertise-addr 192.168.1.80
    Swarm initialized: current node (9nxycsrinzgh5bgqwfus2ia8r) is now a manager.
    
    To add a worker to this swarm, run the following command:
    
     docker swarm join --token SWMTKN-1-5qv7t73fvawvh795ckh3nxl9vnyo2hwwsqnnjwqyav3spj7ufu-1i7wir7oc3g9fh7yidg19i8p5 192.168.1.80: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

    docker swarm join-token manager 命令用于获取添加新的 Manager Node 的命令参数

    docker swarm join-token worker 命令用于获取添加新的 Worker Node 的命令参数

    在生产环境 Manager Node 不推荐运行任何容器实例,但是 Swarm 调度器会分配给Manager Node,

    因此我们可以通过 禁用节点 告诉 Swarm 调度器不要分配给 Manager Node 任何容器实例。

    查看 swarm 当前状态

    docker info
    
    • 1

    例:

    root@u2004:/home/ubuntu# docker info
    Client:
    Context:    default
    Debug Mode: false
    Plugins:
    app: Docker App (Docker Inc., v0.9.1-beta3)
    buildx: Build with BuildKit (Docker Inc., v0.6.3-docker)
    scan: Docker Scan (Docker Inc., v0.9.0)
    
    Server:
    ....
    Swarm: active
    NodeID: 9nxycsrinzgh5bgqwfus2ia8r
    Is Manager: true
    ClusterID: lu8frg6np6dmqf3bjr7jyl628
    Managers: 1
    Nodes: 1
    Default Address Pool: 10.0.0.0/8
    SubnetSize: 24
    Data Path Port: 4789
    Orchestration:
    Task History Retention Limit: 5
    Raft:
    Snapshot Interval: 10000
    Number of Old Snapshots to Retain: 0
    Heartbeat Tick: 1
    Election Tick: 10
    Dispatcher:
    Heartbeat Period: 5 seconds
    CA Configuration:
    Expiry Duration: 3 months
    Force Rotate: 0
    Autolock Managers: false
    Root Rotation In Progress: false
    Node Address: 192.168.1.80
    Manager Addresses:
    192.168.1.80:2377
    ...
    
    • 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
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    查看节点列表

    使用以下命令查看节点列表,节点 ID 旁边的 * 表示你当前已经连接到此节点

    docker node ls
    
    • 1

    例:

    root@u2004:/home/ubuntu# docker node ls
    ID                            HOSTNAME   STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
    9nxycsrinzgh5bgqwfus2ia8r *   u2004      Ready     Active         Leader           20.10.11
    
    • 1
    • 2
    • 3

    查看节点详细信息

    使用以下命令查看节点的详情:

    docker node inspect --pretty 节点名称
    
    • 1

    添加新的 Manager Node 到集群

    在另一台机器运行 docker swarm join 命令加入已存在的集群中

    root@u2004:/home/ubuntu# docker swarm join-token manager
    To add a manager to this swarm, run the following command:
    
        docker swarm join --token SWMTKN-1-5qv7t73fvawvh795ckh3nxl9vnyo2hwwsqnnjwqyav3spj7ufu-ca1v0jiu9xwb6o20dqqajl4n1 192.168.1.80:2377
    
    • 1
    • 2
    • 3
    • 4

    Manager Node 必须是单数(Raft),生产环境推荐3台或5台作为 Manager Node

    docker swarm join-token manager 命令用于获取添加新的 Manager Node 的命令参数

    添加新的 Worker Node 到集群

    在另一台机器运行 docker swarm join 命令加入已存在的集群中

    docker swarm join --token SWMTKN-1-5qv7t73fvawvh795ckh3nxl9vnyo2hwwsqnnjwqyav3spj7ufu-1i7wir7oc3g9fh7yidg19i8p5 192.168.1.80:2377
    
    • 1

    docker swarm join-token worker 命令用于获取添加新的 Worker Node 的命令参数

    禁用节点

    在某些情况下我们想要将某个节点禁用或将节点中运行的容器清空,使用以下命令即可实现:

    docker node update --availability drain 节点名称
    
    • 1

    被禁用的节点仍然存在集群中,只是不会被swarm调度运行容器实例

    启用节点

    禁用节点后使用以下命令即可启用节点:

    docker node update --availability active 节点名称
    
    • 1

    更新节点

    更新节点

    docker node update --label-add foo --label-add bar=baz 节点名称
    
    • 1

    服务管理

    更多高级操作:

    https://docs.docker.com/engine/reference/commandline/service/

    https://docs.docker.com/compose/compose-file/compose-file-v3/#placement

    运行服务

    连接到 Manager Node,使用 docker service create 命令创建服务.

    例:

    docker service create --replicas 1 --name helloworld alpine ping docker.com
    
    • 1
    • --name 指定服务名称为 helloworld
    • --replicas 指定服务运行实例数量为 1
    • 参数 alpine 表示运行的镜像为 Alpine Linux
    • 参数 ping docker.com 表示在容器中执行的命令

    查看运行的服务

    在 Manager Node 运行此命令查看正在运行的服务列表:

    docker service ls
    
    • 1

    例:

    root@u2004:/home/ubuntu# docker service ls
    ID             NAME         MODE         REPLICAS   IMAGE           PORTS
    jkj80hnr73rn   helloworld   replicated   1/1        alpine:latest
    
    • 1
    • 2
    • 3

    查看服务的详细信息

    在 Manager Node 运行此命令查看服务的运行详情:

    docker service inspect --pretty 服务名称
    
    • 1

    参数 --pretty 表示返回格式化后的详细信息,不加这个参数则打印 JSON 格式的信息

    查看服务运行在那些节点

    在 Manager Node 使用此命令查看服务都在那些节点运行:

    docker service ps 服务名称
    
    • 1

    docker-swarm 中的服务实例由 swarm 调度。因此有部分服务的实例运行在 Manager Node 是正常表现。

    伸缩服务

    docker-swarm 支持对服务实例进行动态伸缩,使用以下命令即可实现:

    docker service scale 服务名称=实例数量(最少为1)
    
    • 1

    例:

    root@u2004:/home/ubuntu# docker service scale helloworld=2
    helloworld scaled to 2
    overall progress: 2 out of 2 tasks
    1/2: running   [==================================================>]
    2/2: running   [==================================================>]
    verify: Service converged
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    删除服务

    在 Manager Node 使用以下命令删除服务:

    docker service rm 服务名称
    
    • 1

    注意,因为是集群的原因,集群中的Node将会存在延迟的情况,想确认服务是否被删除成功请使用 docker service ls 查看

    滚动更新服务

    创建服务

    进入 Manager Node 创建一个redis服务用于演示滚动更新:

    docker service create \
      --replicas 3 \
      --name redis \
      --update-delay 10s \
      redis:3.0.6
    
    • 1
    • 2
    • 3
    • 4
    • 5

    --update-dely 表示更新服务或服务集之间的时间延迟:1h10m3s,表示延迟1小时10分钟3秒。

    调度器默认一次更新一个任务,可以通过 --update-parallelism 参数配置调度器同时更新服务数量。

    默认情况下,当单个服务更新返回状态为 RUNNING,调度器会让另一个服务更新,直到所有服务都更新完成。

    如果在更新期间某个服务返回 FAILED ,调度器会暂停更新,可以通过 --update-failure-action 参数配置控制当服务更新发生错误时的行为。

    检查服务状态
    docker service inspect --pretty redis
    
    • 1
    更新服务
    docker service update --image redis:3.0.7 redis
    
    • 1

    默认情况下,调度器将按以下方式更新服务:

    • 停止一个服务
    • 更新已停止的服务
    • 启动已更新的服务
    • 如果更新的服务返回 RUNNING ,等待指定的延迟时间后开始更新下一个服务
    • 如果更新期间某个服务返回 FAILED ,则暂停服务更新
    重新启动暂停的服务更新
    docker service update redis
    
    • 1

    为了避免重复某些失败的更新,可以重新指定更新参数

    查看服务的滚动更新
    docker service ps redis
    
    • 1

    在swarm更新完成所有服务之前,你可以看到一些服务的镜像为 redis:3.0.6,另一些为 redis:3.0.7

    路由网格

    docker swarm支持路由网格。路由网格让处于swarm集群中的任意一个节点都可以作为被访问的入口,即使此节点没有运行任何服务。

    要在 swarm 集群中使用使用路由网格,首先需要开启加入swarm集群的节点的以下端口:

    • 7946 :容器网络发现
    • 4789 :容器网络入口

    其次需要将节点服务实例的端口公开,使服务可以被外部访问(例如使用nginx做负载均衡)

    服务原理

    服务入口图像

    创建服务时公开端口
    docker service create \
      --name <SERVICE-NAME> \
      --publish published=<PUBLISHED-PORT>,target=<CONTAINER-PORT> \
      <IMAGE>
    
    • 1
    • 2
    • 3
    • 4

    --publish-p 效果相同,其中 --published 值为公布的端口,target 值为容器内部监听的端口。

    现在推荐使用 --publish 的写法

    更新现有服务的公开端口
    docker service update \
      --publish-add published=<PUBLISHED-PORT>,target=<CONTAINER-PORT> \
      <SERVICE>
    
    • 1
    • 2
    • 3
    查看服务发布的端口
    docker service inspect --format="{{json .Endpoint.Spec.Ports}}" 服务名称
    
    • 1
    只公开TCP或UDP端口

    默认情况下公开端口都是 TCP 端口,你可以通过参数配置公开端口的类型:

    仅TCP
    docker service create --name dns-cache \
      --publish published=53,target=53 \
      dns-cache
    
    • 1
    • 2
    • 3

    docker service create --name dns-cache \
      -p 53:53 \
      dns-cache
    
    • 1
    • 2
    • 3
    仅UDP
    docker service create --name dns-cache \
      --publish published=53,target=53,protocol=udp \
      dns-cache
    
    • 1
    • 2
    • 3

    docker service create --name dns-cache \
      -p 53:53/udp \
      dns-cache
    
    • 1
    • 2
    • 3
    TCP+UDP
    docker service create --name dns-cache \
      --publish published=53,target=53 \
      --publish published=53,target=53,protocol=udp \
      dns-cache
    
    • 1
    • 2
    • 3
    • 4

    docker service create --name dns-cache \
      -p 53:53 \
      -p 53:53/udp \
      dns-cache
    
    • 1
    • 2
    • 3
    • 4

    绕过路由网格

    要绕过 swarm 集群的路由网格,需要使用 --publish 参数设置 mode 值为host

    下面的命令使用 host 模式创建全局服务并绕过路由网格:

    docker service create --name dns-cache \
      --publish published=53,target=53,protocol=udp,mode=host \
      --mode global \
      dns-cache
    
    • 1
    • 2
    • 3
    • 4

    绕过路由网格后的注意事项:

    • 如果你访问未运行服务的节点,则无法访问此服务
    • 如果你希望在每个节点运行多个服务,就不能指定静态的端口。要么就允许docker随机分配一个公开端口(通过置空 published 参数的值实现)

    配置管理

    普通配置

    https://docs.docker.com/engine/swarm/configs/

    加密配置

    https://docs.docker.com/engine/swarm/secrets/


    锁定集群

    https://docs.docker.com/engine/swarm/swarm_manager_locking/

    默认情况下,swarm manager 使用的 Raft 日志在磁盘上是加密的。这种静态加密保护您的服务配置和数据免受攻击者访问加密的 Raft 日志。引入此功能的原因之一是支持Docker 机密功能。

    当 Docker 重新启动时,用于加密 swarm 节点之间通信的 TLS 密钥和用于加密和解密磁盘上的 Raft 日志的密钥都被加载到每个管理器节点的内存中。Docker 有能力保护双向 TLS 加密密钥和用于加密和解密 Raft 静态日志的密钥,允许您拥有这些密钥并要求手动解锁您的管理器。此功能称为自动锁定

    当 Docker 重新启动时,您必须先 解锁 swarm,使用 Docker 在 swarm 被锁定时生成的*密钥加密密钥。*您可以随时轮换此密钥加密密钥。

    注意:当新节点加入 swarm 时,您不需要解锁 swarm,因为密钥通过双向 TLS 传播给它。


    在生产环境使用swarm集群的注意事项

    swarm集群的管理

    https://docs.docker.com/engine/swarm/admin_guide/

    swarm集群如何使用 docker-componse.yml 部署容器

    如何操作

    https://docs.docker.com/engine/swarm/stack-deploy/

    docker stack 命令

    https://docs.docker.com/engine/reference/commandline/stack/

    如何编写支持 swarm 的 docker-componse.yml

    https://docs.docker.com/compose/compose-file/compose-file-v3/

    version: "3.9"
    services:
      db:
        image: redis:3.0.5
        deploy:
          replicas: 6 # 启动实例数量
          placement: # 配置容器实例位置------------
            max_replicas_per_node: 2 # 每个节点最多运行容器实例数量
            constraints: # 将容器分配到匹配标签的节点运行
              - "node.role==manager"
              - "engine.labels.operatingsystem==ubuntu 18.04"
            preferences: # 将任务平均分配到不同类别的节点上
              - spread: node.labels.zone
        resources: # 资源限制------------
            limits: # 占用上限
              cpus: '0.50'
              memory: 50M
            reservations: # 启动占用
              cpus: '0.25'
              memory: 20M
        restart_policy: # 重启策略------------
            condition: on-failure # 发生失败时
    		delay: 5s # 重启时间间隔
            max_attempts: 3 #最大尝试次数        
    		window: 120s # 判断是否重启成功的等待时长		
        update_config: # 滚动更新的配置------------
            parallelism: 2 # 同时更新的数量
            delay: 10s # 每次更新间隔时间
            monitor: 5s # 每次更新监控失败持续的时长
            failure_action: 'pause' # 滚动更新出现错误时执行的操作: continue/rollback/pause
            max_failure_ratio: # 允许的更新失败率
            order: stop-first # 更新顺序 stop-first(旧任务在启动新任务之前停止)或start-first(新任务首先启动,运行中的任务会出现短暂重叠)
        rollback_config: # 更新失败如何回滚------------
            parallelism: 2 # 每次回滚的数量,如果为0则全部回滚
            delay: 10s # 每次回滚间隔时间
            monitor: 5s # 每次更新监控失败持续的时长
            failure_action: 'pause' # 回滚出现错误时执行的操作: continue/rollback/pause
            max_failure_ratio: # 允许的回滚失败率,默认为0
            order: stop-first # 回滚顺序 stop-first(旧任务在启动新任务之前停止)或start-first(新任务首先启动,运行中的任务会出现短暂重叠)       
    
    • 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
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    docker-stack 不支持的docker-compose配置
  • 相关阅读:
    JAVA 日期时间类(Date)
    如何使用ArkUI从0-1写一个开发购物应用程序(下)
    tree命令-以树形结构显示目录下的内容
    【CSS】全局声明引入自定义字体
    LORS:腾讯提出低秩残差结构,瘦身模型不掉点 | CVPR 2024
    50.MongoDB快速入门实战
    Jmeter面试题
    【网络】详解http协议
    【故障补牢】贪吃的 Bing 爬虫,限量供应的应对措施
    istio系列教程
  • 原文地址:https://blog.csdn.net/hyx1229/article/details/125485503