news 2026/11/2 11:20:22

Kubernetes权威指南——深入掌握Pod(七)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Kubernetes权威指南——深入掌握Pod(七)

深入掌握Pod

    • 11、Pod的升级和回滚
      • 11.1、Deployment的升级
      • 11.2、Deployment的回滚
      • 11.3、暂停和恢复Deployment的部署操作,以完成复杂的修改
      • 11.4、使用kubectl rolling-update命令完成RC的滚动升级
      • 11.5、其他管理对象的更新策略
        • 11.5.1、DaemonSet的更新策略
        • 11.5.2、StatefulSet的更新策略

11、Pod的升级和回滚

当集群中的某个服务需要升级时,我们需要停止目前与该服务相关的所有Pod,然后下载新版本镜像并创建新的Pod。如果集群规模比较大,则这个工作变成了一个挑战,而且先全部停止然后逐步升级的方式会导致较长时间的服务不可用。Kubernetes提供了滚动升级功能来解决上述问题。

如果Pod是通过Deployment创建的,则用户可以在运行时修改Deployment的Pod定义(spec.template)或镜像名称,并应用到Deployment对象上,系统即可完成Deployment的自动更新操作。如果在更新过程中发生了错误,则还可以通过回滚操作恢复Pod的版本。

11.1、Deployment的升级

以Deployment nginx为例:

apiVersion:apps/v1kind:Deployment# 资源类型:Kubernetes Deployment(工作负载控制器)metadata:name:nginx-deployment# Deployment 的名称spec:replicas:3# 期望运行的 Pod 副本数量(这里是 3 个)selector:# 标签选择器:Deployment 通过此规则来关联和管理哪些 PodmatchLabels:app:nginx# 必须与下方 template 中的标签保持一致template:metadata:labels:app:nginx# 为该 Deployment 创建的 Pod 打上标签spec:containers:-name:nginx# 容器名称image:nginx:1.7.9# 使用的 Nginx 镜像及指定版本ports:-containerPort:80# 容器监听的端口

已运行的Pod副本数量有3个:

# kubectl get podsNAME READY STATUS RESTARTS AGE nginx-deployment-4087004473-9jqqs1/1 Running01m nginx-deployment-4087004473-cq0cf1/1 Running01m nginx-deployment-4087004473-vxn561/1 Running01m

现在Pod镜像需要被更新为Nginx:1.9.1,我们可以通过kubectl set image命令为Deployment设置新的镜像名称:

$ kubectlsetimage deployment/nginx-deploymentnginx=nginx:1.9.1 deployment"nginx-deployment"image updated

另一种更新的方法是使用kubectl edit命令修改Deployment的配置,将spec.template.spec.containers[0].image从Nginx:1.7.9更改为Nginx:1.9.1:

$ kubectl edit deployment/nginx-deployment deployment"nginx-deployment"edited

一旦镜像名(或Pod定义)发生了修改,则将触发系统完成Deployment所有运行Pod的滚动升级操作。可以使用kubectl rollout status命令查看Deployment的更新过程:

$ kubectl rollout status deployment/nginx-deploymentWaiting for rollout to finish:2 out of 3 new replicas have been updated...Waiting for rollout to finish:2 out of 3 new replicas have been updated...Waiting for rollout to finish:2 out of 3 new replicas have been updated...Waiting for rollout to finish:2 out of 3 new replicas have been updated...Waiting for rollout to finish:2 old replicas are pending termination...Waiting for rollout to finish:1 old replicas are pending termination...Waiting for rollout to finish:1 old replicas are pending termination...Waiting for rollout to finish:1 old replicas are pending termination...Waiting for rollout to finish:2 of 3 updated replicas are available...deployment "nginx-deployment" successfully rolled out

查看当前运行的Pod,名称已经更新了:

$ kubectl get pods NAME READY STATUS RESTARTS AGE nginx-deployment-3599678771-01h26 1/1 Running 0 2m nginx-deployment-3599678771-57thr 1/1 Running 0 2m nginx-deployment-3599678771-s8p21 1/1 Running 0 2m

查看Pod使用的镜像,已经更新为Nginx:1.9.1了:

# kubectl describe pod/nginx-deployment-3599678771-s8p21Name: nginx-deployment-3599678771-s8p21......Image: nginx:1.9.1......

那么,Deployment是如何完成Pod更新的呢?

我们可以使用kubectl describe deployments/nginx-deployment命令仔细观察Deployment的更新过程。初始创建Deployment时,系统创建了一个ReplicaSet(nginx-deployment-4087004473)​,并按用户的需求创建了3个Pod副本。当更新Deployment时,系统创建了一个新的ReplicaSet(nginx-deployment-3599678771)​,并将其副本数量扩展到1,然后将旧的ReplicaSet缩减为2。之后,系统继续按照相同的更新策略对新旧两个ReplicaSet进行逐个调整。最后,新的ReplicaSet运行了3个新版本Pod副本,旧的ReplicaSet副本数量则缩减为0。如图所示。

下面列出Deployment nginx-deployment的详细事件信息:

$ kubectl describe deployments/nginx-deployment Name: nginx-deployment Namespace: default......Replicas:3updated|3total|3available|0unavailable StrategyType: RollingUpdate MinReadySeconds:0RollingUpdateStrategy:1max unavailable,1max surge Conditions: Type Status Reason ---- ------ ------ Available TrueMinimumReplicasAvailable OldReplicaSets:<none>NewReplicaSet: nginx-deployment-3599678771(3/3 replicas created)Events: FirstSeen LastSeen Count From SubObjectPath Type Reason Message --------- ------------- ---- ------------- -------------- ------- 55m 55m1{deployment-controller}Normal ScalingReplicaSet Scaled up replicasetnginx-deployment-4087004473 to34m 4m1{deployment-controller}Normal ScalingReplicaSet Scaled up replicasetnginx-deployment-3599678771 to14m 4m1{deployment-controller}Normal ScalingReplicaSet Scaled down replicasetnginx-deployment-4087004473 to24m 4m1{deployment-controller}Normal ScalingReplicaSet Scaled up replicasetnginx-deployment-3599678771 to24m 4m1{deployment-controller}Normal ScalingReplicaSet Scaled down replicasetnginx-deployment-4087004473 to14m 4m1{deployment-controller}Normal ScalingReplicaSet Scaled up replicasetnginx-deployment-3599678771 to34m 4m1{deployment-controller}Normal ScalingReplicaSet Scaled down replicasetnginx-deployment-4087004473 to0

运行kubectl get rs命令,查看两个ReplicaSet的最终状态:

$ kubectl get rs NAME DESIRED CURRENT READY AGE nginx-deployment-35996787713331m nginx-deployment-408700447300052m

在整个升级的过程中,系统会保证至少有两个Pod可用,并且最多同时运行4个Pod,这是Deployment通过复杂的算法完成的。Deployment需要确保在整个更新过程中只有一定数量的Pod可能处于不可用状态。在默认情况下,Deployment确保可用的Pod总数至少为所需的副本数量(DESIRED)减1,也就是最多1个不可用(maxUnavailable=1)​。Deployment还需要确保在整个更新过程中Pod的总数量不会超过所需的副本数量太多。在默认情况下,Deployment确保Pod的总数最多比所需的Pod数多1个,也就是最多1个浪涌值(maxSurge=1)​。Kubernetes从1.6版本开始,maxUnavailable和maxSurge的默认值将从1、1更新为所需副本数量的25%、25%。

这样,在升级过程中,Deployment就能够保证服务不中断,并且副本数量始终维持为用户指定的数量(DESIRED)​。

对更新策略的说明如下。

在Deployment的定义中,可以通过spec.strategy指定Pod更新的策略,目前支持两种策略:Recreate(重建)和RollingUpdate(滚动更新)​,默认值为RollingUpdate。在前面的例子中使用的就是RollingUpdate策略。

  • Recreate:设置spec.strategy.type=Recreate,表示Deployment在更新Pod时,会先杀掉所有正在运行的Pod,然后创建新的Pod。
  • RollingUpdate:设置spec.strategy.type=RollingUpdate,表示Deployment会以滚动更新的方式来逐个更新Pod。同时,可以通过设置spec.strategy.rollingUpdate下的两个参数(maxUnavailable和maxSurge)来控制滚动更新的过程。

下面对滚动更新时两个主要参数的说明如下。

  • spec.strategy.rollingUpdate.maxUnavailable:用于指定Deployment在更新过程中不可用状态的Pod数量的上限。该maxUnavailable的数值可以是绝对值(例如5)或Pod期望的副本数的百分比(例如10%)​,如果被设置为百分比,那么系统会先以向下取整的方式计算出绝对值(整数)​。而当另一个参数maxSurge被设置为0时,maxUnavailable则必须被设置为绝对数值大于0(从Kubernetes 1.6开始,maxUnavailable的默认值从1改为25%)​。举例来说,当maxUnavailable被设置为30%时,旧的ReplicaSet可以在滚动更新开始时立即将副本数缩小到所需副本总数的70%。一旦新的Pod创建并准备好,旧的ReplicaSet会进一步缩容,新的ReplicaSet又继续扩容,整个过程中系统在任意时刻都可以确保可用状态的Pod总数至少占Pod期望副本总数的70%。
  • spec.strategy.rollingUpdate.maxSurge:用于指定在Deployment更新Pod的过程中Pod总数超过Pod期望副本数部分的最大值。该maxSurge的数值可以是绝对值(例如5)或Pod期望副本数的百分比(例如10%)​。如果设置为百分比,那么系统会先按照向上取整的方式计算出绝对数值(整数)​。从Kubernetes 1.6开始,maxSurge的默认值从1改为25%。举例来说,当maxSurge的值被设置为30%时,新的ReplicaSet可以在滚动更新开始时立即进行副本数扩容,只需要保证新旧ReplicaSet的Pod副本数之和不超过期望副本数的130%即可。一旦旧的Pod被杀掉,新的ReplicaSet就会进一步扩容。在整个过程中系统在任意时刻都能确保新旧ReplicaSet的Pod副本总数之和不超过所需副本数的130%。

这里需要注意多重更新(Rollover)的情况。如果Deployment的上一次更新正在进行,此时用户再次发起Deployment的更新操作,那么Deployment会为每一次更新都创建一个ReplicaSet,而每次在新的ReplicaSet创建成功后,会逐个增加Pod副本数,同时将之前正在扩容的ReplicaSet停止扩容(更新)​,并将其加入旧版本ReplicaSet列表中,然后开始缩容至0的操作。

例如,假设我们创建一个Deployment,这个Deployment开始创建5个Nginx:1.7.9的Pod副本,在这个创建Pod动作尚未完成时,我们又将Deployment进行更新,在副本数不变的情况下将Pod模板中的镜像修改为Nginx:1.9.1,又假设此时Deployment已经创建了3个Nginx:1.7.9的Pod副本,则Deployment会立即杀掉已创建的3个Nginx:1.7.9 Pod,并开始创建Nginx:1.9.1 Pod。Deployment不会在等待Nginx:1.7.9的Pod创建到5个之后再进行更新操作。

