Pod升级和回滚
当集群中的某个服务需要升级时,我们需要停止目前与该服务相关的所有 Pod ,然后下载新版本镜像井创建新的 Pod 如果集群规模比较大,则这个工作就变成了一个挑战,而且先全部停止然后逐步升级的方式会导致较长时间的服务不可用 Kubernetes 提供了滚动升级功能来解决上述问题。
如果 Pod 是通过 Deployment 建的,则用户可以在运行时修改 Deployment的Pod 定义(spec.template )或镜像名称 ,井应用到 Deployment 对象上,系统即可完成 Deployment 的自动更新操作。如果在更新过程中发生了错误, 则还可以通过回滚( Rollback )操作恢复 Pod的版本。
一、Deployment升级
Deployment nginx
1 | #nginx-deployment.yaml |
将nginx更新为1.9.1,通过kubectl set image命令为Deployment设置新的镜像
1 | #通过命令行修改 |
升级会触发Pod的滚动升级操作
1 | kubectl rollout status deployment/nginx-deployment |
二、Deployment升级过程
更新过程
1 | kubectl describe deployments nginx-deployment |
初始创 Deployment 时, 系统创建了一 ReplicaSet求创建了 Pod 副本,当更新 Deployment 系统 建了一个新 ReplicaSet并将其副本数扩展 然后将旧的 ReplicaSet缩减为 2。之后,系统按照相同策略对新旧两个RepilcaSet进行调整。

查看2个ReplicaSet状态
1 | kubectl get rs |
升级过程中,系统会保证至少有两个 Pod 可用,并且最多同时运行4个 Pod,这是 Deployment 通过复杂的算法完成的。 Deployment 需要确保在整个更新过程中只有一定数量的 Pod 可能处于不可用状态,在默认情况下, Deployment 确保可用的 Pod 总数至少为所需的副本的数量( DESIRED )减1 ,也就是最多1个不可用( maxUnavailable=1), Deployment还需要确保在整个更新过程中 Pod 的总数量不会超过所需的副本数太多,在默认情况下,Deployment 确保 Pod 的总数最 比所 Pod 数多1个,也就是最多1个浪涌值(maxSurge=1)Kubenretes v1.6 版本开始, maxUnavailable 和maxSurge 默认值将从1,1更新为所需副本数的 25%、25%
更新策略
Deployment 的定义中,可以通过 spec.strategy指定 Pod 更新的策略,目前支持两种策略RollingUpdate (被动更新)和 Recreate (重建) ,默认值为 RollingUpdate
Recreate(重建):设置spec. strategy. type= Recreate表示 Deployment 在更新 Pod 时,会先杀掉所有正在运行的 Pod ,然后创建新的 PodRollingUpdate(滚动更新):设置spec.strategy.type=RollingUpdate,表示 Deployment以滚动更新的方式来逐个更新 Pod 。同时,可以通过设置spec. strategy rollingUpdate下的两个参数(maxUnavailable、maxSurge)来控制被动更新的过程。
滚动升级的参数:
spec.strategy.rollingUpdate.maxUnavailable:指定 Deployment 在更新过程中不可用状态 Pod 的上限。可以是绝对值也可以是百分比spec.strategy.rollingUpdate.maxSurge:Pod 总数超过Pod 期望副本数部分的最大值
多重更新:如果Deployment 上一次更新正在进行 ,此时用户再次发起 Deployment 更新操作,那 Deployment 每一次更新都创建一个ReplicaSet 而每次新的 ReplicaSet成功后,会逐 Pod 副本数 ,同时将之前正在扩容的 ReplicaSet 停止扩容(更新) 并将其加入旧版本 ReplicaSet 列表中,然后开始缩容至操作。
注意更新 Deployment 的标签选择器( Label selector )的情况。不鼓励更新Deployment 的标签选择器,因为这样会导致 Deployment选择的Pod列表发生变化,也能与其他控制器产生冲突。注意事项:
- 添加选择器标签时,必须同步修改 Deployment配置的Pod 的标签 ,为 Pod 添加新的标签,否则
Deployment的更新会报验证错误而失败。添加标签选择器是无法向后兼容的,新的标签选择器不会匹配和使用旧选择器创建的ReplicaSet和Pod ,因此添加选择器将会导致旧版ReplicaSet和Pod处于孤立状态 - 更新标签选择器,即更改选择器中标签的键或者值,也会产生与添加选择器标签类似的效果。
- 删除标签选择器, 即从 Deployment 标签选择器中删除一个或者多个标签,该
Deployment的ReplicaSet和Pod不会受到任何影响,不是被删除的标签 仍会存在于现有Pod和ReplicaSet上。
二、Deployment的回滚
当我们更新一个镜像出现错误,这时需要用kubectl rollout history查看Deployment部署的历史记录
1 | kubectl rollout history deployment/nginx-deployment |
创建Deployment时使用--record参数,就可以在CHANGE-CAUSE中看到每个版本的命令
Deployment 的更新操作是在 Deployment 进行部署( Rollout )时被触发的, 这意味着当且仅当 Deployment的Pod (即
spec.template)被更改时才会创建新的修订版本,例如更新模板标签或容器镜像。其他更新操作(如扩展副本数〉将不会触发 Deployment的更新操作,这也意味着我 Deployment 回滚之前版本时, 只有 Deployment的Pod板部分会被修改。
1 | #查看特定版本的详细信息 ,可以加--revision=<N>参数 |
回滚到上一个版本:
1 | kubectl rollout undo deployment/nginx-deployment |
三、暂停和恢复Deployment的部署
对于一次复杂的 Deployment 配置修改,为了避免频繁触发 Deployment 更新操作,可以先暂停 Deployment 的更新操作,然后进行配置修改,再恢复 Deployment ,一次性触发完整的更新操作,就可以避免不必要的Deployment 更新操作了。
1 | #通过 kubectl rollout pause 命令暂停 Deployment 的更新操作: |
四、其他管理对象的更新策略
DaemonSet 的更新策略
包含2种升级策略
OnDelete: 当使用OnDelete作为升级策略时, 建好新DaemonSet配置之后 Pod 并不会被自动创建,直到用户手动删除旧版本 Pod 发新建操。RollingUpdate:旧版本的 Pod 将被自动杀掉, 然后自动创建新版本的DaemonSetPod整个过程与普通deployment的滚动升级一样是可控 。不同于普通 Pod 滚动升级:- 不支持查看和管理
DaemonSet更新历史记录 - DaemonSet 回滚并不能如同 Deployment 样直接通过
kubectl rollback命令来实现, 而是必须通过再次提交旧版本配置的方式实现。
- 不支持查看和管理
StatefulSet更新
针对 StatefulSet 的更新策略正逐渐向 Deploymont DaemonSet的更新策略看齐 ,也将实 RollingUpdate Paritioned OnDelete 种策略 目标是保证StatefulSet 中各 Pod 有序 、逐个被更新,并且能够保留更新历史,也能回滚到某个历史版本。





