目 录CONTENT

文章目录

Docker工具(compose、swarm)

简中仙
2020-09-29 / 0 评论 / 0 点赞 / 62 阅读 / 0 字 / 正在检测是否收录...
温馨提示:
本文最后更新于2024-01-08,若内容或图片失效,请留言反馈。 本文如有错误或者侵权的地方,欢迎您批评指正!

一、docker-compose

官网文档地址https://docs.docker.com/compose/overview/

docker-compose是docker推出一个容器编排工具,它是可以运行在swarm集群,也可以在单机下进行批量的创建容器。它需要一份清单文件(YAML)来作为其创建容器的依据。根据用户编写的清单文件(YAML)来创建相应的容器。

我们在之前的章节中了解到,容器原理以及如何去构建并运行一个我们需要的容器。而在实际应用场景下,可能我们需要很多个容器来完成工作任务,那么容器多了之后,对容器的管理就提出了更高的要求。通常我们创建一个容器时,需要用docker命令来完成,这个命令中可能会包含很多参数,以及需要的数据卷依赖,而当我们去更新一个容器时,同样也需要知道该容器当时被创建时所设置的运行参数。一个容器尚且有很多信息需要被记录,而很多个容器情况下怎么解决?并且容器与容器之间一依赖关系如何处理?

那么compose给出的解决方案是:创建容器时,不再直接在命令行中完成,而是先将与容器相关的参数记录在文件中,包括容器之间的依赖关系,然后通过docker-compose读取这份文件,并根据文件中的要求,自动的创建出对应的容器出来。用户只需要维护这份文件即可。对文件进行更改后可重新使用docker-compose读取,并将最新的更改应用至容器中。

那么由此可见,这份清单文件(YAML)在此时显示额外重要,理解并能够自由的编写这样的清单文件(YAML)是掌握compose使用方法的关键。

1、YAML语法

1、特性

YAML语言特性如下:

YAML对大小写是敏感的,同样的value 与Value被视为是不同的;

以缩进来确立层级关系,缩进不允许Tab,而是使用空格,空格的数量没有明确要求,只要保证同级的元素左对齐即可。但是同样使用两个空格来表示缩进;

YAML文件后缀名通常为.yaml或者.yml;

和大多数脚本语言与配置文件一样,YAML使用#号来表示注释;

YAML支持的数据类型有(集合、数组、纯量),纯量是表示不可再分的值,其中在compose中应用最多的是集合与数组;

2、键值对

我们在编写例如应用的配置文件时,应该都有了解一个最简单的配置形式就是定义一个变量,然后给这个变量再指定一个值。例如 name=myName,那么在YAML中也经常用到这种定义,只不过格式稍有不同。如下所示

name: myName

使用这里是使用:号来分隔变量与值的,这里不再是叫变量,而是称为键(key),而:号右面为值(value)。需要注意的是:号右边还需要紧跟一个空格。

如果value是需要包含一些特殊字符,或者明确要求是字符串类型的,那么可以使用单引号,或双引号来表示,如下所示

name: “9023”

3、数组

如果一个键(key)可以拥有多个值(value)那么可以使用数组来表示,有两种形式,形式一如下:

ports:
  - “1080:80”
  - “1043:443”

还有一种形式如下:

command: [“/bin/sh”,”-c”,”ping”,”localhost”]

这种方式是以中括号加逗号分隔,来表示数组。

4、缩进与对齐

有些时候一个元素会包含子元素,那么在YAML中表示这种层级关系,使用缩进即可,如下所示

prometheus:
  image: prom/prometheus:latest
  container_name: prometheus
  hostname: prometheus

如上所示,那么这就表示image、container、hostname这3个属于prometheus的子元素。同样的使用左对齐来确立层次,如果需要多个元素同属同一级别,那么就需要使其保持左对齐。

而下面是一个错误的示例,因为container增加的缩进量,那么它不再是pormetheus的子元素,而是变成了image的子元素。

prometheus:
  image: prom/prometheus:latest
    container_name: prometheus
  hostname: prometheus

因此在书写YAML文件时一定要注意缩进与对齐,多一个空格或少一个缩进,都会改变原有语意。

设置tab键的空格距离

# vim .vimrc
set tabstop=2
# source .vimrc

2、安装Compose

可以从github上下载最新稳定版本,默认为v2版本(v1已弃用),地址如下:

GitHub:https://github.com/docker/compose/releases

例如这里下载的版本为1.29.2,在Linux中运行以下命令,完成安装。

# curl -L "https://mirror.ghproxy.com/https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# chmod +x /usr/local/bin/docker-compose
# docker-compose -v
docker-compose version 1.29.2, build 5becea4c

也可以下载2.x版本
::: warning
必须安装到指定的目录下,才能被Docker CLI识别,以Docker CLI命令模式运行
:::

# mkdir -p /usr/local/lib/docker/cli-plugins
# curl -SL "https://mirror.ghproxy.com/https://github.com/docker/compose/releases/download/v2.14.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/lib/docker/cli-plugins/docker-compose
# chmod +x /usr/local/lib/docker/cli-plugins/docker-compose
# docker compose version
Docker Compose version v2.14.0

区别

  • docker compose1.x 是相对独立的命令,命令行方式如:docker-compose --version;docker compose v2 被规划为Docker CLI的一部分,命令行方式如docker compose version。注意docker与compose之间是空格,不是中横线;version 作为一个命令存在,而不是参数。

  • 支持 GPU 计算机 – 如果 Docker 主机包含此类设备,并且相应地设置 Docker 守护程序,则撰写服务可以定义 GPU 设备预留。

  • 配置文件支持 – 配置文件允许您通过选择性服务启用来调整 Compose 应用程序模型以适应各种用途和环境。

  • docker compose ls 命令现在允许您查看撰写应用程序的完整列表。

  • docker compose cp 命令允许您在服务容器和本地文件系统之间复制文件和文件夹。

3、构建应用

由于compose是根据YAML清单文件来执行相应的任务,那么要使用compose在我们的环境中构建应用,首先要做的就是需要编写一个YAML文件。

compose是可以批量的来完成一些任务的,例如我们想将构建镜像与运行容器,这两步操作,在一次命令执行中完成。或者说我们想通过一次命令的执行,运行多个容器。那么我们就可以将这多个步骤定义在YAML文件中。然后使用以下命令一次性完成任务的执行。

docker-compose -f docker-compose.yml up

命令中-f是指定要使用的YAML文件,up表示启动任务。下面我们可以通过一个示例来了解这个操作步骤。

1、常用命令

帮助信息

