一、概述
Swarm是docker的一种集群模式,由多个docker节点组成,一般最小规模为3节点。在这些节点中将划分两种角色:manager、workers;做为manager角色的节点将采用Raft算法进行选举,其中将会有一个成为leader,集群任务由该节点进行调度。当一个leader节点发生故障时,其他manager将会重新选举推出新的leader掌管集群。而worker节点负责运行维护服务副本,也就是具体的容器。
1、功能特点
与 Docker Engine 集成的集群管理:使用 Docker Engine CLI 创建一组 Docker Engine,您可以在其中部署应用程序服务。您不需要额外的编排软件来创建或管理集群。
去中心化: Docker 引擎不是在部署时处理节点角色之间的差异,而是在运行时处理任何专业化。您可以使用 Docker 引擎部署两种类型的节点、管理器和工作器。这意味着您可以从单个磁盘映像构建整个集群。
声明式服务模型: Docker Engine 使用声明式方法让您定义应用程序堆栈中各种服务的所需状态。例如,您可能会描述一个应用程序,该应用程序由具有消息队列服务和数据库后端的 Web 前端服务组成。
缩放:对于每个服务,您可以声明要运行的任务数量。当您扩大或缩小规模时,群管理器会通过添加或删除任务来自动适应以保持所需的状态。
期望状态协调: swarm 管理器节点不断监控集群状态,并协调实际状态和您表达的期望状态之间的任何差异。例如,如果您设置一个服务来运行容器的 10 个副本,并且托管其中两个副本的工作机器崩溃,则管理器会创建两个新副本来替换崩溃的副本。swarm manager 将新的副本分配给正在运行且可用的 worker。
多主机网络:您可以为您的服务指定一个覆盖网络。群管理器在初始化或更新应用程序时自动为覆盖网络上的容器分配地址。
服务发现: Swarm 管理器节点为 Swarm 中的每个服务分配一个唯一的 DNS 名称并平衡运行容器的负载。您可以通过嵌入在 swarm 中的 DNS 服务器查询在 swarm 中运行的每个容器。
负载均衡:您可以将服务的端口暴露给外部负载均衡器。在内部,swarm 允许您指定如何在节点之间分发服务容器。
默认安全: swarm 中的每个节点都强制执行 TLS 相互身份验证和加密,以保护自身与所有其他节点之间的通信。您可以选择使用自签名根证书或来自自定义根 CA 的证书。
滚动更新:在推出时,您可以增量地将服务更新应用到节点。swarm 管理器允许您控制服务部署到不同节点集之间的延迟。如果出现任何问题,您可以回滚到该服务的先前版本
2、节点
运行 Docker 的主机可以主动初始化一个 Swarm 集群或者加入一个已存在的 Swarm 集群,这样这个运行 Docker 的主机就成为一个 Swarm 集群的节点 (node) 。
节点分为管理 (manager) 节点和工作 (worker) 节点。
管理节点用于 Swarm 集群的管理,docker swarm 命令基本只能在管理节点执行(节点退出集群命令 docker swarm leave 可以在工作节点执行)。一个 Swarm 集群可以有多个管理节点,但只有一个管理节点可以成为 leader,leader 通过 raft 协议实现。通常,第一个启用docker swarm的节点将成为leader,后来加入的都是follower。当前的leader如果挂掉,剩余的节点将重新选举出一个新的leader。每一个manager都有一个完整的当前集群状态的副本,可以保证manager的高可用。
工作节点是任务执行节点,管理节点将服务 (service) 下发至工作节点执行。管理节点默认也作为工作节点。你也可以通过配置让服务只运行在管理节点。worker节点之间,通过control plane进行通信,这种通信使用gossip协议,并且是异步的。
来自 Docker 官网的这张图片形象的展示了集群中管理节点与工作节点的关系。
3、服务和任务
任务 (Task)是 Swarm 中的最小的调度单位,目前来说就是一个单一的容器。
服务 (Services) 是指一组任务的集合,服务定义了任务的属性。服务有两种模式:
replicated services 按照一定规则在各个工作节点上运行指定个数的任务。
global services 每个工作节点上运行一个任务
两种模式通过 docker service create 的 --mode 参数指定。
来自 Docker 官网的这张图片形象的展示了容器、任务、服务的关系
4、网络模式
在Swarm集群中,由于在容器上层又增加了一个service概念,因此对容器的访问更改成了对service的访问,然后再由一个service对应多个容器。那么一个service可能会包含多个容器副本,而这些容器副本多数情况下是运行在不同的主机中,为了实现service到具体容器副本的转发,在网络模式上与之前的单机的容器网络也将有
所不同。
services
swarm service是一个抽象的概念,它只是一个对运行在swarm集群上的应用服务,所期望状态的描述。它就像一个描述了下面物品的清单列表一样:
服务名称
使用哪个镜像来创建容器
要运行多少个副本
服务的容器要连接到哪个网络上
应该映射哪些端口
task
在Docker Swarm中,task是一个部署的最小单元,task与容器是一对一的关系。
stack
stack是描述一系列相关services的集合。我们通过在一个YAML文件中来定义一个stack。
由于一个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时,指定需要使用的网络名称即可。
在Swarm初始化完成后,默认会创建一个网桥docker_gwbridge,和一个veth设备,而在docker中对应的会出现两个网络,一个名为ingress的overlay网络,一个为docker_gwbridge桥接网络。不仅如此还会创建两个默认network namespace,这两个网络空间的名称为ingress_sbox和另一个ingress,数据包需要进入这两个网络空间中进行一些处理,然后才到达容器的网络空间中。
在Swarm集群中配置使用overlay网络的服务,首先overlay网络会拥有独立的网段,如10.0.0.0/24。那么默认情况下会从该网段中为服务分配的一个IP,该IP是一个虚拟IP,docker使用IPVS对该虚拟IP进行负载,负载至具体的容器IP上,该IP同样来自overlay网络段。
而容器也会拥有2个veth对,一个用于连接容器至docker_gwbridge,另一个用于连接容器至ingress网络空间;因此在容器的网络空间中会出现2个veth接口,分别拥有不同的IP。
二、swarm搭建
安装三台docker,128、129、130
[root@docker dockerfile]# docker swarm init
Error response from daemon: --live-restore daemon configuration is incompatible with swarm mode
docker swarm初始化和--live-restore参数不兼容
三台docker机器去掉这个参数并重启
[root@docker dockerfile]# docker swarm init
Swarm initialized: current node (q0o0dtete9jg1o5z1p5x82dr5) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-09ykfse4tnmz15df3d1vq9vk1jxzdhjjrqmc4r5acxq7yx5ax0-devvjbie9goc98m5ekuvg1efx 192.168.10.128:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
可以在其他机器直接执行docker swarm join --token SWMTKN-1-09ykfse4tnmz15df3d1vq9vk1jxzdhjjrqmc4r5acxq7yx5ax0-devvjbie9goc98m5ekuvg1efx 192.168.10.128:2377加入这个集群
也可以在当前节点执行docker swarm join-token manager重新生成加入集群的语句
[root@docker dockerfile]# docker swarm join-token manager
To add a manager to this swarm, run the following command:
docker swarm join --token SWMTKN-1-09ykfse4tnmz15df3d1vq9vk1jxzdhjjrqmc4r5acxq7yx5ax0-67zhyf4ffrdlg83qmzl81tcpk 192.168.10.128:2377
另外两台机器分别执行命令加入集群
[root@docker ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
q0o0dtete9jg1o5z1p5x82dr5 * docker Ready Active Leader 20.10.9
7443a0o2nwiyi8d7c7jr5uqob docker129 Ready Active Unreachable 20.10.11
mzo5jzic62dwbdtcqz11eum5a docker130 Ready Active Reachable 20.10.10
[root@docker ~]# docker info
Swarm: active
NodeID: q0o0dtete9jg1o5z1p5x82dr5
Is Manager: true
ClusterID: m9iiedb0wypylkgx1m7ofphey
Managers: 3 ##可以确定如果加入swarm集群,默认情况下Managers也是node节点
Nodes: 3
[root@docker ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
q0o0dtete9jg1o5z1p5x82dr5 * docker Ready Active Leader 20.10.9
7443a0o2nwiyi8d7c7jr5uqob docker129 Ready Active Reachable 20.10.11
mzo5jzic62dwbdtcqz11eum5a docker130 Ready Active 20.10.10
默认情况下manager同时也是worker,如果不想让manager同时承担worker的任务的话,执行如下指令,“drain”的意思是manager节点不再接受新的task,如果节点上已经有task在运行,则停止掉并调度到其它worker节点上去:
docker node update --availability drain manager
docker node update docker130 --role worker ##将docker130只设置为worker节点
最好只设置一个为管理节点,如果有两个以上管理节点,会因为开机的先后顺序,搞得leader来回跳,服务命令又只能在管理节点运行
也可以使用命令生成加入集群特定权限的语句
docker swarm join-token manager
docker swarm join-token worker
docker service 适合启动单个服务,对于多服务部署和管理有些无能为力
1、constraint参数
标明使用指定docker服务器创建服务
--constraint 'node.role == manager'
--constraint 'node.hostname==docker129'
三、案例
1、命令启动
[root@docker dockerfile]# docker service create --replicas 3 -p 80:80 --name nginx nginx:1.13-alpine
tk1lrh6zhdgfytnivna36vlp5
overall progress: 3 out of 3 tasks
1/3: running [==================================================>]
2/3: running [==================================================>]
3/3: running [==================================================>]
verify: Service converged
[root@docker dockerfile]# docker service ls ###查看当前swarm运行的服务
ID NAME MODE REPLICAS IMAGE PORTS
tk1lrh6zhdgf nginx replicated 3/3 nginx:1.13-alpine *:80->80/tcp
[root@docker dockerfile]# docker service ps nginx ###查看某个服务的详情
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
u2y6570eslc2 nginx.1 nginx:1.13-alpine docker129 Running Running less than a second ago
lg0j7m4mppfh nginx.2 nginx:1.13-alpine docker130 Running Running less than a second ago
suq5u9c7805t nginx.3 nginx:1.13-alpine docker Running Running about a minute ago
docker service logs nginx ##查看服务日志
docker service logs -f nginx ##实时观察日志
扩容
[root@docker ~]# docker service scale nginx=5
nginx scaled to 5
overall progress: 5 out of 5 tasks
1/5: running [==================================================>]
2/5: running [==================================================>]
3/5: running [==================================================>]
4/5: running [==================================================>]
5/5: running [==================================================>]
verify: Service converged
[root@docker ~]# docker service ps nginx
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
u2y6570eslc2 nginx.1 nginx:1.13-alpine docker129 Running Running less than a second ago
lg0j7m4mppfh nginx.2 nginx:1.13-alpine docker130 Running Running less than a second ago
suq5u9c7805t nginx.3 nginx:1.13-alpine docker Running Running 10 minutes ago
t358dy73zyz2 nginx.4 nginx:1.13-alpine docker Running Running 23 seconds ago
ujheltlnjmuw nginx.5 nginx:1.13-alpine docker130 Running Running less than a second ago
缩容
[root@docker ~]# docker service scale nginx=2
nginx scaled to 2
overall progress: 2 out of 2 tasks
1/2: running [==================================================>]
2/2: running [==================================================>]
verify: Service converged
[root@docker ~]# docker service ps nginx
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
u2y6570eslc2 nginx.1 nginx:1.13-alpine docker129 Running Running less than a second ago
lg0j7m4mppfh nginx.2 nginx:1.13-alpine docker130 Running Running less than a second ago
删除服务
[root@docker ~]# docker service rm nginx
nginx
四、docker stack
1、概述
Docker Stack 为解决该问题而生,Docker Stack 通过提供期望状态、滚动升级、简单易用、扩缩容、健康检查等特性简化了应用的管理,这些功能都封装在一个完美的声明式模型当中。
幸运的是,Stack 正为此而生!Stack 能够在单个声明文件中定义复杂的多服务应用。Stack 还提供了简单的方式来部署应用并管理其完整的生命周期:初始化部署 -> 健康检查 -> 扩容 -> 更新 -> 回滚,以及其他功能!
步骤很简单。在 Compose 文件中定义应用,然后通过 docker stack deploy 命令完成部署和管理。
Compose 文件中包含了构成应用所需的完整服务栈。此外还包括了卷、网络、安全以及应用所需的其他基础架构。然后基于该文件使用 docker stack deploy 命令来部署应用。
Stack 是基于 Docker Swarm 之上来完成应用的部署。因此诸如安全等高级特性,其实都是来自 Swarm。
简而言之,Docker 适用于开发和测试。Docker Stack 则适用于大规模场景和生产环境。
2、compose文件
(1.deploy参数
endpoint_mode
为连接到一个群的外部客户端指定一个服务发现方法
endpoint_mode: vip -docker 为服务分配一个虚拟 ip (vip) ,作为客户端到达网络上服务的前端。Docker 在客户端和服务的可用工作节点之间传递请求,而客户端不知道有多少节点参与服务,也不知道它们的 ip 地址或端口。(这是默认的。)
endpoint_mode: dnsrr - 服务发现不使用单个虚拟 ip。Docker 为服务设置 dns 条目,以便对服务名称的 dns 查询返回一个 ip 地址列表,客户机直接连接到其中一个。Dns round-robin 在需要使用自己的负载均衡器或混合 windows 和 linux 应用程序的情况下非常有用
version: "3.9"
services:
wordpress:
image: wordpress
ports:
- "8080:80"
networks:
- overlay
deploy:
mode: replicated
replicas: 2
endpoint_mode: vip
mysql:
image: mysql
volumes:
- db-data:/var/lib/mysql/data
networks:
- overlay
deploy:
mode: replicated
replicas: 2
endpoint_mode: dnsrr
volumes:
db-data:
networks:
overlay:
labels
为服务指定标签。这些标签只在服务上设置,而不在服务的任何容器上。
version: "3.9"services:
web:
image: web
deploy:
labels:
com.example.description: "This label will appear on the web service"
要在容器上设置标签,请在 deploy 之外使用标签键:
version: "3.9"services:
web:
image: web
labels:
com.example.description: "This label will appear on all containers for the web service"
mode
要么是全局的(每个群集节点只有一个容器),要么是复制的(指定数量的容器)。默认是复制的。(了解更多信息,请查看 swarm 主题中的replicated和global services)
version: "3.9"services:
worker:
image: dockersamples/examplevotingapp_worker
deploy:
mode: global
placement
指定约束和首选项的位置。请参阅 docker 服务创建文档,了解语法和约束、首选项的可用类型的完整描述,并指定每个节点的最大副本
version: "3.9"services:
db:
image: postgres
deploy:
placement:
constraints:
- "node.role==manager"
- "engine.labels.operatingsystem==ubuntu 18.04"
preferences:
- spread: node.
max_replicas_per_node
如果服务设置了副本数(这是默认值),限制任何时候在一个节点上运行的副本数量。当请求的任务比运行的节点多时,不会引发合适的节点错误(每个节点的最大副本限制超过)。
version: "3.9"services:
worker:
image: dockersamples/examplevotingapp_worker
networks:
- frontend
- backend
deploy:
mode: replicated
replicas: 6
placement:
max_replicas_per_node: 1
replicas
如果服务设置了副本数(这是默认值),则指定在任何给定时间应该运行的容器数量。
version: "3.9"services:
worker:
image: dockersamples/examplevotingapp_worker
networks:
- frontend
- backend
deploy:
mode: replicated
replicas: 6
resources
配置资源约束
(cpu_shares, cpu_quota, cpuset, mem_limit, memswap_limit, mem_swappiness).
redis 服务被限制使用不超过50m 的内存和0.50(单核的50%)的可用处理时间(cpu) ,并且有20m 的内存和0.25的 cpu 时间(总是可用)。
version: "3.9"services:
redis:
image: redis:alpine
deploy:
resources:
limits: ##最大值
cpus: '0.50'
memory: 50M
reservations: ##初始值
cpus: '0.25'
memory: 20M
restart_policy
配置如何在容器退出时重新启动容器
condition: 定义什么时机进行重启,One of none,on-failure是在运行失败时进行重启或者any(默认any)
delay: 发生错误后多长时间执行重启,指定为持续时间(默认值: 5秒)。
max_attempts: 在放弃之前尝试重新启动容器的次数(默认值: 永远不要放弃)。如果重新启动在配置的窗口内不成功,则此尝试不计入配置的 max_attempts 值。例如,如果 max _ attempts 设置为‘2’,并且第一次尝试重启失败,则可能会尝试两次以上的重启。
window: 设置重启的超时时间,指定为持续时间(默认值: 立即决定)。
version: "3.9"services:
redis:
image: redis:alpine
deploy:
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s
rollback_config
配置在更新失败的情况下应该如何回滚服务。
parallelism: 每次回滚的容器数量。如果设置为0,所有容器同时回滚。
delay: 每个容器组回滚之间的等待时间(默认值为0)
failure_action:如果回滚失败,应该怎么做。一个 continue 或 pause (default pause)
monitor: 每次任务更新后监视故障后的持续时间(ns | us | ms | s | m | h)(缺省值5s)注意: 设置为0将使用缺省值5s。
max_failure_ratio: 回滚期间容忍的故障率(默认值为0)。
order: 回滚期间的操作顺序。stop-first(在启动新任务之前停止旧任务)或start-first(先启动新任务,然后运行任务短暂重叠)之一(默认stop-first)。
update_config
配置如何更新服务,对于配置滚动更新很有用
parallelism: 每次更新的容器数量
delay: 更新一组容器之间的等待时间
failure_action:如果更新失败了怎么办。选择 continue、 rollback 或 pause (默认值: pause)
monitor: 每个容器更新后,持续观察是否失败了的时间(ns | us | ms | s | m | h)(缺省值5s)注意: 设置为0将使用缺省值5s
max_failure_ratio: 更新过程中容忍的故障率
order: 更新期间的操作顺序。Stop-first (在启动新任务之前停止旧任务)或 start-first (先启动新任务,然后运行任务短暂重叠)(默认 stop-first) 注意:只支持 v3.4版本和更高版本的文件格式。
docker stack deploy不支持以下子选项(支持 docker-compose up 和 docker-compose run)。
build
cgroup_parent
container_name
devices
tmpfs
external_links
links
network_mode
restart
security_opt
userns_mode
(2.案例
[root@docker dockerfile]# cat docker-compose.yml
version: "3"
services:
wordpress:
depends_on:
- db
image: wordpress:latest
ports:
- "80:80"
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
deploy:
mode: replicated
replicas: 3
healthcheck:
test: ["CMD", "wget", "-qO", "-", "http://localhost"]
interval: 2s
timeout: 2s
retries: 3
start_period: 2s
networks:
- overlay
db:
image: mysql:8.0.18
command:
- --default_authentication_plugin=mysql_native_password
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci
volumes:
- db-data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: root123
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
deploy:
placement:
constraints: [node.role == manager]
networks:
- overlay
volumes:
db-data:
networks:
overlay:
docker stack deploy -c docker-compose.yml wordpress ##启动服务
[root@docker dockerfile]# docker stack ls
NAME SERVICES ORCHESTRATOR
wordpress 2 Swarm
[root@docker dockerfile]# docker stack ps wordpress
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
o4vk5y1hkoyb wordpress_db.1 mysql:8.0.18 docker Running Running 2 minutes ago
eo8sjhp0kaq8 wordpress_wordpress.1 wordpress:latest docker130 Running Running less than a second ago
p8g8ib4o1ytd wordpress_wordpress.2 wordpress:latest docker129 Running Running less than a second ago
i0vas0rj42y2 wordpress_wordpress.3 wordpress:latest docker Running Running 2 minutes ago
移除服务,但是不会移除数据卷
[root@docker dockerfile]# docker stack down wordpress
Removing service wordpress_db
Removing service wordpress_wordpress
Removing network wordpress_default
Removing network wordpress_overlay
移除数据卷
docker volume prune
3、更新与回滚
(1.配置重启策略
[root@docker dockerfile]# cat docker-compose.yml
version: "3"
services:
web:
image: nginx:1.13-alpine
ports:
- "80:80"
networks:
- overlay
deploy:
mode: replicated
replicas: 7
restart_policy: ##重启设置
condition: on-failure ##发生错误多长时间执行重启
delay: 10s ##发生错误多长时间执行重启
max_attempts: 3 ##在放弃之前尝试重新启动容器的次数
window: 120s ##设置重启的超时时间
networks:
overlay:
docker stack deploy web -c docker-compose.yml ###启动服务
[root@docker dockerfile]# docker stack ps web ##查看服务
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
5dgj8ctndj2r web_web.1 nginx:1.13-alpine docker129 Running Running less than a second ago
isstrurfahh8 web_web.2 nginx:1.13-alpine docker130 Running Running less than a second ago
l77dvnhwyfqg web_web.3 nginx:1.13-alpine docker Running Running 13 seconds ago
l8zefqpmjfuq web_web.4 nginx:1.13-alpine docker129 Running Running less than a second ago
esu0o19z7dh2 web_web.5 nginx:1.13-alpine docker130 Running Running less than a second ago
u4jjakbn9ddo web_web.6 nginx:1.13-alpine docker130 Running Running less than a second ago
onfupyxseaim web_web.7 nginx:1.13-alpine docker Running Running 13 seconds ago
去docker130停掉一个服务
docker rm -f b194292a61fc
再次查看,又拉起来一个新服务
[root@docker dockerfile]# docker stack ps web
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
5dgj8ctndj2r web_web.1 nginx:1.13-alpine docker129 Running Running less than a second ago
isstrurfahh8 web_web.2 nginx:1.13-alpine docker130 Running Running less than a second ago
l77dvnhwyfqg web_web.3 nginx:1.13-alpine docker Running Running about a minute ago
l8zefqpmjfuq web_web.4 nginx:1.13-alpine docker129 Running Running less than a second ago
7uu0pzdl8a2l web_web.5 nginx:1.13-alpine docker129 Running Running less than a second ago
esu0o19z7dh2 \_ web_web.5 nginx:1.13-alpine docker130 Shutdown Failed less than a second ago "task: non-zero exit (137)"
u4jjakbn9ddo web_web.6 nginx:1.13-alpine docker130 Running Running less than a second ago
onfupyxseaim web_web.7 nginx:1.13-alpine docker Running Running about a minute ago
(2.配置更新策略
#####################配置更新策略
[root@docker dockerfile]# cat docker-compose.yml
version: "3"
services:
web:
image: nginx:aaaa ###将镜像设置为不存在的
ports:
- "80:80"
networks:
- overlay
deploy:
mode: replicated
replicas: 7
restart_policy: ##重启设置
condition: on-failure ##发生错误多长时间执行重启
delay: 10s ##发生错误多长时间执行重启
max_attempts: 3 ##在放弃之前尝试重新启动容器的次数
window: 120s ##设置重启的超时时间
update_config:
parallelism: 2 ##每次更新容器数量
delay: 10s ##更新一组容器之间的等待时间
failure_action: pause ##如果更新失败了怎么办,选择 continue、 rollback 或 pause (默认值: pause)
monitor: 500ms ###每个容器更新后,持续观察是否失败了的时间
max_failure_ratio: 0.5 ##在更新过程中可以容忍的故障率
networks:
overlay:
[root@docker dockerfile]# docker stack deploy web -c docker-compose.yml
Updating service web_web (id: nn7h04x63xawy31q493vycqr0)
image nginx:aaaa could not be accessed on a registry to record
its digest. Each node will access nginx:aaaa independently,
possibly leading to different nodes running different
versions of the image.
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
5dgj8ctndj2r web_web.1 nginx:1.13-alpine docker129 Running Running less than a second ago
ao5jgfl0wn13 web_web.2 nginx:aaaa docker130 Running Preparing less than a second ago
3wr8sucy0egl \_ web_web.2 nginx:aaaa docker130 Shutdown Rejected less than a second ago "No such image: nginx:aaaa"
jcbzpof4ziay \_ web_web.2 nginx:aaaa docker Shutdown Rejected about a minute ago "No such image: nginx:aaaa"
o9zi6b5rqqof \_ web_web.2 nginx:aaaa docker129 Shutdown Rejected less than a second ago "No such image: nginx:aaaa"
ru9ocdls07yz web_web.3 nginx:aaaa docker130 Running Preparing less than a second ago
zet2s6ow3ny2 \_ web_web.3 nginx:aaaa docker129 Shutdown Rejected less than a second ago "No such image: nginx:aaaa"
djaupgwafma6 \_ web_web.3 nginx:aaaa docker129 Shutdown Rejected less than a second ago "No such image: nginx:aaaa"
kgm1cgwhy3xj \_ web_web.3 nginx:aaaa docker129 Shutdown Rejected less than a second ago "No such image: nginx:aaaa"
srp5pgrepfjl web_web.4 nginx:aaaa docker Running Preparing 2 minutes ago
qpn29q5kraq9 \_ web_web.4 nginx:aaaa docker Shutdown Rejected 2 minutes ago "No such image: nginx:aaaa"
z1ijpp19sssc \_ web_web.4 nginx:aaaa docker Shutdown Rejected 3 minutes ago "No such image: nginx:aaaa"
041am3c4u935 \_ web_web.4 nginx:aaaa docker Shutdown Rejected 4 minutes ago "No such image: nginx:aaaa"
1pvdmbk72w7o web_web.5 nginx:aaaa docker130 Running Preparing less than a second ago
bf41j6hweqj9 \_ web_web.5 nginx:aaaa docker130 Shutdown Rejected less than a second ago "No such image: nginx:aaaa"
sedp15e3o3p9 \_ web_web.5 nginx:aaaa docker Shutdown Rejected about a minute ago "No such image: nginx:aaaa"
lxdnbvnonk90 \_ web_web.5 nginx:aaaa docker Shutdown Rejected 2 minutes ago "No such image: nginx:aaaa"
u4jjakbn9ddo web_web.6 nginx:1.13-alpine docker130 Running Running less than a second ago
onfupyxseaim web_web.7 nginx:1.13-alpine docker Running Running 24 minutes ago
###有两组容器受到了影响,failure_action设置为pause应该是更新失败立刻就停止的,可能是delay: 10s设置时间太短引起的
###更新的时候是随机到一台服务器的
########清理掉服务:docker stack down web
(3.配置回滚策略
[root@docker dockerfile]# cat docker-compose.yml
version: "3.9" ##这个能写具体就具体点,之前3,启动服务直接报不支持rollback_config
services:
web:
image: nginx:latest
ports:
- "80:80"
networks:
- overlay
deploy:
mode: replicated
replicas: 7
restart_policy: ##重启设置
condition: on-failure ##发生错误多长时间执行重启
delay: 10s ##发生错误多长时间执行重启
max_attempts: 3 ##在放弃之前尝试重新启动容器的次数
window: 120s ##设置重启的超时时间
update_config:
parallelism: 2 ##每次更新容器数量
delay: 10s ##更新一组容器之间的等待时间
failure_action: rollback ##如果更新失败了怎么办,选择 continue、 rollback 或 pause (默认值: pause)
monitor: 500ms ###每个容器更新后,持续观察是否失败了的时间
max_failure_ratio: 0.5 ##在更新过程中可以容忍的故障率
rollback_config:
parallelism: 1 ##每次回滚的容器数量。如果设置为0,所有容器同时回滚。
delay: 0s ##每个容器组回滚之间的等待时间(默认值为0)
monitor: 500ms ##每次任务更新后监视故障后的持续时间
networks:
overlay:
docker stack deploy web -c docker-compose.yml ##启动服务
将docker-compose.yml中nginx镜像改为nginx:aaaa
docker stack deploy web -c docker-compose.yml ##启动服务
mkqelwr9sklm web_web.1 nginx:latest docker130 Running Running less than a second ago
8kq3faqemvwx \_ web_web.1 nginx:aaaa docker130 Shutdown Shutdown less than a second ago
vjw7mgm6whv7 \_ web_web.1 nginx:aaaa docker129 Shutdown Rejected less than a second ago "No such image: nginx:aaaa"
v8idz9logsp2 \_ web_web.1 nginx:latest docker Shutdown Shutdown about a minute ago
k0nrak6izq16 web_web.2 nginx:latest docker129 Running Running less than a second ago
xjr1w57b2o8o web_web.3 nginx:latest docker129 Running Running less than a second ago
7gihi47tcth7 \_ web_web.3 nginx:aaaa docker129 Shutdown Shutdown less than a second ago
l5izw67ks37s \_ web_web.3 nginx:aaaa docker129 Shutdown Rejected less than a second ago "No such image: nginx:aaaa"
vrrsfzlevmtb \_ web_web.3 nginx:aaaa docker129 Shutdown Rejected less than a second ago "No such image: nginx:aaaa"
8ng5lzc8vdos web_web.4 nginx:latest docker Running Running 28 seconds ago
vql56te7z1ro \_ web_web.4 nginx:aaaa docker130 Shutdown Shutdown less than a second ago
oqui2zhqfnmo \_ web_web.4 nginx:aaaa docker130 Shutdown Rejected less than a second ago "No such image: nginx:aaaa"
t8ze552h7fg7 \_ web_web.4 nginx:latest docker130 Shutdown Shutdown less than a second ago
ppir7ccgd9f0 web_web.5 nginx:latest docker Running Running 20 seconds ago
48exbywyl02j \_ web_web.5 nginx:aaaa docker Shutdown Shutdown 21 seconds ago
vufsdxf01j5x \_ web_web.5 nginx:latest docker Shutdown Shutdown 39 seconds ago
ijsufbuc3ncm web_web.6 nginx:latest docker129 Running Running less than a second ago
rfnxf2i6dvuc \_ web_web.6 nginx:aaaa docker Shutdown Shutdown 25 seconds ago
nc188djymo47 \_ web_web.6 nginx:aaaa docker Shutdown Rejected 51 seconds ago "No such image: nginx:aaaa"
16n5zqibfb1x \_ web_web.6 nginx:aaaa docker129 Shutdown Rejected less than a second ago "No such image: nginx:aaaa"
kwdbnwlyrj6v web_web.7 nginx:latest docker130 Running Running less than a second ago
##过程有点漫长,但是最后还是都回滚回去了
4、健康检测
version: "3.9"
services:
web:
image: nginx:1.13-alpine
ports:
- "80:80"
networks:
- overlay
deploy:
mode: replicated
replicas: 7
restart_policy: ##重启设置
condition: on-failure ##在运行失败的时候
delay: 10s ##发生错误多长时间执行重启
max_attempts: 3 ##在放弃之前尝试重新启动容器的次数(默认值: 永远不要放弃)
window: 120s ##设置重启的超时时间
update_config:
parallelism: 2 ##每次更新容器数量
delay: 10s ##更新一组容器之间的等待时间
failure_action: pause ##如果更新失败了怎么办,选择 continue、 rollback 或 pause (默认值: pause)
monitor: 500ms ###每个容器更新后,持续观察是否失败了的时间
max_failure_ratio: 0.5 ##在更新过程中可以容忍的故障率
rollback_config:
parallelism: 1 ##每次回滚的容器数量。如果设置为0,所有容器同时回滚。
delay: 0s ##每个容器组回滚之间的等待时间(默认值为0)
monitor: 500ms ##每次任务更新后监视故障后的持续时间
healthcheck:
test: ["CMD", "wget", "-qO", "-", "http://localhost"] ##定义检测的命令
interval: 2s #命令执行间隔,默认30秒
timeout: 2s #命令超时时间,默认30秒
retries: 3 #命令失败重试次数
start_period: 2s #启动延时,即容器启动后多久开始执行检测
networks:
overlay: