Deployment 是 Kubernetes 控制器的一种高级别实现,它构建于 ReplicaSet 控制器之上,它可用于为 Pod 和 ReplicaSet 资源提供声明式更新,并能够以自动方式实现跨多个 ReplicaSet 对象的滚动更新功能。相比较来说,Pod 和 ReplicaSet 是较低级别的资源,以至于很少被直接使用。


Deployment 控制器资源的主要职责同样是为了保证 Pod 资源健康运行,其大部分功能通过调用 ReplicaSet 控制器实现,并增添了部分特性。

事件和状态查看:必要时可以查看 Deployment 对象的更新进度和状态。

版本记录:将 Deployment 对象的更新操作予以保存,以便后续可能执行的回滚操作使用。

回滚:更新操作启动后的任一时刻(包括完成后)发现问题,都可以通过回滚机制将应用返回到前一个或由用户指定的历史记录中的版本。

暂停和启动:更新过程中能够随时暂停和继续完成后面的步骤。

多种更新方案:一是 Recreate,即重建更新机制,单批次更新所有 Pod 对象;另一个是 RollingUpdate,即滚动更新机制,多批次逐步替换旧有的 Pod 至新的版本。


Deployment 控制器支持滚动更新(rolling updates)和重新创建(recreate)两种更新策略,默认使用滚动更新策略。重建式更新类同 ReplicaSet 的第一种更新方式,即先删除现存的 Pod 对象,而后由控制器基于新模板重新创建出新版本资源对象。通常,只有当应用的新旧版本不兼容(例如依赖的后端数据库的格式不同且无法兼容)时才会使用 recreate 策略。但重建策略会导致应用在更新期间不可用,建议用户使用蓝绿部署的方式进行,除非系统资源不足以支撑蓝绿部署的实现


Deployment 控制器的滚动更新操作并非在同一个 ReplicaSet 控制器对象下删除并创建 Pod 资源,而是将它们分置于两个不同的控制器之下,当前 ReplicaSet 对象的 Pod 副本数量不断减少的同时,新 ReplicaSet 对象的 Pod 对象数量不断增加,直到现有 ReplicaSet 对象的 Pod 副本数为 0,而新控制器的副本数量变得完全符合期望值,新旧版本之间区别彼此 Pod 对象的关键标签为 pod-template-hash。


spec.strategy.rollingUpdate.maxSurge:指定升级期间存在的总 Pod 对象数量最多可超出期望值的个数,其值可以是 0 或正整数,也可以是相对于期望值的一个百分比;例如,如果期望值为 10,maxSurge 属性值为 2,则表示 Pod 对象总数至多不能超过 12 个。


spec.strategy.rollingUpdate.maxUnavailable:升级期间正常可用的 Pod 副本数(包括新旧版本)最多不能低于期望值的个数,其值可以是 0 或正整数,也可以是相对于期望值的一个百分比;默认值为 1,这意味着如果期望值是 10,则升级期间至少要有 9 个 Pod 对象处于正常提供服务的状态。


可组合定义出 3 种不同的策略完成多批次的应用更新。

先增新,后减旧:将 maxSurge 设定为小于等于期望值的正整数或相对于期望值的一个百分比,而 maxUnavailable 的值为 0。


先减旧,后增新:将 maxUnavailable 设定为小于等于期望值的正整数或相对于期望值的一个百分比,而 maxSurge 的值为 0。


同时增减(少减多增):将 maxSurge 和 maxUnavailabe 字段的值同时设定为小于等于期望值的正整数或相对于期望值的一个百分比,二者可以使用不同值。


maxSurge 和 maxUnavailable 属性的值不可同时为 0,否则 Pod 对象的副本数量在符合用户期望的数量后无法做出合理变动以进行滚动更新操作


Deployment 还支持使用 spec.minReadySeconds 字段来控制滚动更新的速度,其默认值为 0,表示新建的 Pod 对象一旦“就绪”将立即被视作可用,随后即可开始下一轮更新过程。而为该字段指定一个正整数值能够定义新建的 Pod 对象至少要成功运行多久才会被视作可用,即就绪之后还要等待 minReadySeconds 指定的时长才能开始下一批次的更新。


为了保存升级历史,需要在创建 Deployment 对象时为命令使用--record 选项。


修改 Deployment 控制器的 minReadySeconds、replicas 和 strategy 等字段的值并不会触发 Pod 资源的更新操作,因为它们不属于 template 的内嵌字段,对现存的 Pod 对象不产生任何影响


滚动更新时,deployment-demo 会创建一个新的 ReplicaSet 控制器对象来管控新版本的 Pod 对象,升级完成后,旧版本的 ReplicaSet 会保留在历史记录中,但它的 Pod 副本数被降为 0


在 kubectl rollout undo 命令上使用--to-revision 选项指定 revision 号码还可回滚到历史记录中的特定版本。需要注意的是,如果此前的滚动更新过程处于“暂停”状态,回滚操作就需要先将 Pod 模板的版本改回之前,然后“继续”更新,否则,其将一直处于暂停状态而无法回滚。


在第一批新的 Pod 资源创建完成后立即暂停更新过程,此时,仅有一小部分新版本的应用存在,主体部分还是旧的版本。然后,通过应用层路由机制根据请求特征精心筛选出小部分用户的请求路由至新版本的 Pod 应用,并持续观察其是否能稳定地按期望方式运行。默认,Service 只会随机或轮询地将用户请求分发给所有的 Pod 对象。确定没有问题后再继续进行完余下的所有 Pod 资源的滚动更新,否则便立即回滚至第一步更新操作。这便是所谓的金丝雀部署