还需要注意更新Deployment的标签选择器(LabelSelector)的情况。通常来说,不鼓励更新Deployment的标签选择器,因为这样会导致Deployment选择的Pod列表发生变化,也可能与其他控制器产生冲突。如果一定要更新标签选择器,那么请务必谨慎,确保不会出现其他问题。关于Deployment标签选择器的更新的注意事项如下。

  • (1)添加选择器标签时,必须同步修改Deployment配置的Pod的标签,为Pod添加新的标签,否则Deployment的更新会报验证错误而失败:

    deployments"nginx-deployment"was not valid: * spec.template.metadata.labels: Invalid value:{"app":"nginx"}:`selector`does not match template`labels`

    添加标签选择器是无法向后兼容的,这意味着新的标签选择器不会匹配和使用旧选择器创建的ReplicaSets和Pod,因此添加选择器将会导致所有旧版本的ReplicaSets和由旧ReplicaSets创建的Pod处于孤立状态(不会被系统自动删除,也不受新的ReplicaSet控制)​。

    为标签选择器和Pod模板添加新的标签(使用kubectledit deployment命令)后,效果如下:

    $ kubectl get rs NAME DESIRED CURRENT READY AGE nginx-deployment-36617425163332s nginx-deployment-35996787713331m nginx-deployment-408700447300052m

    可以看到新ReplicaSet(nginx-deployment-3661742516)创建的3个新Pod:

    $ kubectl get pods NAME READY STATUS RESTARTS AGE nginx-deployment-3599678771-01h261/1 Running02m nginx-deployment-3599678771-57thr1/1 Running02m nginx-deployment-3599678771-s8p211/1 Running02m nginx-deployment-3661742516-46djm1/1 Running052s nginx-deployment-3661742516-kws841/1 Running052s nginx-deployment-3661742516-wq30s1/1 Running052s
  • (2)更新标签选择器,即更改选择器中标签的键或者值,也会产生与添加选择器标签类似的效果。

  • (3)删除标签选择器,即从Deployment的标签选择器中删除一个或者多个标签,该Deployment的ReplicaSet和Pod不会受到任何影响。但需要注意的是,被删除的标签仍会存在于现有的Pod和ReplicaSets上。

11.2、Deployment的回滚

有时(例如新的Deployment不稳定时)我们可能需要将Deployment回滚到旧版本。在默认情况下,所有Deployment的发布历史记录都被保留在系统中,以便于我们随时进行回滚(可以配置历史记录数量)​。

假设在更新Deployment镜像时,将容器镜像名误设置成Nginx:1.91(一个不存在的镜像)​:

$ kubectlsetimage deployment/nginx-deploymentnginx=nginx:1.91 deployment"nginx-deployment"image updated

则这时Deployment的部署过程会卡住:

$ kubectl rollout status deployments nginx-deployment Waitingforrollout to finish:1out of3new replicas have been updated...

由于执行过程卡住,所以需要执行Ctrl-C命令来终止这个查看命令。

查看ReplicaSet,可以看到新建的ReplicaSet(nginx-deployment-3660254150)​:

$ kubectl get rs NAME DESIRED CURRENT READY AGE nginx-deployment-364629502833353s nginx-deployment-366025415011040s nginx-deployment-42342840260001m

再查看创建的Pod,会发现新的ReplicaSet创建的1个Pod被卡在镜像拉取过程中。

$ kubectl get pods NAME READY STATUS RESTARTS AGE nginx-deployment-3646295028-d5r6r1/1 Running01m nginx-deployment-3646295028-jw22d1/1 Running059s nginx-deployment-3646295028-tw6x71/1 Running01m nginx-deployment-3660254150-9kj510/1 ImagePullBackOff049s

为了解决上面这个问题,我们需要回滚到之前稳定版本的Deployment。

首先,用kubectl rollout history命令检查这个Deployment部署的历史记录:

$ kubectl rollouthistorydeployment/nginx-deployment deployments"nginx-deployment"REVISION CHANGE-CAUSE1kubectl create--filename=nginx-deployment.yaml--record=true2kubectlsetimage deployment/nginx-deploymentnginx=nginx:1.9.13kubectlsetimage deployment/nginx-deploymentnginx=nginx:1.91

注意,在创建Deployment时使用–record参数,就可以在CHANGE-CAUSE列看到每个版本使用的命令了。另外,Deployment的更新操作是在Deployment进行部署(Rollout)时被触发的,这意味着当且仅当Deployment的Pod模板(即spec.template)被更改时才会创建新的修订版本,例如更新模板标签或容器镜像。其他更新操作(如扩展副本数)将不会触发Deployment的更新操作,这也意味着我们将Deployment回滚到之前的版本时,只有Deployment的Pod模板部分会被修改。

如果需要查看特定版本的详细信息,则可以加上--revision=<N>参数:

$ kubectl rollouthistorydeployment/nginx-deployment--revision=3deployments"nginx-deployment"with revision#3Pod Template: Labels:app=nginx pod-template-hash=3660254150Annotations: kubernetes.io/change-cause=kubectlsetimage deployment/nginx-deploymentnginx=nginx:1.91 Containers: nginx: Image: nginx:1.91 Port:80/TCP Environment:<none>Mounts:<none>Volumes:<none>

现在我们决定撤销本次发布并回滚到上一个部署版本:

$ kubectl rollout undo deployment/nginx-deployment deployment"nginx-deployment"rolled back

当然,也可以使用–to-revision参数指定回滚到的部署版本号:

$ kubectl rollout undo deployment/nginx-deployment --to-revision=2deployment"nginx-deployment"rolled back

这样,该Deployment就回滚到之前的稳定版本了,可以从Deployment的事件信息中查看到回滚到版本2的操作过程:

$ kubectl describe deployment/nginx-deployment Name: nginx-deployment......OldReplicaSets:<none>NewReplicaSet: nginx-deployment-3646295028(3/3 replicas created)Events: FirstSeen LastSeen Count From SubObjectPath Type Reason Message --------- -------- ----- ---- ------------- -------- ------ ------- 4m 4m1deployment-controller Normal ScalingReplicaSet Scaled up replicasetnginx-deployment-4234284026 to34m 4m1deployment-controller Normal ScalingReplicaSet Scaled up replicasetnginx-deployment-3646295028 to14m 4m1deployment-controller Normal ScalingReplicaSet Scaled down replicasetnginx-deployment-4234284026 to24m 4m1deployment-controller Normal ScalingReplicaSet Scaled up replicasetnginx-deployment-3646295028 to24m 4m1deployment-controller Normal ScalingReplicaSet Scaled down replicasetnginx-deployment-4234284026 to14m 4m1deployment-controller Normal ScalingReplicaSet Scaled up replicasetnginx-deployment-3646295028 to34m 4m1deployment-controller Normal ScalingReplicaSet Scaled down replicasetnginx-deployment-4234284026 to04m 4m1deployment-controller Normal ScalingReplicaSet Scaled up replicasetnginx-deployment-3660254150 to136s 36s1deployment-controller Normal DeploymentRollback Rolled back deployment"nginx-deployment"to revision236s 36s1deployment-controller Normal ScalingReplicaSet Scaled down replicasetnginx-deployment-3660254150 to0

11.3、暂停和恢复Deployment的部署操作,以完成复杂的修改

对于一次复杂的Deployment配置修改,为了避免频繁触发Deployment的更新操作,可以先暂停Deployment的更新操作,然后进行配置修改,再恢复Deployment,一次性触发完整的更新操作,就可以避免不必要的Deployment更新操作了。

以之前创建的Nginx为例:

$ kubectl get deployments NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE nginx-deployment330332s $ kubectl get rs NAME DESIRED CURRENT READY AGE nginx-deployment-42342840263337s

通过kubectl rollout pause命令暂停Deployment的更新操作:

$ kubectl rollout pause deployment/nginx-deployment deployment"nginx-deployment"paused

然后修改Deployment的镜像信息:

$ kubectlsetimage deploy/nginx-deploymentnginx=nginx:1.9.1 deployment"nginx-deployment"image updated

然后修改Deployment的镜像信息:

$ kubectlsetimage deploy/nginx-deploymentnginx=nginx:1.9.1 deployment"nginx-deployment"image updated

查看Deployment的历史记录,发现并没有触发新的Deployment部署操作:

$ kubectl rollouthistorydeploy/nginx-deployment deployments"nginx-deployment"REVISION CHANGE-CAUSE1kubectl create--filename=nginx-deployment.yaml--record=true

在暂停Deployment部署之后,可以根据需要进行任意次数的配置更新。例如,再次更新容器的资源限制:

$ kubectlsetresourcesdeployment nginx-deployment-c=nginx--limits=cpu=200m,memory=512Mi deployment"nginx-deployment"resource requirements updated