# docker-compose --help

创建或重新创建服务使用的镜像

# docker-compose build

通过容器发送SIGKILL信号强行停止服务

# docker-compose kill nginx

显示service的日志信息

# docker-compose logs

暂停和恢复服务

# docker-compose pause             //暂停服务
# docker-compose unpause             //恢复被暂停的服务

查看服务中的端口与物理机的映射关系

# docker-compose port nginx 80             //查看服务中80端口映射到物理机上的端口

显示当前项目下的容器

# docker-compose ps

拉取服务依赖的镜像

# docker-compose pull

重启某个服务中的所有容器

# docker-compose restart

删除停止的服务(服务里的容器)

root@docker compose]# docker-compose rm
参数说明参数说明
-f强制删除-v删除与容器相关的卷(volumes)

在服务中运行一个一次性的命令

# docker-compose run nginx ls /

启动/停止运行某个服务的所有容器

# docker-compose start             //启动运行某个服务的所有容器
# docker-compose stop             //停止运行某个服务的所有容器

指定某个服务启动的容器个数

# docker-compose scale nginx=2
参数说明参数说明
-f用于指定配置文件-p用于指定项目名称

2、compose文件指令

version

指定使用的YAML 依从的 compose 哪个版本制定的

build

构建指令,指定为构建镜像上下文,其中包含以下子元素

build参数说明
context上下文路径
dockerfile指定构建镜像的 Dockerfile 文件
args构建参数,这是在构建过程中使用的环境变量,而非供容器内引用的
labels设置构建镜像的tag
target多层构建时,可以指定构建哪一层
version: "3.9"
services:
  webapp:
    build:
      context: ./dir
      dockerfile: Dockerfile
      args:
        buildno: 1
      labels:
        - "com.example.description=Accounting webapp"
        - "com.example.department=Finance"
        - "com.example.label-with-empty-value"
      target: prod

cap_addcap_drop

添加或删除容器拥有的宿主机的内核功能。

cap_add:
  - ALL # 开启全部权限
cap_drop:
  - SYS_PTRACE # 关闭 ptrace权限

cgroup_parent

为容器指定父 cgroup 组,意味着将继承该组的资源限制

cgroup_parent: docker-admin

sysctls

设置容器中的内核参数,可以使用数组或字典格式

sysctls:
  net.core.somaxconn: 1024
  net.ipv4.tcp_syncookies: 0

sysctls:
  - net.core.somaxconn=1024
  - net.ipv4.tcp_syncookies=0

command

指定容器启动时的运行命令,可覆盖构建镜像时的CMD内容

command: ["/bin/sh", "-c", "ping", "localhost"]

container_name

指定自定义容器名称,而不是生成的默认名称。

image

指定容器运行的镜像。以下格式都可以

restart

定义重启策略

no:是默认的重启策略,在任何情况下都不会重启容器;

always:容器总是重新启动;

on-failure:在容器非正常退出时(退出状态非0),才会重启容器;

unless-stopped:在容器退出时总是重启容器,但是不考虑在Docker守护进程启动时就已经停止了的容器;

stop_signal

设置停止容器的替代信号。默认情况下使用 SIGTERM 。

stop_signal: SIGUSR1

以下示例,使用 SIGUSR1 替代信号 SIGTERM 来停止容器。

stop_grace_period

指定在容器无法处理 SIGTERM (或者任何 stop_signal 的信号),等待多久后发送 SIGKILL 信号关闭容器。

stop_grace_period: 1s # 等待 1 秒
stop_grace_period: 1m30s # 等待 1 分 30 秒

dns

自定义 DNS 服务器,可以是单个值或列表的多个值。

dns: 8.8.8.8

dns:
  - 8.8.8.8
  - 9.9.9.9

dns_search

自定义 DNS 搜索域。可以是单个值或列表。

dns_search: example.com

dns_search:
  - dc1.example.com
  - dc2.example.com

extra_hosts

添加主机名映射。类似 docker --add-host。

示例

extra_hosts:
 - "registry-1.local:192.168.26.11"
 - "registry-2.local:192.168.26.12"

env_file

从文件添加环境变量。可以是单个值或列表的多个值

env_file:
      - ./common/config/core/env

environment

添加环境变量。您可以使用数组或字典、任何布尔值,布尔值需要用引号引起来,以确保 YML 解析器不会将其转换为 True 或 False。

environment:
  MYSQL_HOST: localhost
  MYSQL_PORT: 3306

secrets

存储敏感数据,例如密码:

secrets:
  my_secret:
    file: ./my_secret.txt

volumes

将主机的数据卷或着文件挂载到容器里。

services:
  postgresql:
    image: postgres:latest
    volumes:
      - "/data/database:/var/lib/postgresql/data"

tmpfs

在容器内挂载一个临时文件系统。可以是单个值或列表的多个值。

tmpfs:
  - /tmp

devices

映射宿主机设备到容器内。

devices:
  - "/dev/ttyUSB0:/dev/ttyUSB0"

entrypoint

覆盖容器默认的 entrypoint。

entrypoint: /code/entrypoint.sh

也可以直接将脚本内的操作以参数形式定义,如下

entrypoint:
    - /bin/bash
    - -c
    - $@

network_mode

设置容器使用的网络模式。

network_mode: "bridge"
network_mode: "host"
network_mode: "none"
network_mode: "service:[service name]"
network_mode: "container:[container name/id]"

networks

配置容器连接的网络,引用顶级 networks 下的条目 。

services:
  prometheus:
    image: prom/prometheus:latest
    container_name: prometheus
    hostname: prometheus
restart: always
ports:
  - "18190:9090"
networks:
  - monitor
networks:
  monitor:
    driver: bridge

也可以使用external字段来标识,该网络是使用外部已经存在的,还是为此创建新的网络,如果external值为true则表示,使用外部网络,你可以使用docker network create创建自定义网络,然后在此处配置它。而如果为false则compose将为此创建新网络

networks:
  harbor:
    external: false

当然也可在创建新网络时,直接指定网段及网关

networks:
    demo:
      driver: bridge
      config:
         subnet: 172.19.0.0/16
         gateway: 172.19.0.1

logging

服务的日志记录配置。

driver:指定服务容器的日志记录驱动程序,默认值为json-file。有以下三个选项

driver: "json-file"
driver: "syslog"
driver: "none"

在 json-file 驱动程序下,可以使用以下参数,限制日志文件的数量和大小,当达到文件限制上限,会自动删除旧得文件。

logging:
  driver: json-file
  options:
    max-size: "500k" # 单个文件大小上限为500k
    max-file: "15" # 最多15个文件

