节点管理
更多高级操作:
创建一个新的 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地址
例:
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.
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
例:
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
...
查看节点列表
使用以下命令查看节点列表,节点 ID
旁边的 *
表示你当前已经连接到此节点
docker node ls
例:
root@u2004:/home/ubuntu# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
9nxycsrinzgh5bgqwfus2ia8r * u2004 Ready Active Leader 20.10.11
查看节点详细信息
使用以下命令查看节点的详情:
docker node inspect --pretty 节点名称
添加新的 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
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
docker swarm join-token worker
命令用于获取添加新的 Worker Node 的命令参数
禁用节点
在某些情况下我们想要将某个节点禁用或将节点中运行的容器清空,使用以下命令即可实现:
docker node update --availability drain 节点名称
被禁用的节点仍然存在集群中,只是不会被swarm调度运行容器实例
启用节点
禁用节点后使用以下命令即可启用节点:
docker node update --availability active 节点名称
更新节点
更新节点
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
命令创建服务.
例:
docker service create --replicas 1 --name helloworld alpine ping docker.com
-
--name
指定服务名称为helloworld
-
--replicas
指定服务运行实例数量为1
- 参数
alpine
表示运行的镜像为Alpine Linux
- 参数
ping docker.com
表示在容器中执行的命令
查看运行的服务
在 Manager Node 运行此命令查看正在运行的服务列表:
docker service ls
例:
root@u2004:/home/ubuntu# docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
jkj80hnr73rn helloworld replicated 1/1 alpine:latest
查看服务的详细信息
在 Manager Node 运行此命令查看服务的运行详情:
docker service inspect --pretty 服务名称
参数
--pretty
表示返回格式化后的详细信息,不加这个参数则打印JSON
格式的信息
查看服务运行在那些节点
在 Manager Node 使用此命令查看服务都在那些节点运行:
docker service ps 服务名称
docker-swarm 中的服务实例由 swarm 调度。因此有部分服务的实例运行在 Manager Node 是正常表现。
伸缩服务
docker-swarm 支持对服务实例进行动态伸缩,使用以下命令即可实现:
docker service scale 服务名称=实例数量(最少为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
删除服务
在 Manager Node 使用以下命令删除服务:
docker service rm 服务名称
注意,因为是集群的原因,集群中的Node将会存在延迟的情况,想确认服务是否被删除成功请使用
docker service ls
查看
滚动更新服务
创建服务
进入 Manager Node 创建一个redis服务用于演示滚动更新:
docker service create \
--replicas 3 \
--name redis \
--update-delay 10s \
redis:3.0.6
--update-dely
表示更新服务或服务集之间的时间延迟:1h10m3s
,表示延迟1小时10分钟3秒。调度器默认一次更新一个任务,可以通过
--update-parallelism
参数配置调度器同时更新服务数量。默认情况下,当单个服务更新返回状态为
RUNNING
,调度器会让另一个服务更新,直到所有服务都更新完成。如果在更新期间某个服务返回
FAILED
,调度器会暂停更新,可以通过--update-failure-action
参数配置控制当服务更新发生错误时的行为。
检查服务状态
docker service inspect --pretty redis
更新服务
docker service update --image redis:3.0.7 redis
默认情况下,调度器将按以下方式更新服务:
- 停止一个服务
- 更新已停止的服务
- 启动已更新的服务
- 如果更新的服务返回
RUNNING
,等待指定的延迟时间后开始更新下一个服务- 如果更新期间某个服务返回
FAILED
,则暂停服务更新
重新启动暂停的服务更新
docker service update redis
为了避免重复某些失败的更新,可以重新指定更新参数
查看服务的滚动更新
docker service ps redis
在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>
--publish
与-p
效果相同,其中--published
值为公布的端口,target
值为容器内部监听的端口。现在推荐使用
--publish
的写法
更新现有服务的公开端口
docker service update \
--publish-add published=<PUBLISHED-PORT>,target=<CONTAINER-PORT> \
<SERVICE>
查看服务发布的端口
docker service inspect --format="{{json .Endpoint.Spec.Ports}}" 服务名称
只公开TCP或UDP端口
默认情况下公开端口都是 TCP 端口,你可以通过参数配置公开端口的类型:
仅TCP
docker service create --name dns-cache \
--publish published=53,target=53 \
dns-cache
或
docker service create --name dns-cache \
-p 53:53 \
dns-cache
仅UDP
docker service create --name dns-cache \
--publish published=53,target=53,protocol=udp \
dns-cache
或
docker service create --name dns-cache \
-p 53:53/udp \
dns-cache
TCP+UDP
docker service create --name dns-cache \
--publish published=53,target=53 \
--publish published=53,target=53,protocol=udp \
dns-cache
或
docker service create --name dns-cache \
-p 53:53 \
-p 53:53/udp \
dns-cache
绕过路由网格
要绕过 swarm 集群的路由网格,需要使用 --publish
参数设置 mode
值为host
。
下面的命令使用 host
模式创建全局服务并绕过路由网格:
docker service create --name dns-cache \
--publish published=53,target=53,protocol=udp,mode=host \
--mode global \
dns-cache
绕过路由网格后的注意事项:
- 如果你访问未运行服务的节点,则无法访问此服务
- 如果你希望在每个节点运行多个服务,就不能指定静态的端口。要么就允许docker随机分配一个公开端口(通过置空
published
参数的值实现)
配置管理
普通配置
https://docs.docker.com/engine/swarm/configs/
加密配置
https://docs.docker.com/engine/swarm/secrets/
锁定集群
默认情况下,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(新任务首先启动,运行中的任务会出现短暂重叠)
docker-stack 不支持的docker-compose配置
- build
- cgroup_parent
- container_name
- devices
- tmpfs
- external_links
- links
- network_mode
- restart
- security_opt
- userns_mode