最后,恢复这个Deployment的部署操作:

$ kubectl rollout resume deploy nginx-deployment deployment"nginx-deployment"resumed

可以看到一个新的ReplicaSet被创建出来了:

$ kubectl get rs NAME DESIRED CURRENT READY AGE nginx-deployment-31334408823336s nginx-deployment-423428402600049s

查看Deployment的事件信息,可以看到Deployment完成了更新:

# kubectl describe deployment/nginx-deploymentName: nginx-deployment......Events: FirstSeen LastSeen Count From SubObjectPath Type Reason Message --------- -------- ----- ---- ------------- -------- ------ ------- 1m 1m1deployment-controller Normal ScalingReplicaSet Scaled up replicasetnginx-deployment-4234284026 to328s 28s1deployment-controller Normal ScalingReplicaSet Scaled up replicasetnginx-deployment-3133440882 to127s 27s1deployment-controller Normal ScalingReplicaSet Scaled down replicasetnginx-deployment-4234284026 to227s 27s1deployment-controller Normal ScalingReplicaSet Scaled up replicasetnginx-deployment-3133440882 to226s 26s1deployment-controller Normal ScalingReplicaSet Scaled down replicasetnginx-deployment-4234284026 to125s 25s1deployment-controller Normal ScalingReplicaSet Scaled up replicasetnginx-deployment-3133440882 to323s 23s1deployment-controller Normal ScalingReplicaSet Scaled down replicasetnginx-deployment-4234284026 to0

注意,在恢复暂停的Deployment之前,无法回滚该Deployment。

11.4、使用kubectl rolling-update命令完成RC的滚动升级

对于RC的滚动升级,Kubernetes还提供了一个kubectlrolling-update命令进行实现。该命令创建了一个新的RC,然后自动控制旧的RC中的Pod副本数量逐渐减少到0,同时新的RC中的Pod副本数量从0逐步增加到目标 值,来完成Pod的升级。需要注意的是,系统要求新的RC与旧的RC都在相同的命名空间内。

以redis-master为例,假设当前运行的redis-master Pod是1.0版本,现在需要升级到2.0版本。

创建redis-master-controller-v2.yaml的配置文件如下:

apiVersion:v1kind:ReplicationController# 资源类型:ReplicationController(RC 控制器,用于确保指定数量的 Pod 副本在运行)metadata:name:redis-master-v2# RC 的名称labels:name:redis-masterversion:v2spec:replicas:1# 期望运行的 Pod 副本数量(这里为 1 个)selector:# 选择器:定义该 RC 管理哪些带有特定标签的 Podname:redis-masterversion:v2template:metadata:labels:name:redis-master# Pod 模板的标签,必须与上方的 selector 保持一致version:v2spec:containers:-name:master# 容器名称image:kubeguide/redis-master:2.0# 使用的 Redis 主节点镜像ports:-containerPort:6379# 容器暴露的端口(Redis 默认端口)

在配置文件中需要注意以下两点。

  • RC的名字(name)不能与旧RC的名字相同。
  • 在selector中应至少有一个Label与旧RC的Label不同,以标识其为新RC。在本例中新增了一个名为version的Label,以与旧RC进行区分。

运行kubectl rolling-update命令完成Pod的滚动升级:

kubectl rolling-update redis-master-fredis-master-controller-v2.yaml

kubectl的执行过程如下:

Creating redis-master-v2 At beginning of loop: redis-master replicas:2, redis-master-v2 replicas:1Updating redis-master replicas:2, redis-master-v2 replicas:1At end of loop: redis-master replicas:2, redis-master-v2 replicas:1At beginning of loop: redis-master replicas:1, redis-master-v2 replicas:2Updating redis-master replicas:1, redis-master-v2 replicas:2At end of loop: redis-master replicas:1, redis-master-v2 replicas:2At beginning of loop: redis-master replicas:0, redis-master-v2 replicas:3Updating redis-master replicas:0, redis-master-v2 replicas:3At end of loop: redis-master replicas:0, redis-master-v2 replicas:3Update succeeded. Deleting redis-master redis-master-v2

