Docker-Swarm速成
在生产环境使用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/
1 | version: "3.9" |
docker-stack 不支持的docker-compose配置
- build
- cgroup_parent
- container_name
- devices
- tmpfs
- external_links
- links
- network_mode
- restart
- security_opt
- userns_mode
节点管理
更多高级操作:
- 给 Swarm 添加节点
- 管理集群中的节点
创建一个新的 Manager Node
使用
docker swarm init
命令创建一个 Manager Node.
-advertise-addr
参数将 Manager Node 监听的IP设置为:
192.168.99.100
.
注意,使用
-advertise-addr
默认监听的端口为
1 | 2377 |
swarm 中的其他 Node 必须能访问 Manager Node 的 IP.
输出包括将新节点加入 swarm 的命令。根据
-token
标志的值,节点将作为Master或Worker加入。
1 | docker swarm init --advertise-addr ManagerIP地址 |
例:
1 | root@u2004:/home/ubuntu# docker swarm init --advertise-addr 192.168.1.80 |
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 |
查看节点列表
使用以下命令查看节点列表,节点
ID
旁边的 *
表示你当前已经连接到此节点
1 | docker node ls |
例:
1 | root@u2004:/home/ubuntu# docker node ls |
查看节点详细信息
使用以下命令查看节点的详情:
1 | docker node inspect --pretty 节点名称 |
添加新的 Manager Node 到集群
在另一台机器运行 docker swarm join
命令加入已存在的集群中
1 | root@u2004:/home/ubuntu# docker swarm join-token managerTo add a manager to this swarm, run the following command: docker swarm join --token SWMTKN-1-5qv7t73fvawvh795ckh3nxl9vnyo2hwwsqnnjwqyav3spj7ufu-ca1v0jiu9xwb6o20dqqajl4n1 192.168.1.80:2377 |
Manager Node 必须是单数(Raft),生产环境推荐3台或5台作为 Manager Node
docker swarm join-token manager 命令用于获取添加新的 Manager Node 的命令参数
添加新的 Worker Node 到集群
在另一台机器运行
docker swarm join
命令加入已存在的集群中
1 | docker swarm join --token SWMTKN-1-5qv7t73fvawvh795ckh3nxl9vnyo2hwwsqnnjwqyav3spj7ufu-1i7wir7oc3g9fh7yidg19i8p5 192.168.1.80:2377 |
docker swarm join-token worker 命令用于获取添加新的 Worker Node 的命令参数
禁用节点
在某些情况下我们想要将某个节点禁用或将节点中运行的容器清空,使用以下命令即可实现:
1 | docker node update --availability drain 节点名称 |
被禁用的节点仍然存在集群中,只是不会被swarm调度运行容器实例
启用节点
禁用节点后使用以下命令即可启用节点:
1 | docker node update --availability active 节点名称 |
更新节点
更新节点
1 | docker node update --label-add foo --label-add bar=baz 节点名称 |
服务管理
更多高级操作:
https://docs.docker.com/engine/reference/commandline/service/
https://docs.docker.com/compose/compose-file/compose-file-v3/#placement
运行服务
连接到 Manager Node,使用
docker service create
命令创建服务.
例:
1 | docker service create --replicas 1 --name helloworld alpine ping docker.com |
-name
指定服务名称为helloworld
-replicas
指定服务运行实例数量为1
- 参数
alpine
表示运行的镜像为Alpine Linux
- 参数
ping docker.com
表示在容器中执行的命令
查看运行的服务
在 Manager Node 运行此命令查看正在运行的服务列表:
1 | docker service ls |
例:
1 | root@u2004:/home/ubuntu# docker service ls |
查看服务的详细信息
在 Manager Node 运行此命令查看服务的运行详情:
1 | docker service inspect --pretty 服务名称 |
参数 --pretty 表示返回格式化后的详细信息,不加这个参数则打印 JSON 格式的信息
查看服务运行在那些节点
在 Manager Node 使用此命令查看服务都在那些节点运行:
1 | docker service ps 服务名称 |
docker-swarm 中的服务实例由 swarm 调度。因此有部分服务的实例运行在 Manager Node 是正常表现。
伸缩服务
docker-swarm 支持对服务实例进行动态伸缩,使用以下命令即可实现:
1 | docker service scale 服务名称=实例数量(最少为1) |
例:
1 | root@u2004:/home/ubuntu# docker service scale helloworld=2 |
删除服务
在 Manager Node 使用以下命令删除服务:
1 | docker service rm 服务名称 |
注意,因为是集群的原因,集群中的Node将会存在延迟的情况,想确认服务是否被删除成功请使用 docker service ls 查看
滚动更新服务
创建服务
进入 Manager Node 创建一个redis服务用于演示滚动更新:
1 | docker service create \ |
–update-dely 表示更新服务或服务集之间的时间延迟:1h10m3s,表示延迟1小时10分钟3秒。
调度器默认一次更新一个任务,可以通过 --update-parallelism 参数配置调度器同时更新服务数量。
默认情况下,当单个服务更新返回状态为 RUNNING,调度器会让另一个服务更新,直到所有服务都更新完成。
如果在更新期间某个服务返回 FAILED ,调度器会暂停更新,可以通过 --update-failure-action 参数配置控制当服务更新发生错误时的行为。
检查服务状态
1 | docker service inspect --pretty redis |
更新服务
1 | docker service update --image redis:3.0.7 redis |
默认情况下,调度器将按以下方式更新服务:
- 停止一个服务
- 更新已停止的服务
- 启动已更新的服务
如果更新的服务返回 RUNNING ,等待指定的延迟时间后开始更新下一个服务
如果更新期间某个服务返回 FAILED ,则暂停服务更新
重新启动暂停的服务更新
1 | docker service update redis |
为了避免重复某些失败的更新,可以重新指定更新参数
查看服务的滚动更新
1 | docker service ps redis |
在swarm更新完成所有服务之前,你可以看到一些服务的镜像为 redis:3.0.6,另一些为 redis:3.0.7
路由网格
docker swarm支持路由网格。路由网格让处于swarm集群中的任意一个节点都可以作为被访问的入口,即使此节点没有运行任何服务。
要在 swarm 集群中使用使用路由网格,首先需要开启加入swarm集群的节点的以下端口:
7946
:容器网络发现4789
:容器网络入口
其次需要将节点服务实例的端口公开,使服务可以被外部访问(例如使用nginx做负载均衡)
服务原理
创建服务时公开端口
1 | docker service create \ |
–publish 与 -p 效果相同,其中 --published 值为公布的端口,target 值为容器内部监听的端口。–publish 的写法
更新现有服务的公开端口
1 | docker service update \ |
查看服务发布的端口
1 | docker service inspect --format="{{json .Endpoint.Spec.Ports}}" 服务名称 |
只公开TCP或UDP端口
默认情况下公开端口都是 TCP 端口,你可以通过参数配置公开端口的类型:
仅TCP
1 | docker service create --name dns-cache \ |
或
1 | docker service create --name dns-cache \ |
仅UDP
1 | docker service create --name dns-cache \ |
或
1 | docker service create --name dns-cache \ |
TCP+UDP
1 | docker service create --name dns-cache \ |
或
1 | docker service create --name dns-cache \ |
绕过路由网格
要绕过 swarm 集群的路由网格,需要使用
-publish
参数设置mode
值为host
。
下面的命令使用
host
模式创建全局服务并绕过路由网格:
1 | docker service create --name dns-cache \ |
绕过路由网格后的注意事项:
- 如果你访问未运行服务的节点,则无法访问此服务
- 如果你希望在每个节点运行多个服务,就不能指定静态的端口。要么就允许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 传播给它。