前言
微服务场景下,服务更新迭代的速度很快,应用发布的速度和成功率也有很高的要求。这样就产生了多种发布方式,下面分别介绍下每种方式的优缺点和使用场景。
滚动发布
rolling update。kubernets在应用更新的时候默认的发布方式,一次只更新一小部分副本,成功后,在更新更多的副本,最终完成所有副本的更新。
优点
- 用户无感知,不需要停机发布。
- 节约资源
缺点
- 发布/回滚时间会比较长。需要设置readnessProbe,等待pod ready,然后升级下一个。
- 没有一个整体OK的环境,一直有一个或几个pod在更新。
发布过程
- 根据maxSurge和maxUnavailable设置的值,来决定最新更新几个新副本,减少几个旧副本。
- 新副本健康检查通过后,加入到service的后端中,旧的副本从后端中移除。
- 按照更新策略,依次更新,直到全部副本更新完毕。
使用场景
适合可用性较高的生产环境
参数说明
- maxSurge:和期望ready的副本数比,超过期望副本数最大比例(或最大值),这个值调的越大,副本更新速度越快。向上取整。值默认为0,比例默认为25%。
- maxUnavailable:和期望ready的副本数比,不可用副本数最大比例(或最大值),这个值越小,服务越稳定,更新越平滑。向下取整。值默认为1,比例默认为25%。
- 两者不能同时为0。
- DESIRED: 期望ready的副本数。
- CURRENT: 当前副本数。在[replicas-maxUnavailable, replicas+maxSurge]之间变动,最终等于DESIRED值。
- UP-TO-DATE: 已更新的副本数,最终等于DESIRED值。
- AVALIABLE: 可用副本数,最终等于DESIRED值。
建议配置
- maxUnavailable == 0
- maxSurge == 1
- 即1个新版本pod ready后,才销毁旧版本pod。
滚动更新命令
# 记录版本到revision中
kubectl apply -f nginx.yaml --record
# 查看历史
kubectl rollout history deployment/nginx
# 查看具体某一个历史版本信息
kubectl rollout history deployment/nginx--revision=2
# 回滚上个版本
kubectl rollout undo deployment/nginx
# 回滚到指定版本
kubectl rollout undo deployment/nginx --to-revision=2
蓝绿发布
发布过程
- 蓝绿发布需要对服务的新版本进行冗余部署,一般新版本的机器规格和数量与旧版本保持一致,相当于该服务有两套完全相同的部署环境,只不过此时只有旧版本在对外提供服务,新版本作为热备。
- 当服务升级时,新版本测试好后,只需将流量全部切换到新版本即可,旧版本作为热备。
- 如果新版本上线后出现严重的程序BUG,那么我们只需将流量全部切回至旧版本,大大缩短故障恢复的时间。待新版本完成 BUG 修复并重新部署之后,再将旧版本的流量切换到新版本。
优点
- 无需停机
- 发布策略简单
- 升级/回滚快
缺点
- 需要2倍的服务器资源
- 新版本故障影响范围大
使用场景
资源充裕的环境。
蓝绿发布对于增量升级有比较好的支持,但是对于涉及数据表结构变更等不可逆转的升级,并不完全合适用蓝绿发布来实现,需要结合一些业务的逻辑以及数据迁移与回滚的策略才可以完全满足需求。
灰度发布(金丝雀发布)
发布过程
灰度发布只升级部分服务,从LB摘掉灰度服务器,升级成功后再加入LB。即让一部分用户继续用老版本,一部分用户开始用新版本,如果新版本符合预期,那么逐步扩大范围,把所有用户都迁移到新版本上面来。
优点
- 新版本故障影响范围小
- 发布期间逐步对新版本扩容,同时对老版本缩容,资源利用率高
- 用户无感知,平滑过渡
缺点
- 发布周期长
- 流量无差别地导向新版本,可能会影响重要用户的体验
使用场景
基本上都适合
A/B 测试
发布过程
A/B测试基于用户请求的元信息将流量路由到新版本,这是一种基于请求内容匹配的灰度发布策略。只有匹配特定规则的请求才会被引流到新版本,常见的做法包括基于Http Header 和 Cookie。
- 基于 Http Header 方式的例子,例如 User-Agent 的值为 Android的请求 (来自安卓系统的请求)可以访问新版本,其他系统仍然访问旧版本。
- 基于 Cookie 方式的例子,Cookie中通常包含具有业务语义的用户信息,例如普通用户可以访问新版本,VIP 用户仍然访问旧版本。
通过在监控平台观察旧版本与新版本的成功率、RT 对比,当新版本整体服务预期后,即可将所有请求切换到新版本,最后为了节省资源,可以逐步下线到旧版本。
优点
- 可以对特定的请求或者用户提供服务新版本,新版本故障影响范围小
缺点
- 需要构建完备的监控平台,用于对比不同版本之间请求状态的差异
- 发布周期长
- 资源需求偏多
使用场景
只针对部分特定用户升级的场景
分批次暂停发布
发布过程
在执行分批发布过程中,新旧版本同时存在,Service的流量会同时转发到新旧版本中。在应用升级完成后,旧版本会自动删除。
分批发布策略
- 分批发布第一批暂停:按批次对应用进行升级,并且在第一批次执行完成后,暂停。等待用户确认是否继续后续批次的发布,后续批次发布过程不再暂停。
- 分批发布每批暂停:按批次对应用进行升级,在每批发布执行完成后都需要用户确认是否继续下一批次的任务
注意
- 需要readnessProbe,等待pod ready,否则可能一部分应用访问请求出现异常。
- 第一次部署时不会分批次。