等所有新的Pod都启动完成后,旧的Pod也被全部销毁,这样就完成了容器集群的更新工作。

另一种方法是不使用配置文件,直接用kubectl rolling-update命令,加上–image参数指定新版镜像名称来完成Pod的滚动升级:

kubectl rolling-update redis-master--image=redis-master:2.0

与使用配置文件的方式不同,执行的结果是旧RC被删除,新RC仍将使用旧RC的名称。

kubectl的执行过程如下:

Creating redis-master-ea866a5d2c08588c3375b86fb253db75 At beginning of loop: redis-master replicas:2, redis-master-ea866a5d2c08588c 3375b86fb253db75 replicas:1Updating redis-master replicas:2, redis-master-ea866a5d2c08588c3375b86fb253db75replicas:1At end of loop: redis-master replicas:2, redis-master-ea866a5d2c08588c3375b86fb 253db75 replicas:1At beginning of loop: redis-master replicas:1, redis-master-ea866a5d2c08588c 3375b86fb253db75 replicas:2Updating redis-master replicas:1, redis-master-ea866a5d2c08588c3375b86fb 253db75 replicas:2At end of loop: redis-master replicas:1, redis-master-ea866a5d2c08588c3375b86fb 253db75 replicas:2At beginning of loop: redis-master replicas:0, redis-master-ea866a5d2c08588c 3375b86fb253db75 replicas:3Updating redis-master replicas:0, redis-master-ea866a5d2c08588c3375b86fb253db75replicas:3At end of loop: redis-master replicas:0, redis-master-ea866a5d2c08588c3375b86fb 253db75 replicas:3Update succeeded. Deleting old controller: redis-master Renaming redis-master-ea866a5d2c08588c3375b86fb253db75 to redis-master redis-master

可以看到,kubectl通过新建一个新版本Pod,停掉一个旧版本Pod,如此逐步迭代来完成整个RC的更新。

更新完成后,查看RC:

$ kubectl get rc CONTROLLER CONTAINER(S)IMAGE(S)SELECTOR REPLICAS redis-master master kubeguide/redis-master:2.0deployment=ea866a5d2c08588c3375b86fb253db75,name=redis-master,version=v13

可以看到,kubectl给RC增加了一个key为“deployment”的Label(这个key的名字可通过–deployment-label-key参数进行修改)​,Label的值是RC的内容进行Hash计算后的值,相当于签名,这样就能很方便地比较RC里的Image名字及其他信息是否发生了变化。

如果在更新过程中发现配置有误,则用户可以中断更新操作,并通过执行kubectl rolling- update --rollback完成Pod版本的回滚:

$ kubectl rolling-update redis-master--image=kubeguide/redis-master:2.0--rollbackFound existing updateinprogress(redis-master-fefd9752aa5883ca4d53013a7b583967), resuming. Found desired replicas.Continuing update with existing controller redis-master. At beginning of loop: redis-master-fefd9752aa5883ca4d53013a7b583967 replicas:0, redis-master replicas:3Updating redis-master-fefd9752aa5883ca4d53013a7b583967 replicas:0, redis-master replicas:3At end of loop: redis-master-fefd9752aa5883ca4d53013a7b583967 replicas:0, redis-master replicas:3Update succeeded. Deleting redis-master-fefd9752aa5883ca4d53013a7b583967 redis-master

至此,可以看到Pod恢复到更新前的版本了。

可以看出,RC的滚动升级不具有Deployment在应用版本升级过程中的历史记录、新旧版本数量的精细控制等功能,在Kubernetes的演进过程中,RC将逐渐被RS和Deployment所取代,建议用户优先考虑使用Deployment完成Pod的部署和升级操作。

11.5、其他管理对象的更新策略

Kubernetes从1.6版本开始,对DaemonSet和StatefulSet的更新策略也引入类似于Deployment的滚动升级,通过不同的策略自动完成应用的版本升级。