syslog 驱动程序下,可以使用 syslog-address 指定日志接收地址。

logging:
  driver: syslog
  options:
    syslog-address: " tcp://127.0.0.1:1514"

healthcheck

用于检测容器服务是否健康运行。

healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost"] # 设置检测程序
  interval: 1m30s # 设置检测间隔
  timeout: 10s # 设置检测超时时间
  retries: 3 # 设置重试次数
  start_period: 40s # 启动后,多少秒开始启动检测程序

::: warning
处于单机状态的healthcheck,非swarm集群模式下,健康检查程序返回了异常,应用的状态将标记为unhealth,但不会对应用进行重启,而在swarm模式下才会执行重启。
:::

depends_on

设置依赖关系。

docker-compose up :以依赖性顺序启动服务。在以下示例中,先启动 db 和 redis ,才会启动 web。

docker-compose up SERVICE :自动包含 SERVICE 的依赖项。在以下示例中,docker-compose up web 还将创建并启动 db 和 redis。

docker-compose stop :按依赖关系顺序停止服务。在以下示例中,web 在 db 和 redis 之前停止。

version: "3.9"
services:
  web:
    image: python/demo:latest
    depends_on:
      - db
      - redis
  redis:
    image: redis
  db:
    image: postgres

deploy

指定与服务的部署和运行有关的配置,该字段只在 swarm 模式下才有用。deploy允许一个服务拥有多个副本,并且保证每个副本分布在多个节点中,以此来提高服务的可用性,见下文。

3、环境变量

在compose中有两种方式,将环境变量定义并导入容器的运行环境中,第一种是使用environment字段直接定义,还有一种是使用env_file来指定已经带有环境变量定义的文件,这方法适用于拥有较多变量需要定义时的场景。

使用environment定义一个变量GUEST_NAME

version: "3.9"
services:
  web:
    image: "python/demo:latest"
    container_name: web
    ports:
      - "5000:5000"
    environment:
      GUEST_NAME: "Bob"
    volumes:
      - "./app.py:/code/app.py"
  redis:
    image: "redis:6.0"
    container_name: redis

使用env_file

version: "3.9"
services:
  web:
    image: "python/demo:latest"
    container_name: web
    ports:
      - "5000:5000"
    env_file:
      - ./web.env
    volumes:
      - "./app.py:/code/app.py"
  redis:
    image: "redis:6.0"
    container_name: redis

4、处理依赖

compose可在在YAML文件中定义每个服务之间的依赖关系,使用depends_on字段。如前面的python/demo例子,我们的web服务依赖于redis,那么我们可以使用depends_on来明确指定依赖。而当指定依赖后,compose在启动或停止过程中会按照顺序启停容器。

例如web依赖redis,那么compose会首先启动redis,然后再启动web,而停止时则反向操作,先停止web然后是redis。

修改之前的docker-compose.yaml文件,内容如下

version: "3.9"
services:
  web:
    image: "python/demo:latest"
    container_name: web
    ports:
      - "5000:5000"
    env_file:
      - ./web.env
    depends_on:
      - redis
    volumes:
      - "./app.py:/code/app.py"
  redis:
    image: "redis:6.0"
    container_name: redis

二、docker swarm

Swarm是docker的一种集群模式,由多个docker节点组成,一般最小规模为3节点。在这些节点中将划分两种角色:manager、workers;做为manager角色的节点将采用Raft算法进行选举,其中将会有一个成为leader,集群任务由该节点进行调度。当一个leader节点发生故障时,其他manager将会重新选举推出新的leader掌管集群。而worker节点负责运行维护服务副本,也就是具体的容器。

概念说明
Swarm作用运行docker engin(引擎)的多个主机组成的集群
node每一个docker engin都是一个node(节点),分为 manager 和worker
manager node负责执行容器的编排和集群的管理工作,保持并维护swarm处于期望的状态。swarm可以有多个manager node,他们会自动协调并选举出一个Leader执行编排任务。但相反,不能没有managernode。
worker node接受并执行由manager node 派发的任务,并且默认manager node也是一个work node,不过可以将它设为manager-onlynode.让它只负责编排和管理工作。
service用来定义worker上执行的命令

1、功能亮点

  • **与 Docker 引擎集成的集群管理:**使用 Docker 引擎 CLI 创建一组 Docker 引擎,您可以在其中部署应用程序服务。您不需要额外的编排软件来创建或管理群。
  • 分散式设计: Docker 引擎不是在部署时处理节点角色之间的差异,而是在运行时处理任何专业化。您可以使用 Docker 引擎部署两种类型的节点、管理器和工作器。这意味着您可以从单个磁盘映像构建整个群。
  • 声明式服务模型: Docker 引擎使用声明式方法让您定义应用程序堆栈中各种服务的所需状态。例如,您可以描述一个应用程序,该应用程序由具有消息队列服务的 Web 前端服务和数据库后端组成。
  • **缩放:**对于每个服务,您可以声明要运行的任务数。当您按比例放大或缩小时,群管理器会通过添加或删除任务来自动调整以维持所需的状态。
  • Desired state reconciliation: swarm manager 节点持续监控集群状态,并协调实际状态与您表达的期望状态之间的任何差异。例如,如果您设置一个服务来运行一个容器的 10 个副本,并且托管其中两个副本的工作机器崩溃,则管理器创建两个新副本来替换崩溃的副本。群管理器将新副本分配给正在运行且可用的工作人员。
  • **多主机网络:**您可以为您的服务指定覆盖网络。群管理器在初始化或更新应用程序时自动为覆盖网络上的容器分配地址。
  • 服务发现: Swarm 管理器节点为 swarm 中的每个服务分配一个唯一的 DNS 名称和负载平衡运行的容器。您可以通过嵌入在 swarm 中的 DNS 服务器查询在 swarm 中运行的每个容器。
  • **负载平衡:**您可以将服务端口公开给外部负载平衡器。在内部,swarm 允许您指定如何在节点之间分发服务容器。
  • **默认安全:**集群中的每个节点都强制执行 TLS 相互身份验证和加密,以确保自身与所有其他节点之间的通信安全。您可以选择使用自签名根证书或来自自定义根 CA 的证书。
  • **滚动更新:**在推出时,您可以增量地将服务更新应用到节点。群管理器允许您控制服务部署到不同节点集之间的延迟。如果出现任何问题,您可以回滚到以前版本的服务。

2、工作原理

