Kubernetes 实现金丝雀发布
Deployment 支持自定义控制更新过程中的滚动节奏,如“暂停”或“继续”更新操作。借助 maxSurge
和 maxUnavailable
属性还能实现更为精巧的控制过程。
- spec.strategy.rollingUpdate.maxSurge:指定更新期间存在的总 Pod 副本数最多可超出期望值
spec.replicas
的个数,默认是 1,也可以是 0 或其他正整数。 - spec.strategy.rollingUpdate.maxUnavailable:升级期间不可用的 Pod 副本数,默认是 1,也可以是 0 或其他正整数。
所谓金丝雀发布(Canary Release),就是第一个新的 Pod 创建完成后立即暂停更新过程,这时主体部分还是旧的版本。然后再根据用户特征精心筛选出小部分用户的请求路由至新版本的应用程序,并持续观察是否满足期望。确定没问题后再继续完成剩下的滚动更新,否则立即回滚。
通常的 Deployment 滚动更新删除一个 v1 Pod 创建一个 v2 Pod 是因为 Deployment maxSurge
和 maxUnavailable
属性都默认为 1,金丝雀发布中要实现先创建再删除且可用 Pod 总数不低于期望值。这里先创建的 Pod 副本数量取决于其负载能力。将 maxUnavailable
设置为 0:
$ kubectl patch deployments my-app-deployment \
-p '{"spec": {"strategy": {"rollingUpdate": {"maxSurge": 1, "maxUnavailable": 0}}}}'
开始 Deployment 控制器的更新过程,在修改相应容器的镜像版本后立即暂停更新。这里可以通过设置 maxReadySeconds
属性(新的 Pod 对象创建后至少等待多久才就绪)来为暂停更新预留操作时间,也可以一次在 Shell 中执行两条命令:
$ kubectl set image deployments my-app-deployment myapp=path/to/image:new \
&& kubectl rollout pause deployments my-app-deployment
查看状态,创建完一个新版本的 Pod 资源后滚动更新处于暂停状态:
$ kubectl rollout status deployments my-app-deployment
而后通过 Service 或 Ingress 资源及相关路由策略等设定,将一小部分用户流量引导至新的 Pod 进行发布验证。一段时间后确认没有问题,再恢复滚动更新:
$ kubectl rollout resume deoloyments my-app-deployment
如果“金丝雀”遇险,这时候需要恢复滚动更新并立即回滚:
$ kubectl rollout resume deoloyments my-app-deployment \
&& kubectl rollout undo deoloyments my-app-deployment
回滚完成后验证 Deployment 管理的 ReplicaSet 控制器对象是否已恢复到指定的历史版本以确保回滚正常。在 kubectl rollout undo
后跟上 --to-revision=N
选项指定历史版本序号即可回滚至历史特定版本。
$ kubectl rollout history deployments my-app-deployment
$ kubectl rollout undo deployments my-app-deployment --to-revision=3