如果要使用 Deployment 向用户子集或服务器子集上线版本, 则可以遵循资源管理所描述的金丝雀模式, 创建多个 Deployment,每个版本一个。
所谓金丝雀发布(Canary Release),就是第一个新的 Pod 创建完成后立即暂停更新过程,这时主体部分还是旧的版本。然后再根据用户特征精心筛选出小部分用户的请求路由至新版本的应用程序,并持续观察是否满足期望。确定没问题后再继续完成剩下的滚动更新,否则立即回滚。
滚动更新 Deployment
Deployment 支持自定义控制更新过程中的滚动节奏,如“暂停”或“继续”更新操作。借助 maxSurge
和 maxUnavailable
属性还能实现更为精巧的控制过程。
Deployment 会在 .spec.strategy.type==RollingUpdate
时,采取 滚动更新的方式更新 Pod。你可以指定 maxUnavailable
和 maxSurge
来控制滚动更新 过程。
最大不可用
.spec.strategy.rollingUpdate.maxUnavailable
是一个可选字段,用来指定 更新过程中不可用的 Pod 的个数上限。该值可以是绝对数字(例如,5),也可以是所需 Pod 的百分比(例如,10%)。百分比值会转换成绝对数并去除小数部分。 如果 .spec.strategy.rollingUpdate.maxSurge
为 0,则此值不能为 0。 默认值为 25%。
例如,当此值设置为 30% 时,滚动更新开始时会立即将旧 ReplicaSet 缩容到期望 Pod 个数的70%。 新 Pod 准备就绪后,可以继续缩容旧有的 ReplicaSet,然后对新的 ReplicaSet 扩容, 确保在更新期间可用的 Pod 总数在任何时候都至少为所需的 Pod 个数的 70%。
最大峰值
.spec.strategy.rollingUpdate.maxSurge
是一个可选字段,用来指定可以创建的超出期望 Pod 个数的 Pod 数量。此值可以是绝对数(例如,5)或所需 Pod 的百分比(例如,10%)。 如果 MaxUnavailable
为 0,则此值不能为 0。百分比值会通过向上取整转换为绝对数。 此字段的默认值为 25%。
例如,当此值为 30% 时,启动滚动更新后,会立即对新的 ReplicaSet 扩容,同时保证新旧 Pod 的总数不超过所需 Pod 总数的 130%。一旦旧 Pod 被杀死,新的 ReplicaSet 可以进一步扩容, 同时确保更新期间的任何时候运行中的 Pod 总数最多为所需 Pod 总数的 130%。
进度期限秒数
.spec.progressDeadlineSeconds
是一个可选字段,用于指定系统在报告 Deployment 进展失败 之前等待 Deployment 取得进展的秒数。 这类报告会在资源状态中体现为 type: Progressing
、status: False
、 reason: ProgressDeadlineExceeded
。Deployment 控制器将在默认 600 毫秒内持续重试 Deployment。 将来,一旦实现了自动回滚,Deployment 控制器将在探测到这样的条件时立即回滚 Deployment。
如果指定,则此字段值需要大于 .spec.minReadySeconds
取值。
实际操作
通常情况下, 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
关于更多属性请参考官网:
K8S deployemnt金丝雀部署网页地址