在Swarm集群中,节点被分为两种类型,Manager、Worker。Manager负责集群事务的调度,Worker负责具体的任务执行,例如创建容器等。一个Swarm集群中必须至少有一个manager节点。

Swarm 模式集群

需要说明的是在只有一个manager节点的swarm集群中,当manager发生故障时,集群中运行的容器服务不会受到影响,但会影响后续的任务创建及调度,这需要手动恢复manager节点。

而为了更好的应对该情况,推荐设置多个manager节点,来形成冗余。当一个manager节点发生故障时,其他的manager将接替其工作,以此来提高集群的可用性。

要利用 swarm 模式的容错功能,Docker 建议您根据组织的高可用性要求实施奇数个节点。当您有多个管理器时,您可以在不停机的情况下从管理器节点的故障中恢复。

  • 一个三管理器群最多可以容忍一个管理器的损失。
  • 一个五管理器群最多可以容忍两个管理器节点同时丢失。
  • 集群中奇数个N管理器节点最多容忍丢失(N-1)/2管理器。Docker 建议一个 swarm 最多有七个管理器节点。

1、什么是swarm?

Docker 引擎中嵌入的集群管理和编排功能是使用swarmkit 构建的。Swarmkit 是一个单独的项目,它实现了 Docker 的编排层,直接在 Docker 内部使用。

一个 swarm 由多个 Docker 主机组成,这些主机以swarm 模式运行并充当管理器(管理成员资格和委派)和工作人员(运行 swarm 服务)。给定的 Docker 主机可以是管理者、工作者,也可以兼任这两种角色。创建服务时,您定义其最佳状态(副本数、可用的网络和存储资源、服务向外界公开的端口等)。Docker 致力于维护所需的状态。例如,如果工作节点变得不可用,Docker 会在其他节点上安排该节点的任务。任务是一个 正在运行的容器,它是 swarm 服务的一部分,由 swarm 管理器管理,而不是一个独立的容器。

与独立容器相比,swarm 服务的主要优势之一是您可以修改服务的配置,包括它所连接的网络和卷,而无需手动重启服务。Docker 将更新配置,停止具有过时配置的服务任务,并创建与所需配置匹配的新任务。

当 Docker 在 swarm 模式下运行时,您仍然可以在参与 swarm 的任何 Docker 主机上运行独立容器,以及 swarm 服务。独立容器和 swarm 服务之间的一个关键区别是只有 swarm 管理器可以管理 swarm,而独立容器可以在任何守护进程上启动。Docker 守护进程可以作为管理器、工作器或两者参与集群。

就像您可以使用Docker Compose定义和运行容器一样,您可以定义和运行Swarm 服务堆栈。

2、节点

节点是参与 swarm 的 Docker 引擎实例。您也可以将其视为 Docker 节点。您可以在一台物理计算机或云服务器上运行一个或多个节点,但生产集群部署通常包括分布在多个物理和云计算机上的 Docker 节点。

要将您的应用程序部署到群中,您需要将服务定义提交给 管理器节点。管理节点将称为 任务的工作单元分派给工作节点。

管理器节点还执行维护集群所需状态所需的编排和集群管理功能。管理器节点选择一个领导者来执行编排任务。

工作节点接收并执行从管理节点分派的任务。默认情况下,管理器节点也将服务作为工作节点运行,但您可以将它们配置为专门运行管理器任务并成为仅管理器节点。代理在每个工作节点上运行并报告分配给它的任务。工作节点将其分配任务的当前状态通知管理节点,以便管理节点可以维护每个工作节点的所需状态。

3、服务和任务

服务是要在管理器或工作节点上执行的任务的定义。它是蜂群系统的中心结构,也是用户与蜂群交互的主要根源。

创建服务时,您指定要使用的容器映像以及要在运行的容器内执行的命令。

复制服务模型中,群管理器根据您在所需状态下设置的规模在节点之间分配特定数量的副本任务。

对于全局服务,swarm 在集群中的每个可用节点上为服务运行一个任务。

任务携带 Docker 容器和在容器内运行的命令。它是swarm的原子调度单元。管理器节点根据服务规模中设置的副本数将任务分配给工作器节点。一旦任务分配给一个节点,它就不能移动到另一个节点。它只能在分配的节点上运行或失败。

创建服务时,您指定要使用的容器映像以及要在运行的容器内执行的命令。您还可以为服务定义选项,包括:

  • 群使服务在群外可用的端口
  • 服务连接到 swarm 中其他服务的覆盖网络
  • CPU 和内存限制和预留
  • 滚动更新策略
  • 要在 swarm 中运行的图像副本数

4、负载均衡

Swarm 管理器使用入口负载平衡来公开您希望在外部提供给 Swarm 的服务。Swarm 管理器可以自动为服务分配PublishedPort,或者您可以为服务配置 PublishedPort。您可以指定任何未使用的端口。如果不指定端口,swarm 管理器会为服务分配一个 30000-32767 范围内的端口。

外部组件(例如云负载平衡器)可以访问集群中任何节点的 PublishedPort 上的服务,无论该节点当前是否正在运行该服务的任务。swarm 中的所有节点都将入口连接路由到正在运行的任务实例。

Swarm 模式有一个内部 DNS 组件,可以自动为 swarm 中的每个服务分配一个 DNS 条目。Swarm 管理器使用内部负载平衡根据服务的 DNS 名称在集群内的服务之间分配请求。

3、服务部署

1、设置环境

主机之间的开放协议和端口,以下端口必须可用。在某些系统上,这些端口默认是打开的。

  • 用于集群管理通信的TCP 端口 2377
  • 用于节点间通信的TCPUDP 端口 7946
  • 覆盖网络流量的UDP 端口 4789

2、初始化集群

# docker swarm init --advertise-addr 192.168.1.10
Swarm initialized: current node (ifs6xxct4dbmmkjsq7oawpu30) is now a manager.

To add a worker to this swarm, run the following command:
# 添加work节点运行的命令
    docker swarm join --token SWMTKN-1-1m3lg48xri63c8nhhdjoidcwi2tdugrqa367g2uvsijgd405rd-4snc764xlxzh3ghtfcaxx8uzp 192.168.1.10:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
参数说明
--advertise-addr指定与其他Node通信的地址
--token据标志的值作为管理者或工作者加入

查看节点信息

# docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
ifs6xxct4dbmmkjsq7oawpu30 *   docker01            Ready               Active              Leader              18.09.0

3、节点操作

