容器编排服务变更策略调研

容器编排服务变更策略调研

本文调研目前流行的三款容器编排平台的服务变更策略,包括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 UnavailableMax 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: 回滚的并发度

Docker Service

Nomad

Nomad是Hashicorp设计的一款容器编排系统,它拥有服务变更策略多种多样,包括了:

  • Rolling Upgrades: 滚动升级
  • Blue/Green & Canary Deployments: 蓝/绿 & Cannary 部署
  • Handling Signals: 信号处理方式

下面分别简单的介绍一下这几种服务变更策略。

RollingUpdate

RollingUpdate是滚动变更的意思,它是nomad第一个支持的服务变更策略,为了在jobtask中使用这种服务变更策略,需要在更新策略中使用update这个配置,也叫update stanza类似如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
job "geo-api-server" {
...
group "api-server" {
...
# Add an update stanza to enable rolling updates of the service
update {
max_parallel = 2
min_healthy_time = "30s"
healthy_deadline = "10m"
}
...
}
}

在这个例子中通过增加update stanzaapi-server这个任务组增加了服务变更策略,当api-server这个任务组需要更新时,会首先创建2个新版本的实例,并且要求新版本的实例要保持Health状态30秒,才可以继续进行服务变更。

也就是说nomadRollingUpdate的服务更新策略与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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
job "docs" {
...
group "api" {
count = 5

update {
max_parallel = 1
canary = 5
min_healthy_time = "30s"
healthy_deadline = "10m"
auto_revert = true
}
...
}
}

在升级时,会创建5个新版本的实例(canary部分),通过查看部署信息:

1
2
3
4
Latest Deployment
ID = 32a080c1
Status = running
Description = Deployment is running but requires promotion

如果本次的升级没有异常时,可以进行主体服务的升级,将旧版本的服务下掉

1
2
# 将旧版本的5个实例下掉
nomad deployment promote 32a080c1

如果升级出现异常,可以回滚上个版本

1
nomad deployment fail 32a080c1

这样新版本的5个实例会被下掉,本次上线服务主体不受影响。

Handling Signals

现代操作系统支持信号机制,nomad在杀掉一个应用之前,会给这个应用发送一个信号,这个信号是可以配置的,这种方式允许一些应用当被nomad杀掉的时候,有机会进行优雅的退出、销毁资源操作等等。同时nomad允许指定一个时间,在杀死该应用时,等待用户程序的退出。

nomad终结一个进程时,会给该进程发送SIGINT信号,在nomad下的进程应该响应这个信号,以优雅的退出,如果超过配置的时间内还没有处理该信号,那么这个进程会被强制杀掉。