深入掌握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 to011.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.yamlkubectl的执行过程如下:
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有序地、逐个地更新,并且能够保留更新历史,也能回滚到某个历史版本。