1、添加work节点
# docker swarm join --token SWMTKN-1-1m3lg48xri63c8nhhdjoidcwi2tdugrqa367g2uvsijgd405rd-4snc764xlxzh3ghtfcaxx8uzp 192.168.1.10:2377
# docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
ifs6xxct4dbmmkjsq7oawpu30 *   docker01            Ready               Active              Leader              18.09.0
y32kx76irorhbq3zpjoe13cs9     docker02            Ready               Active                                  18.09.0
vb2lonkjx944wyrofd3xplqop     docker03            Ready               Active                                  18.09.0
2、添加manager 节点

运行swarm join-token --rotate使旧令牌失效并生成新令牌。指定是否要为workermanager 节点轮换令牌,当忘记旧令牌需要添加新节点时也可以使用这个命令

# docker swarm join-token manager
To add a manager to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-1m3lg48xri63c8nhhdjoidcwi2tdugrqa367g2uvsijgd405rd-dyrnsrnxwm84i1nk4aniw1so4 192.168.1.10:2377
# docker swarm join --token SWMTKN-1-1m3lg48xri63c8nhhdjoidcwi2tdugrqa367g2uvsijgd405rd-dyrnsrnxwm84i1nk4aniw1so4 192.168.1.10:2377
This node joined a swarm as a manager.
# docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
ifs6xxct4dbmmkjsq7oawpu30 *   docker01            Ready               Drain               Leader              18.09.0
y32kx76irorhbq3zpjoe13cs9     docker02            Ready               Active                                  18.09.0
j6n7zb15uyqzx63cfyr7ptff2     docker03            Ready               Active              Reachable           18.09.0
3、节点升级

将warm节点的work升级为manage

# docker node promote docker02
Node docker02 promoted to a manager in the swarm.
# docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
ifs6xxct4dbmmkjsq7oawpu30 *   docker01            Ready               Drain               Leader              18.09.0
y32kx76irorhbq3zpjoe13cs9     docker02            Ready               Active              Reachable           18.09.0
vb2lonkjx944wyrofd3xplqop     docker03            Ready               Active                                  18.09.0
4、节点降级

将swarm节点的manager降级为work

# docker node demote docker02
Manager docker02 demoted in the swarm.
# docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
ifs6xxct4dbmmkjsq7oawpu30 *   docker01            Ready               Drain               Leader              18.09.0
y32kx76irorhbq3zpjoe13cs9     docker02            Ready               Active                                  18.09.0
vb2lonkjx944wyrofd3xplqop     docker03            Ready               Active                                  18.09.0
5、节点申请离开一个集群
# docker swarm leave
Node left the swarm.
# docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
ifs6xxct4dbmmkjsq7oawpu30 *   docker01            Ready               Drain               Leader              18.09.0
y32kx76irorhbq3zpjoe13cs9     docker02            Ready               Active                                  18.09.0
vb2lonkjx944wyrofd3xplqop     docker03            Down                Active                       
6、删除节点
# docker node rm docker03
docker03
# docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
ifs6xxct4dbmmkjsq7oawpu30 *   docker01            Ready               Drain               Leader              18.09.0
y32kx76irorhbq3zpjoe13cs9     docker02            Ready               Active                                  18.09.0

4、使用docker swarm集群网络

Docker Engine swarm 模式可以轻松发布服务端口,使它们可供 swarm 外部的资源使用。所有节点都参与一个入口路由网格。路由网格使 swarm 中的每个节点都可以接受已发布端口上的连接,以供 swarm 中运行的任何服务使用,即使节点上没有运行任何任务也是如此。路由网格将所有传入请求路由到可用节点上的已发布端口到活动容器。

由于一个service会包含多个容器副本,多个副本可以看成一个service整体,它们通常只干一类相同的事情。而稍复杂一点的情况是,一个service可能还需要依赖其他service的能力才能完成任务,那么这就涉及从一个service到另一个service的调用。那么因此在swarm中最常见的2种网络访问是:

  • 外部至swarm内部的service的调用
  • swarm内部,service至service的调用

Service到Service的调用,在swarm中将使用overlay网络解决该问题,overlay是一种覆盖多个主机的虚拟网络,它是利用路由转发策略将对虚拟网络中ip的请求转发至具体容器IP上来完成通信。

而在swarm中不仅如此,还将使用Docker内部的DNS为服务名进行DNS解析,这意味着你可以在swarm集群内部使用服务名称来访问对应的service。在swarm集群中一个service可被其他容器应用调用,该调用可以基于服务名的DNS记录,如果一个service分配的vip,那么使用服务名调用DNS将解析为vip,vip在对应具体的容器副本IP,而如果使用dnsrr模式(轮询),则使用服务名调用时会直接返回一个具体的容器副本ip。

外部到service的调用,在swarm中仍然采用端口映射方式,使用宿主机端口映射到overlay网络分配的容器副本IP,而这种映射仍然基于一种多副本间的轮询。即使宿主机中并没有实际运行对应的容器副本,那么该主机仍然会使用本地端口,转发请求至其他主机上的容器副本。

在swarm初始化过程中,会创建一个默认的overlay网络名为ingress,当然也支持用户自定义自己的overlay网络。要让service使用自定义的网络,那么在创建service时,指定需要使用的网络名称即可。

创建一个自定义overlay网络

要创建可由 swarm 服务 独立容器使用以与在其他 Docker 守护进程上运行的其他独立容器通信的覆盖网络,请添加--attachable标志

# docker network create -d overlay --attachable docker
55dzciuvpuimx1fzyvgyrnrkh

1、创建服务时发布一个端口

将 nginx 容器中的 80 端口发布到 swarm 中任意节点的 8080 端口

docker service create --name my-web --network docker --publish published=8080,target=80 --replicas 2 nginx
参数说明
--name服务名称
published用于指定路由网格上绑定的端口。如果省略它,则会绑定一个随机的高编号端口
target用于指定容器内部的端口
--network指定网络

2、为现有服务发布端口

docker service update --publish-add published=8080,target=80 service名称

3、使用本地网络

您可以绕过路由网格,这样当您访问给定节点上的绑定端口时,您始终访问的是运行在该节点上的服务实例。这称为host模式。

  • 如果您访问未运行服务任务的节点,则该服务不会侦听该端口。可能没有任何东西在监听,或者一个完全不同的应用程序在监听。
  • 如果您希望在每个节点上运行多个服务任务(例如当您有 5 个节点但运行 10 个副本时),则不能指定静态目标端口。要么允许 Docker 分配一个随机的高编号端口(通过省略 published),要么通过使用全局服务而不是复制服务,或者通过使用放置约束,确保只有一个服务实例在给定节点上运行。