11.5.1、DaemonSet的更新策略

目前DaemonSet的升级策略包括两种:OnDelete和RollingUpdate。

  • (1)OnDelete:DaemonSet的默认升级策略,与1.5及以前版本的Kubernetes保持一致。当使用OnDelete作为升级策略时,在创建好新的DaemonSet配置之后,新的Pod并不会被自动创建,直到用户手动删除旧版本的Pod,才触发新建操作。
  • (2)RollingUpdate:从Kubernetes 1.6版本开始引入。当使用RollingUpdate作为升级策略对DaemonSet进行更新时,旧版本的Pod将被自动杀掉,然后自动创建新版本的DaemonSet Pod。整个过程与普通Deployment的滚动升级一样是可控的。不过有两点不同于普通Pod的滚动升级:一是目前Kubernetes还不支持查看和管理DaemonSet的更新历史记录;二是DaemonSet的回滚(Rollback)并不能如同Deployment一样直接通过kubectl rollback命令来实现,必须通过再次提交旧版本配置的方式实现。
11.5.2、StatefulSet的更新策略

Kubernetes从1.6版本开始,针对StatefulSet的更新策略逐渐向Deployment和DaemonSet的更新策略看齐,也将实现RollingUpdate、Paritioned和OnDelete这几种策略,以保证StatefulSet中各Pod有序地、逐个地更新,并且能够保留更新历史,也能回滚到某个历史版本。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/11/2 11:19:04

人生有哪些突破:辞掉稳妥的工作去做一件自己真正在意的事、搬到一个谁也不认识的城市、把攒了三年的钱投进一个还没验证的产品、四十岁去学一门和本职毫无关系的技能、把“不好意思开口“的那句话认真说一遍

人生有哪些突破:一份从临终遗憾倒推出来的清单 有位护士叫布朗妮韦尔(Bronnie Ware),在姑息护理病房工作了很多年。她记录下临终者最常说的遗憾,后来写成《临终前最后悔的五件事》。这几条被转述过无数次,因为它们几乎一模一样: 我希望能有勇气过忠于自己的生活,而不是…

作者头像 李华
网站建设 2026/11/2 11:17:41

多智能体三: Fan-out/Gather 并行聚合模式

在多智能体工程体系中&#xff0c;并非所有任务都需要复杂的DAG拓扑调度、串行依赖编排。大量企业级AI场景存在一个共性特征&#xff1a;任务可拆分为多个互相无依赖、可同时执行的独立子任务。针对这类场景&#xff0c;Parallel Fan-out/Result Gather&#xff08;并行分发/结…

作者头像 李华
网站建设 2026/11/2 11:17:22

Blender模型到STL:先过这6道打印检查

从可编辑模型到STL三角网格的几何示意 Blender里的模型能正常显示,不代表导出的STL已经适合打印。本文按“尺寸约定—应用缩放—实体与网格检查—导出—切片回读”走一遍,目标是把一个示例外形为403020 mm的模型,交给默认按毫米读取STL的切片器。 本文菜单与选项依据Blende…

作者头像 李华
网站建设 2026/11/2 11:15:21

ConcurrentHashMap 的实现原理

ConcurrentHashMap 是 HashMap 的线程安全版本&#xff0c;核心目标是在高并发下提供安全的读写&#xff0c;同时尽量避免阻塞。它的实现经历了两个关键阶段&#xff1a;JDK 1.7 用“分段锁”降低锁粒度&#xff0c;JDK 1.8 改为“CAS synchronized 锁单个桶”&#xff0c;并发…

作者头像 李华
网站建设 2026/11/2 11:11:36

RAG 重排实战:正确证据找到了,为什么还是没进上下文?

RAG 重排实战&#xff1a;正确证据找到了&#xff0c;为什么还是没进上下文&#xff1f; 检索返回了 20 段内容&#xff0c;只取前 5 段送给模型&#xff1b;真正支持答案的证据在第 12 位。此时召回并非一无所获&#xff0c;问题出在最终选择。 重排&#xff08;Reranking&am…

作者头像 李华