ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、视频、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
设想一个场景,我们的服务需要升级,传统的做法是:暂停与该服务相关的所有 Pod,下载新镜像并创建新的 Pod,这种方式不好的地方是升级的过程中,会导致服务不可用,进而影响整体的产品体验。因此 kubernetes 提供了滚动升级功能来解决这个问题。 通常使用 Deployment 来创建 Pod 资源对象,当 Pod 在运行中,可以修改 Deployment 的 Pod 定义或是镜像名称,并应用到 Deployment 对象上,这样就完成了 Deployment 的自动更新操作。在更新过程中发生了错误,可以通过回滚操作恢复 Pod 的版本。 这里我们将 Pod 的镜像更新为`nginx:1.9.1`: ~~~bash $ kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1 deployment.extensions/nginx-deployment image updated # 也可以使用 kubectl edit 命令进行更新,把 image 字段下的 nginx:1.7.9 更改为 nginx:1.9.1 $ kubectl edit deployment/nginx-deployment deployment.extensions/nginx-deployment edited ~~~ 上面我们修改了镜像名,就会触发系统完成 Deployment 所有运行 Pod 的滚动升级操作,查看 rollout 的状态: ~~~bash $ kubectl rollout status deployment/nginx-deployment deployment "nginx-deployment" successfully rolled out ~~~ 需要注意的是:当且仅当 Deployment 的`.spec.template`字段下的`labels`或是`image`更新时才会触发 rollout,其它的更新并不会触发 rollout。 查看更新后的 Deployment、RS、Pods: ~~~bash # 可以看到 UP-TO-DATE 的数量已经变成了 3,说明已经全部更新完成 $ kubectl get deployment NAME READY UP-TO-DATE AVAILABLE AGE nginx-deployment 3/3 3 3 143m # 查看两个 RS 的最终状态,可以看到旧的 RS 已经没有 Pod 在运行了,新的 RS 创建好了 3 个新的 Pod $ kubectl get rs NAME DESIRED CURRENT READY AGE nginx-deployment-5754944d6c 0 0 0 143m nginx-deployment-7448597cd5 3 3 3 6m11s # 由新 nginx-deployment-7448597cd5 RS 创建出来的 3 个 Pod $ kubectl get pods NAME READY STATUS RESTARTS AGE nginx-deployment-7448597cd5-7c9ms 1/1 Running 0 6m19s nginx-deployment-7448597cd5-h6k89 1/1 Running 0 5m58s nginx-deployment-7448597cd5-m8dnk 1/1 Running 0 5m25s ~~~ 查看现在 nginx-deployment 的详细信息: ~~~bash $ kubectl describe deployments/nginx-deployment ... Annotations: deployment.kubernetes.io/revision: 2 ... Image: nginx:1.9.1 ... OldReplicaSets: <none> # ReplicaSet 更新为 nginx-deployment-7448597cd5 NewReplicaSet: nginx-deployment-7448597cd5 (3/3 replicas created) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ScalingReplicaSet 14m deployment-controller Scaled up replica set nginx-deployment-7448597cd5 to 1 Normal ScalingReplicaSet 14m deployment-controller Scaled down replica set nginx-deployment-5754944d6c to 2 Normal ScalingReplicaSet 14m deployment-controller Scaled up replica set nginx-deployment-7448597cd5 to 2 Normal ScalingReplicaSet 13m deployment-controller Scaled down replica set nginx-deployment-5754944d6c to 1 Normal ScalingReplicaSet 13m deployment-controller Scaled up replica set nginx-deployment-7448597cd5 to 3 Normal ScalingReplicaSet 13m deployment-controller Scaled down replica set nginx-deployment-5754944d6c to 0 ~~~ 从`Events`事件中我们可以看到 Pod 的更新过程: * 系统创建了一个新的 RS(nginx-deployment-7448597cd5),将其副本数量扩展到 1;将旧的 RS(nginx-deployment-5754944d6c)副本数量缩减为 2 * 新的 RS 副本数量扩展到了 2,旧的 RS 副本数量缩减为 1 * 新的 RS 副本数量扩展到了 3,旧的 RS 副本数量缩减为 0 就是通过这样逐步替换的过程完成了整个 Pod 的更新,这个过程中保证了整体服务不中断,并且副本数量始终维持为用户指定的数量。 Deployment 通过字段`spec.strategy`设置 Pod 更新策略,我们上面创建的 Deployment 的相关默认设置如下: ~~~yaml spec: strategy: rollingUpdate: maxSurge: 25% maxUnavailable: 25% type: RollingUpdate ~~~ Deployment 的更新策略有两种: * `Recreat`(重建): 先 kill 掉所有正在运行的 Pod,然后创建新的 Pod。 * `RollingUpdate`(滚动更新): 逐个更新 Pod。可以在字段`spec.strategy.rollingUpdate`下设置两个参数`maxSurge`和`maxUnavailable`来控制滚动更新的过程。 关于两个参数的详细说明: * `maxUnavailable`:指定更新过程中不可用状态的 Pod 数量上限。默认值 25% 指的是:Pod 期望副本数的 25%,然后系统会以向下取整的方式计算出绝对值(整数)。对于这里而言,当开始滚动更新时,旧的 RS 立即将副本数缩小到所需副本总数的 75%(3 \* 75% = 2.25,然后向下取整,绝对值为 2),一旦新的 Pod 创建并准备好,旧的 RS 会进一步缩容,新的 RS 会进一步扩容,整个过程中系统在任意时刻都可以确保可用状态的 Pod 总数至少占 Pod 期望副本总数的 75%。 * `maxSurge`:指定更新过程中 Pod 总数超过 Pod 期望副本数部分的最大值。默认值 25% 指的是:Pod 期望副本数的 25%,然后系统会以向上取整的方式计算出绝对值(整数)。对于这里而言,新的 RS 可以在滚动更新开始时立即进行副本数扩容,只要保证新旧 RS 的 Pod 副本总数之和不超过期望副本数的 125% 即可。一旦旧的 Pod 被 kill 掉,新的 RS 会进一步扩容。在整个过程中系统在任意时刻都能确保新旧 RS 的 Pod 副本总数之和不超过所需副本数的 125%。