默认情况下,发布端口的群服务使用路由网格来实现。当您连接到任何 swarm 节点上的已发布端口时(无论它是否正在运行给定服务),您将被透明地重定向到正在运行该服务的工作人员。实际上,Docker 充当了集群服务的负载均衡器。使用路由网格的服务以虚拟 IP (VIP) 模式运行。即使是在每个节点上运行的服务(通过--mode global 标志)也使用路由网格。使用路由网格时,无法保证哪个 Docker 节点为客户端请求提供服务。

要绕过路由网格,您可以使用DNS 循环 (DNSRR) 模式启动服务,方法是将--endpoint-mode标志设置为dnsrr。您必须在服务前面运行您自己的负载均衡器。对 Docker 主机上服务名称的 DNS 查询返回运行该服务的节点的 IP 地址列表。配置您的负载均衡器以使用此列表并平衡节点之间的流量。

要绕过路由网格,您必须使用长--publish服务并设置modehost. 如果省略mode密钥或将其设置为ingress,则使用路由网格。以下命令使用 host模式创建全局服务并绕过路由网格。

docker service create --name dns-cache \
  --publish published=53,target=53,protocol=udp,mode=host \
  --mode global \
  dns-cache

4、配置服务发现

服务发现是 Docker 用于将请求从服务的外部客户端路由到单个群节点的机制,客户端无需知道有多少节点参与了服务或其 IP 地址或端口。您不需要发布在同一网络上的服务之间使用的端口。例如,如果您有一个 WordPress 服务将其数据存储在 MySQL 服务中,并且它们连接到同一个覆盖网络,则不需要向客户端发布 MySQL 端口,只需发布 WordPress HTTP 端口。

服务发现可以以两种不同的方式工作:使用嵌入式 DNS 和虚拟 IP (VIP) 在第 3 层和第 4 层进行基于内部连接的负载平衡,或者使用 DNS 循环在第 7 层进行基于外部和自定义请求的负载平衡(DNSRR)。您可以为每个服务配置它。

  • 默认情况下,当您将一项服务附加到网络并且该服务发布一个或多个端口时,Docker 会为该服务分配一个虚拟 IP (VIP),这是客户端访问该服务的“前端”。Docker 保留服务中所有工作节点的列表,并在客户端和其中一个节点之间路由请求。来自客户端的每个请求都可能被路由到不同的节点。

  • 如果将服务配置为使用 DNS 循环 (DNSRR) 服务发现,则不会有单个虚拟 IP。相反,Docker 为服务设置 DNS 条目,以便对服务名称的 DNS 查询返回 IP 地址列表,客户端直接连接到其中一个。

    如果您想使用自己的负载均衡器(例如 HAProxy),DNS 轮询非常有用。要将服务配置为使用 DNSRR,请 --endpoint-mode dnsrr在创建新服务或更新现有服务时使用该标志。

5、service(服务)

在Swarm集群中容器被看成是服务,多个相同的容器副本,也可看作是一服务的多个副本。那么在swarm集群中部署服务也比较简单,需要提供最基本的信息就是容器镜像信息,在只提供镜像信息时,将创建一个简单的服务只有一个容器副本,并且也不可被外部访问。

1、创建service

# docker service create --replicas 1 --network docker --name web1 -p 80 nginx
jqubcwzqomj1dogwc2x7v887n
overall progress: 1 out of 1 tasks 
1/1: running   
verify: Service converged 
参数说明
--replicas副本数量

2、查看service

# docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
soux8c2909bo        web1                replicated          1/1                 nginx:latest        *:30000->80/tcp

3、查看哪些节点正在运行服务

# docker service ps web1 
ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE            ERROR               PORTS
oshddet9cjky        web1.1              nginx:latest        docker01            Running             Running 31 seconds ago     

4、删除服务

# docker service rm web1
web1

5、扩展服务

scale进行设置副本数量

# docker service scale web=6
web scaled to 6
overall progress: 6 out of 6 tasks 
1/6: running   
2/6: running   
3/6: running   
4/6: running   
5/6: running   
6/6: running   
verify: Service converged 

6、服务的升级与回滚

调度程序默认按如下方式应用滚动更新:

  • 停止第一个任务。
  • 为已停止的任务安排更新。
  • 启动更新任务的容器。
  • 如果对任务的更新返回RUNNING,等待指定的延迟时间,然后开始下一个任务。
  • 如果在更新期间的任何时候任务返回FAILED,则暂停更新。
1、更新
# docker service update --image 192.168.1.10:5000/httpd.v2 web
web
overall progress: 6 out of 6 tasks 
1/6: running   
2/6: running   
3/6: running   
4/6: running   
5/6: running   
6/6: running   
verify: Service converged 

或者

# docker service update --image 192.168.1.10:5000/httpd.v3 --update-parallelism 2 --update-delay 1m web 
web
overall progress: 6 out of 6 tasks 
1/6: running   
2/6: running   
3/6: running   
4/6: running   
5/6: running   
6/6: running   
verify: Service converged 
参数说明
--update-parallelism设置并行更新的副本数量
--update-delay指定滚动更新的时间间隔
2、回滚
# docker service rollback web
web
rollback: manually requested rollback 
overall progress: rolling back update: 6 out of 6 tasks 
1/6: running   
2/6: running   
3/6: running   
4/6: running   
5/6: running   
6/6: running   
verify: Service converged 

7、设置manager node工作状态

所有节点都在ACTIVE 可用性上运行。swarm manager 可以将任务分配给任何ACTIVE节点,因此到目前为止所有节点都可以接收任务。

有时,例如计划维护时间,您需要将节点设置为DRAIN 可用。DRAIN可用性阻止节点从群管理器接收新任务。这也意味着管理器停止在节点上运行的任务并在可用的节点上启动副本任务ACTIVE

::: tip
将节点设置为DRAIN不会从该节点中删除独立容器,例如使用 、 或 Docker Engine API 创建的docker run容器docker-compose up。一个节点的状态,包括DRAIN,只会影响节点调度 swarm 服务工作负载的能力。
:::

将节点状态设置为暂停

# docker node update docker01 --availability active|pause|drain
docker01                                                         活跃|暂停|关闭

8、指定容器运行节点

节点标签提供了一种灵活的节点组织方法。您还可以在服务约束中使用节点标签。在创建服务时应用约束以限制调度程序为服务分配任务的节点。

