容器编排服务变更策略调研
本文调研目前流行的三款容器编排平台的服务变更策略,包括kubernetes、swarm、nomad。
其中它们的版本信息如下:
平台|版本
kubernetes|v1.8
swarm|v1.2.8
nomad|v0.6.3
下面分别介绍一下这些平台的服务变更策略。
kubernetes
在Kubernetes中,是由deployment
控制器来控制服务变更的过程,它目前提供了两种服务变更策略,分别是:
- Recreate
- RollingUpdate
下面分别介绍一下这两种服务变更策略。
Recreate
Recreate这种服务变更策略非常简单粗暴,要把deployment
关联的现存Pod全部杀掉之后,才能进行升级。
RollingUpdate
RollingUpdate
是滚动更新的意思,可以通过这种策略来精确的控制服务变更的过程。在deployment
中有两个字段是与服务变更的过程有关,分别是Max Unavailable
和Max Surge
,下面分别介绍一下这两个字段的含义。
Max Unavailable
.spec.strategy.rollingUpdate.maxUnavailable
是一个可选的字段,用来表明在升级过程中Pod的最大不可用数目,如果超过这个数目的话,deployment
便不会销毁旧的实例,停止更新的过程。
这个值可以是一个绝对数值,也可以是一个百分比,默认值是25%
。有一点需要注意的是,当.spec.strategy.rollingUpdate.maxSurge
为0时,.spec.strategy.rollingUpdate.maxUnavailable
不能为0。
举个例子当该值设置成30%
时,deployment
会立马将旧的ReplicaSet缩减为原来的70%
,然后新建新的ReplicaSet,当新的ReplicaSet已经ready之后才能继续完成升级操作。
Max Surge
.spec.strategy.rollingUpdate.maxSurge
是一个可选字段,它表明了可以创建超过期望Pod个数的最大数目,它可以是一个绝对值,也可以是一个百分比形式。它的值和.spec.strategy.rollingUpdate.maxUnavailable
不能同时为0。
举个例子,当这个值设置成30%
时,当滚动更新开始时,新的ReplicaSet可以立马开始扩容,但是要保证新的ReplicaSet和旧的ReplicaSet的Pod数目不能超过Pod期望数目的130%
。
小结
比如deployment
的定义如下:
- .spec.replicas: 10
- .spec.strategy.rollingUpdate.maxSurge: 30%
- .spec.strategy.rollingUpdate.maxUnavailable: 30%
那么在更新过程中,旧的ReplicaSet会缩容到70%
,也就是7个Pod,新的ReplicaSet会扩容到6个Pod,要同时保证不可用的数目在30%
以下,总的Pod数目在130%
以下,当新的ReplicaSet有Pod启动好了,那么会继续缩容旧的ReplicaSet。
kubernetes Deployment
swarm
swarm是docker官方推出的一款容器编排管理工具,它通过docker service的形式来管理容器实例的变更过程。在创建docker service前,必须先初始化swarm集群,比如创建一个http服务:
1 | # docker swarm init && docker service create --name http --replicas 2 -p 80:80 katacoda/docker-http-server:v1 |
可以通过docker service的方式来滚动更新和弹性扩展服务。涉及到服务的更新过程是通过docker service update来实现的,它有以下字段控制着实例的变更过程。
--update-parallelism
: 确保实例更新的并发度--update-delay
: 设置每次更新的时间间隔--update-max-failure-ratio
: 更新时允许失败的容器数目比--update-failure-action
: 更新失败时的动作 [pause,continue,rollback]--update-monitor
: 监控容器更新失败的时间--rollback
: 回滚前一个版本--rollback-delay
: 每次回滚操作之间的时间间隔--rollback-failure-action
: 当回滚失败时的动作 [pause,continue]--rollback-max-failure-ratio
: 回滚失败允许失败的容器数目比--rollback-parallelism
: 回滚的并发度
Nomad
Nomad
是Hashicorp设计的一款容器编排系统,它拥有服务变更策略多种多样,包括了:
Rolling Upgrades
: 滚动升级Blue/Green & Canary Deployments
: 蓝/绿 & Cannary 部署Handling Signals
: 信号处理方式
下面分别简单的介绍一下这几种服务变更策略。
RollingUpdate
RollingUpdate
是滚动变更的意思,它是nomad
第一个支持的服务变更策略,为了在job
和task
中使用这种服务变更策略,需要在更新策略中使用update
这个配置,也叫update stanza类似如下:
1 | job "geo-api-server" { |
在这个例子中通过增加update stanza
为api-server
这个任务组增加了服务变更策略,当api-server
这个任务组需要更新时,会首先创建2个新版本的实例,并且要求新版本的实例要保持Health状态30秒,才可以继续进行服务变更。
也就是说nomad
的RollingUpdate
的服务更新策略与update stanza
息息相关,下面简单的介绍一下update stanza
。
update Stanza
update Stanza指明了任务组的更新策略,如果不指定的话那么服务变更时将不会出发滚动升级和Cannary
,主要一下更新参数:
max_parallel
: 指明任务组同时可以更新的数目health_check
: 指明健康检查的机制,主要有checks
(所有的实例处于运行状态,并且关联的checks状态正常时,才处于健康状态)、task_states
(仅仅检查所有task是否处于运行状态,如果是运行状态那么处于health,否则是不健康状态)、manual
(指明Nomand不能自动的检查健康,而是由操作人员通过HTTP API的方式判断健康状态)- ``
min_healthy_time
: 指明每个实例必须处于健康状态的最短持续时间。healthy_deadline
: 指明每个实例必须被标记为health状态的时间,如果还没有变成health状态,那么自动转换成不健康状态。auto_revert
: 指明当一个任务更新失败时,是否回滚到最近的一个稳定版本。canary
: 在进行job升级时,会创建指定数目的canary
实例,只有这些canary
实例是health状态,才可以开始进行服务变更过程,这个过程是通过max_parallel
来触发的。stagger
: 指明实例在node间故障迁移的时间间隔。
Blue/Green & Canary Deployments
有时候rolling upgrades
在生产环境中没有提供足够的灵活性,很多企业在生产环境更新时,会通过部署一个canary
,技术上叫做蓝绿部署,这种方式来确保服务能够稳定的变更,以减少不可用的时间。
这个是通过update stanza
中的canary
配置来实现的,假如配置如下:
1 | job "docs" { |
在升级时,会创建5个新版本的实例(canary部分),通过查看部署信息:
1 | Latest Deployment |
如果本次的升级没有异常时,可以进行主体服务的升级,将旧版本的服务下掉
1 | # 将旧版本的5个实例下掉 |
如果升级出现异常,可以回滚上个版本
1 | nomad deployment fail 32a080c1 |
这样新版本的5个实例会被下掉,本次上线服务主体不受影响。
Handling Signals
现代操作系统支持信号机制,nomad
在杀掉一个应用之前,会给这个应用发送一个信号,这个信号是可以配置的,这种方式允许一些应用当被nomad
杀掉的时候,有机会进行优雅的退出、销毁资源操作等等。同时nomad
允许指定一个时间,在杀死该应用时,等待用户程序的退出。
在nomad
终结一个进程时,会给该进程发送SIGINT
信号,在nomad
下的进程应该响应这个信号,以优雅的退出,如果超过配置的时间内还没有处理该信号,那么这个进程会被强制杀掉。