1、节点添加或删除标签元数据
# docker node update --label-add disk=max docker02
docker02
2、查看标签信息
# docker node inspect docker02
[
    {
        "ID": "y32kx76irorhbq3zpjoe13cs9",
        "Version": {
            "Index": 310
        },
        "CreatedAt": "2020-09-28T14:34:56.097756526Z",
        "UpdatedAt": "2020-09-29T03:42:20.865860853Z",
        "Spec": {
            "Labels": {
                "disk": "max"
            },
3、运行服务,指定节点
# docker service create --name test --replicas 3 --constraint 'node.labels.disk == max' nginx
z5momze933w5ewyxm864orayk
overall progress: 3 out of 3 tasks 
1/3: running   
2/3: running   
3/3: running   
verify: Service converged 
# docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
z3ysfn8ukure        test                replicated          3/3                 nginx:latest        
# docker service ps test
ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE            ERROR               PORTS
30mli9tz2tv0        test.1              nginx:latest        docker02            Running             Running 12 seconds ago                       
ja1ewvxnvvvt        test.2              nginx:latest        docker02            Running             Running 12 seconds ago                       
ni7nhj53s2vc        test.3              nginx:latest        docker02            Running             Running 12 seconds ago       

6、配置管理(Docker Configs)

Docker swarm 服务配置允许您将非敏感信息(例如配置文件)存储在服务映像或正在运行的容器之外。这使您可以使图像尽可能通用,而无需将配置文件绑定到容器或使用环境变量。

配置以类似于secrets的方式运行,除了它们没有静态加密并且直接挂载到容器的文件系统中而不使用 RAM 磁盘。可以随时在服务中添加或删除配置,并且服务可以共享配置。您甚至可以将配置与环境变量或标签结合使用,以获得最大的灵活性。配置值可以是通用字符串或二进制内容(最大 500 kb)。

::: warning
Docker 配置仅适用于 swarm 服务,不适用于独立容器。要使用此功能,请考虑调整您的容器以作为规模为 1 的服务运行。
:::

1、生成配置文件

在当前目录中,创建一个名为site.conf以下内容的新文件

server {
    listen                80;
    server_name           localhost;
  #  ssl_certificate       /run/secrets/site.crt;
  #  ssl_certificate_key   /run/secrets/site.key;
    
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
}

2、创建配置

将文件保存site.conf在 Docker 配置中。第一个参数是配置的名称,第二个参数是要从中读取的文件。

# docker config create site.conf site.conf
# docker config ls
ID                          NAME                CREATED             UPDATED
4ory233120ccg7biwvy11gl5z   site.conf           4 seconds ago       4 seconds ago

也可以使用标签(-l,--label)创建配置

docker config create \
    --label env=dev \
    --label rev=20230202 \
    site.conf site.conf

3、使用配置

创建一个运行 Nginx 并有权访问这两个密钥和配置的服务。将模式设置为,0440以便文件只能由其所有者和该所有者的组读取,而不是所有。

docker service create \
     --name nginx \
     --config source=site.conf,target=/etc/nginx/conf.d/site.conf,mode=0440 \
     --publish published=3000,target=443 \
     nginx:latest \
     sh -c "exec nginx -g 'daemon off;'"

4、更新配置

# 使用site.conf名为site-v2.conf
docker config create site-v2.conf site.conf
# 更新nginx服务以使用新配置而不是旧配置
docker service update \
  --config-rm site.conf \
  --config-add source=site-v2.conf,target=/etc/nginx/conf.d/site.conf,mode=0440 \
  nginx

5、删除配置

# docker config rm site.conf

7、秘钥管理(Docker secrets)

就 Docker Swarm 服务而言,秘密是一团数据,例如密码、SSH 私钥、SSL 证书或其他不应通过网络传输或未加密存储在 Dockerfile 或应用程序中的数据源代码。您可以使用 Docker机密来集中管理此数据,并将其安全地传输到仅需要访问它的那些容器。秘密在传输过程中被加密,并在 Docker 群中处于静止状态。给定的秘密只能由那些已被授予明确访问权限的服务访问,并且只能在这些服务任务运行时访问。

您可以使用机密来管理容器在运行时需要的任何敏感数据,但您不想将其存储在图像或源代码管理中,例如:

  • 用户名和密码
  • TLS 证书和密钥
  • SSH 密钥
  • 其他重要数据,例如数据库或内部服务器的名称
  • 通用字符串或二进制内容(最大 500 kb)

1、生成配置文件

在当前目录中,创建一个名为site.conf以下内容的新文件

server {
    listen                443 ssl;
    server_name           localhost;
    ssl_certificate       /run/secrets/site.crt;
    ssl_certificate_key   /run/secrets/site.key;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
}

2、创建秘钥

创建三个秘密,分别代表密钥、证书和 site.conf

docker secret create site.key site.key
docker secret create site.crt site.crt
docker secret create site.conf site.conf

3、使用秘钥

默认情况下,秘钥位于/run/secrets/容器的目录中,为方便使用,可以使用该target选项指定自定义位置

docker service create \
     --name nginx \
     --secret site.key \
     --secret site.crt \
     --secret source=site.conf,target=/etc/nginx/conf.d/site.conf \
     --publish published=3000,target=443 \
     nginx:latest \
     sh -c "exec nginx -g 'daemon off;'"

4、删除秘钥

docker secret rm site.crt site.key site.conf

5、docker-compose使用秘钥

1、创建秘钥

::: warning
创建密文后,您将无法更新它。您只能删除并重新创建它,而不能删除服务正在使用的秘密。但是,您可以使用授予或撤销正在运行的服务对机密的访问权限docker service update。如果您需要更新秘密的能力,请考虑向秘密名称添加版本组件,以便您以后可以添加新版本,更新服务以使用它,然后删除旧版本。
:::

# 该密码仅作为 MySQL 连接应用密码,不作他用
openssl rand -base64 20 | docker secret create mysql_password -
# root为 MySQL用户生成第二个秘密。此机密不会与稍后创建的服务共享。它只需要引导mysql服务
openssl rand -base64 20 | docker secret create mysql_root_password -
  • 这些机密分别安装在tmpfs文件系统中的 /run/secrets/mysql_password/run/secrets/mysql_root_passworddocker commit它们永远不会作为环境变量公开,如果运行命令,它们也不能提交给image。mysql_password 秘密是非特权应用容器用来连接 MySQL的秘密。
  • 设置环境变量MYSQL_PASSWORD_FILEMYSQL_ROOT_PASSWORD_FILE指向文件/run/secrets/mysql_password/run/secrets/mysql_root_password. 该mysql镜像在首次初始化系统数据库时从这些文件中读取密码字符串。之后,密码存储在 MySQL 系统数据库本身中。
2、使用秘钥
version: "3.9"

services:
   db:
     image: mysql:latest
     volumes:
       - db_data:/var/lib/mysql
     environment:
       MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_password
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD_FILE: /run/secrets/db_password
     secrets:
       - db_root_password
       - db_password

   wordpress:
     depends_on:
       - db
     image: wordpress:latest
     ports:
       - "8000:80"
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_USER: wordpress
       WORDPRESS_DB_PASSWORD_FILE: /run/secrets/db_password
     secrets:
       - db_password


secrets:
   db_password:
     file: db_password.txt
   db_root_password:
     file: db_root_password.txt

volumes:
    db_data:

部署时,Docker/run/secrets/<secret_name>会在服务下挂载一个文件。这些文件永远不会保存在磁盘中,而是在内存中进行管理。

3、轮换秘钥
# 创建新密码并将其存储为名为mysql_password_v2的秘钥
openssl rand -base64 20 | docker secret create mysql_password_v2 -

注意:您无法更新或重命名机密,但您可以撤销机密并使用新的目标文件名授予对其的访问权限。

# 撤销秘钥
docker service update \
     --secret-rm mysql_password mysql
# 重新指定秘钥
docker service update \
     --secret-add source=mysql_password,target=old_mysql_password \
     --secret-add source=mysql_password_v2,target=mysql_password \
     mysql

尽管 MySQL 服务现在可以访问新旧密码,但应用用户的 MySQL 密码尚未更改,所以更换秘钥后还需要手动使用 mysqladminCLI更改用户的 MySQL 密码

docker container exec <CONTAINER_ID> \
    bash -c 'mysqladmin --user=wordpress --password="$(< /run/secrets/old_mysql_password)" password "$(< /run/secrets/mysql_password)"'
    
docker service update \
     --secret-rm mysql_password \
     --secret-add source=mysql_password_v2,target=wp_db_password,mode=0400 \
     wordpress   

8、使用stack部署

在单机模式下通过docker-compose来进行一次部署多个容器,那么在swarm集群下,也可使用compose的清单文件来进行多服务部署。

在swarm应用部署,首先需要准备一份清单也就是之前提到的YAML格式书写的compose文件,不同之外是可以增加一些针对swarm的参数。

1、参数介绍

# vim nginx.yaml
version: "3.7"

networks:
  myingress:
    external: true					# 表示该网络已经存在于集群中

services:
  nginx:
    image: "nginx:1.19.6"
    environment:
  	  RACK_ENV: development
  	  SHOW: 'true'
  	  SESSION_SECRET:
	environment:
  	  - RACK_ENV=development
  	  - SHOW=true
  	  - SESSION_SECRET
    healthcheck:					# 健康检查
      test: ["CMD-SHELL", "curl -sS 127.0.0.1:80 || exit 1"]		# 定义用于检测的命令
      interval: 60s					# 命令执行的间隔 默认30s
      timeout: 10s					# 命令超时的时间 默认30s
      retries: 2					# 命令失败重试的次数
      start_period: 30s				# 启动延时,即容器启动后多久开始执行检测
    command:
      - "echo"
      - "error"
    networks:						# 采用哪个网络,不写则是默认
      - myingress
    expose:							# 开放容器的端口而不用在主机上暴露端口,它们只能被相关联的服务获取。只能指定内部端口
 	  - "3000"
      - "8000"
    ports:
      - "10000:80"
    deploy:							# 服务部署,多个服务同属于一个deploy
      mode: replicated				# 副本模式,选取与设置的副本数相等的worker然后在其上完成副本创建
      #mode: global					# 全局模式,在所有worker节点上创建副本
      labels:						# 指定服务的标签
        com.example.description: "This label will appear on the web service"
      replicas: 3					# 设置副本(replicas)为3
      endpoint_mode: dnsrr			# DNS轮询模式
      #endpoint_mode: vip			# 虚拟 IP模式
      restart_policy:				# 重启策略
        condition: on-failure		# 什么时机进行重启,none(从不重启)、on-failure(在运行失败时进行重启)和any(总是重启)
        delay: 10s					# 发生错误后多长时间执行重启
        max_attempts: 3				# 最多重启几次
        window: 120s				# 重启的超时时间
      update_config:				# 更新策略
        parallelism: 1				# 一次更新的容器数
        delay: 1s					# 在更新一组容器之间等待的时间
        failure_action: rollback	# 如果更新失败,该怎么办,continue(继续),rollback(回滚),pause(暂停)
        monitor: 500ms				# 每个容器更新后,持续观察是否失败了的时间
        max_failure_ratio: 0		# 在更新过程中可以容忍的故障率
        order: stop-first			# 更新期间的操作顺序,stop-first(串行更新),start-first(并行更新)
      rollback_config:				# 回滚策略
        parallelism: 1				# 一次回滚的容器数
        delay: 0s					# 在回滚一组容器之间等待的时间
        failure_action: rollback	# 如果回滚失败,该怎么办,continue(继续),rollback(回滚),pause(暂停)
        monitor: 500ms				# 每个容器回滚后,持续观察是否失败了的时间
      resources:					# 资源限制
        limits:						# 上限
          cpus: '1'
          memory: 500m
        reservations:				# 初始值
          cpus: '0.5'
          memory: 250m
endpoint_mode参数说明
vipDocker 为服务分配一个虚拟 IP (VIP),充当客户端访问网络服务的前端。Docker 在客户端和服务的可用工作节点之间路由请求,而客户端不知道有多少节点参与了服务或它们的 IP 地址或端口。(这是默认设置。)
dnsrrDNS 循环 (DNSRR) 服务发现不使用单个虚拟 IP。Docker 为服务设置 DNS 条目,以便对服务名称的 DNS 查询返回 IP 地址列表,客户端直接连接到其中一个。DNS 轮询在您想要使用自己的负载平衡器或混合 Windows 和 Linux 应用程序的情况下很有用。

2、常用 stack 命令

# 部署命令来创建服务
docker stack deploy --with-registry-auth -c nginx.yaml demo 
# 查看deploy下的服务
docker stack services demo
# 查看当前集群拥有哪些deploy
docker stack ps demo
# 删除部署
docker stack rm demo
# 更新服务
docker service update --fore --with-registry-auth --images nginx:latest demo
参数说明
--with-registry-auth向swarm agents发送注册表身份验证详细信息(使用私有仓库时启用),原理:会将manager节点本地客户端的登录token传送到swarm集群中service运行的节点。使用这个token信息,节点可以登录到私有仓库,然后拉取镜像
--fore强制更新,即使没有更改
0

评论区