Kubernetes应用编排与管理 —— Deployment升级策略
1、Deployment概述
Deployment 是 Kubernetes 控制器的一种高级别实现,它构建于 ReplicaSet 控制器之上,它可用于为 Pod 和 ReplicaSet 资源提供声明式更新,并能够以自动方式实现跨多个 ReplicaSet 对象的滚动更新功能。相比较来说,Pod 和 ReplicaSet 是较低级别的资源,以至于很少被直接使用。
Deployment 控制器资源的主要职责同样是为了保证 Pod 资源健康运行,其大部分功能通过调用 ReplicaSet 控制器实现,并增添了部分特性。
- 版本记录:将 Deployment 对象的更新操作予以保存,以便后续可能执行的回滚操作使用。
- 回滚:更新操作启动后的任一时刻(包括完成后)发现问题,都可以通过回滚机制将应用返回到前一个或由用户指定的历史记录中的版本。
- 暂停和启动:更新过程中能够随时暂停和继续完成后面的步骤。
- 事件和状态查看:必要时可以查看 Deployment 对象的更新进度和状态。
- 多种升级策略:一是 Recreate,即重建更新机制,单批次更新所有 Pod 对象;另一个是 RollingUpdate,即滚动更新机制,多批次逐步替换旧有的 Pod 至新的版本。
通过以上内容可以知道Deployment提供了很多核心功能,在本文主要关注Deployment多种升级策略功能。通过深入研究Deployment升级策略,我们将获得更好的理解和掌握如何在Kubernetes环境中进行应用程序的升级。我们将学习如何选择合适的升级策略,并了解如何正确配置和管理升级过程中的各种参数。最终,我们将能够实现无缝、可控的应用程序升级,提高应用的稳定性和可用性。
在接下来的篇章中,让我们一起深入探索Deployment升级策略的精髓,并学习如何在实际应用中应用这些策略,为应用程序的持续演进提供支持。
注意 1:Deployment只负责管理不同版本的ReplicaSet, 由ReplicaSet管理Pod副本数。每个ReplicaSet对应了Deployment template的一个版本,一个ReplicaSet下的Pod都是相同的版本。
2、Deployment升级策略
Deployment控制器支持两种更新策略: 滚动更新(RollingUpdate)和删除式更新(Recreate)也称为单批次更新,默认使用滚动更新策略。
- 滚动更新(Rolling Update),滚动更新是默认的更新策略,一次仅更新一批Pod,当更新的Pod就绪后再更新另一批,直到全部更新完成为止;该策略实现了不间断服务的目标,但是在更新过程中,不同客户端得到的响应内容可能会来自不同版本的应用,会出现新老版本共存状态。
- 删除式更新(Recreate),当更新策略设定为Recreate,在更新镜像时,它会先删除现在正在运行的Pod,等彻底杀死后,重新创建新的RS(ReplicaSet),然后启动对应的Pod,在整个更新过程中,会造成服务一段时间无法提供服务。也称之为单批次更新。
Deployment 控制器的滚动更新操作并非在同一个 ReplicaSet 控制器对象下删除并创建 Pod 资源,而是将它们分置于两个不同的控制器之下,当前 ReplicaSet 对象的 Pod 副本数量不断减少的同时,新 ReplicaSet 对象的 Pod 对象数量不断增加,直到现有 ReplicaSet 对象的 Pod 副本数为 0,而新控制器的副本数量变得完全符合期望值,新旧版本之间区别彼此 Pod 对象的关键标签为 pod-template-hash。
2.1 滚动更新(Rolling Update)策略实战
2.1.1 滚动更新(Rolling Update)策略升级步骤
滚动更新(RollingUpdate)一次仅更新一批Pod,当更新的Pod就绪(可用)后,再更新另一批,直到全部更新完成为止,该策略实现了不间断服务的目标,在更新过程中可能会出现不同的应用版本且并存,同时提供服务的情况,Rolling Update升级策略分为三个步骤:
- 创建新的RS,然后根据新的镜像运行新的Pod。
- 删除旧的Pod,启动新的Pod,当新Pod就绪后,继续删除旧Pod,启动新Pod。
- 持续第二步过程,直到所有Pod都被更新成功。
注意 1:注意滚动升级步骤第2步,存在先增新后减旧、先减旧后增新、同时增减(少减多增)多种情况,具体与滚动升级策略属性spec.strategy.rollingUpdate.maxSurge和spec.strategy.rollingUpdate.maxUnavailable配置相关,此部分会在下文进行详细解释。
注意 2:在Deployment的滚动升级期间,可以通过以下方式判断Pod是否处于可用状态:Pod配置就绪探针(Readiness Probe)的情况下:如果就绪探针的探测结果为成功,则表示容器已经准备好接收流量,该Pod被认为是就绪状态。Pod没有就绪探针的情况下:判断Pod是否就绪的依据主要是基于Pod的运行状态,一般Pod的状态为Running则认为Pod是就绪状态。
注意 3:修改 Deployment 控制器的 minReadySeconds、replicas 和 strategy 等字段的值并不会触发 Pod 资源的更新操作,因为它们不属于 template 的内嵌字段,对现存的 Pod 对象不产生任何影响。
2.1.2 滚动更新(Rolling Update)策略实战
(1)应用配置示例
type字段须配置为RollingUpdate spec: strategy: type: RollingUpdate 应用配置文件,现版本Nginx是1.16版本,要滚动到1.21.5; root@kubernetes-master01:~ cat nginx-deployment-test.yaml apiVersion: apps/v1 kind: Deployment metadata: name: deployment-nginx-test namespace: deployment-test spec: strategy: type: RollingUpdate replicas: 2 selector: matchLabels: app: nginx-deployment template: metadata: labels: app: nginx-deployment spec: containers: - name: nginx image: nginx:1.16 imagePullPolicy: IfNotPresent ports: - name: http containerPort: 80
在集群创建Deployment工作负载对象deployment-nginx-test。
[root@node1 deploy] kubectl create ns deployment-test namespace/deployment-test created [root@node1 deploy] kubectl apply -f nginx-deployment-test.yaml deployment.apps/deployment-nginx-test created
查看Deployment工作负载对象deployment-nginx-test状态,可以看到其滚动升级策略类型为RollingUpdate,这里提前注意下滚动升级策略默认属性值25% max unavailable, 25% max surge,此部分会在下文进行详细解释。
[root@node1 deploy] kubectl describe deployments.apps -n=deployment-test deployment-nginx-test Name: deployment-nginx-test Namespace: deployment-test CreationTimestamp: Tue, 27 Jun 2023 09:29:42 +0800 Labels: <none> Annotations: deployment.kubernetes.io/revision: 1 Selector: app=nginx-deployment Replicas: 2 desired | 2 updated | 2 total | 2 available | 0 unavailable StrategyType: RollingUpdate MinReadySeconds: 0 RollingUpdateStrategy: 25% max unavailable, 25% max surge Pod Template: Labels: app=nginx-deployment Containers: nginx: Image: nginx:1.16 Port: 80/TCP Host Port: 0/TCP Environment: <none> Mounts: <none> Volumes: <none> Conditions: Type Status Reason ---- ------ ------ Available True MinimumReplicasAvailable Progressing True NewReplicaSetAvailable OldReplicaSets: <none> NewReplicaSet: deployment-nginx-test-65b5c9746c (2/2 replicas created) Events: <none>
查看Deployment工作负载对象deployment-nginx-test关联Pod状态。
[root@node1 deploy] kubectl get pods -n=deployment-test NAME READY STATUS RESTARTS AGE deployment-nginx-test-65b5c9746c-nc875 1/1 Running 0 6m43s deployment-nginx-test-65b5c9746c-rbzsx 1/1 Running 0 6m43s
(2)测试滚动更新升级策略
修改Deployment工作负载对象deployment-nginx-test镜像版本,测试滚动更新升级策略。
[root@node1 deploy] kubectl set image -n=deployment-test deployment/deployment-nginx-test nginx=nginx:latest deployment.apps/deployment-nginx-test image updated
在测试滚动更新升级策略的同时,开一个新的shell窗口,监视Deployment工作负载对象deployment-nginx-test关联Pod的实时状态变化。
[root@node1 ~] kubectl get pods -n=deployment-test --watch NAME READY STATUS RESTARTS AGE deployment-nginx-test-65b5c9746c-2f599 1/1 Running 0 23s deployment-nginx-test-65b5c9746c-m9lrs 1/1 Running 0 23s deployment-nginx-test-74859ff6d8-lhphh 0/1 Pending 0 0s deployment-nginx-test-74859ff6d8-lhphh 0/1 Pending 0 0s deployment-nginx-test-74859ff6d8-lhphh 0/1 ContainerCreating 0 0s deployment-nginx-test-74859ff6d8-lhphh 1/1 Running 0 2s deployment-nginx-test-65b5c9746c-2f599 1/1 Terminating 0 78s deployment-nginx-test-74859ff6d8-kjcgf 0/1 Pending 0 0s deployment-nginx-test-74859ff6d8-kjcgf 0/1 Pending 0 0s deployment-nginx-test-74859ff6d8-kjcgf 0/1 ContainerCreating 0 0s deployment-nginx-test-65b5c9746c-2f599 0/1 Terminating 0 79s deployment-nginx-test-74859ff6d8-kjcgf 1/1 Running 0 2s deployment-nginx-test-65b5c9746c-m9lrs 1/1 Terminating 0 80s deployment-nginx-test-65b5c9746c-m9lrs 0/1 Terminating 0 81s deployment-nginx-test-65b5c9746c-m9lrs 0/1 Terminating 0 88s deployment-nginx-test-65b5c9746c-m9lrs 0/1 Terminating 0 88s deployment-nginx-test-65b5c9746c-2f599 0/1 Terminating 0 88s deployment-nginx-test-65b5c9746c-2f599 0/1 Terminating 0 88s
通过监视Deployment工作负载对象deployment-nginx-test关联Pod的实时状态变化可知,当工作负载更新策略设定为Rolling Update,在更新镜像时,它会启动新的Pod,删除旧的Pod,当新的Pod就绪后,继续启动新的Pod,删除旧的Pod,周而复始,直到所有Pod都被更新成功。
注意 1:注意滚动升级步骤第2步,存在先增新后减旧、先减旧后增新、同时增减(少减多增)多种情况,具体与滚动升级策略属性spec.strategy.rollingUpdate.maxSurge和spec.strategy.rollingUpdate.maxUnavailable配置相关,此部分会在下文进行详细解释。
2.1.3 控制滚动更新(Rolling Update)速率
滚动升级策略属性:
- spec.strategy.rollingUpdate.maxSurge:决定了 Deployment 配置中期望的副本数之外,最多允许超出的 Pod 实例的数量,其值可以是 0 或正整数,也可以是相对于期望值的一个百分比。默认值为 25% 当把百分数转换成绝对值时,会将数字四舍五入。比如,如果期望副本数被设置为 4,maxSurge 属性值为 25%,则表示 Pod 对象总数至多不能超过 5个;如果期望值为 10,maxSurge 属性值为 2,则表示 Pod 对象总数至多不能超过 12 个。
- spec.strategy.rollingUpdate.maxUnavailable:决定了在滚动升级期间 ,相对于期望副本数能够允许有多少 Pod 实例处于不可用状态。默认值也是 25% ,所以可用 Pod 实例的数量(包括新旧版本)不能低于期望副本数的 75% 。百分数转换成绝对值时这个数字也会四舍五入。比如,如果期望副本数设置为4 ,并且百分比为 25%,那么只能有一个 Pod 处于不可用状态,在整个发布过程中 ,总是保持至少有三个 Pod 实例处于可用状态来提供服务。与 maxSurge 一样,也可以指定绝对值而不是百分比。比如,如果期望值是 10,则升级期间至少要有 9 个 Pod 对象处于正常提供服务的状态。
可组合定义出 3 种不同的策略完成多批次的应用更新:
- 先增新,后减旧:将 maxSurge 设定为小于等于期望值的正整数或相对于期望值的一个百分比,而 maxUnavailable 的值为 0。
- 先减旧,后增新:将 maxUnavailable 设定为小于等于期望值的正整数或相对于期望值的一个百分比,而 maxSurge 的值为 0。
- 同时增减(少减多增):将 maxSurge 和 maxUnavailabe 字段的值同时设定为小于等于期望值的正整数或相对于期望值的一个百分比,二者可以使用不同值。
注意 1:maxSurge 和 maxUnavailable 属性的值不可同时为 0,否则 Pod 对象的副本数量在符合用户期望的数量后无法做出合理变动以进行滚动更新操作。
注意 2:有个特例,如果期望副本数被设置为 1,使用 Deployment 默认滚动升级策略,滚动升级策略属性值也都是默认值(maxSurge: 25%、maxUnavailable: 25%),由于期望实例数 1*maxSurge 四舍五入=0,期望实例数 1*maxUnavailable 四舍五入=0,那么在滚动升级期间,Pod 对象总数至多为1,至少有1个 Pod 处于正常提供服务的状态,按照公式计算,则此工作负载无法做出合理变动以进行滚动更新操作。实际情况是先增新,后减旧。
示例,创建Deploymnet工作负载对象,其实例数为1,使用默认滚动升级策略,滚动升级策略属性值也都是默认值(maxSurge: 25%、maxUnavailable: 25%),配置文件和2.1.2除了工作负载实例数外一致。
[root@node1 deploy] kubectl apply -f nginx-deployment-test.yaml deployment.apps/deployment-nginx-test created [root@node1 deploy] kubectl get pods -n=deployment-test NAME READY STATUS RESTARTS AGE deployment-nginx-test-65b5c9746c-cwbhr 0/1 ContainerCreating 0 5s [root@node1 deploy] kubectl get pods -n=deployment-test NAME READY STATUS RESTARTS AGE deployment-nginx-test-65b5c9746c-cwbhr 1/1 Running 0 8s修改Deployment工作负载对象deployment-nginx-test镜像版本,测试滚动更新升级策略。
[root@node1 deploy] kubectl set image -n=deployment-test deployment/deployment-nginx-test nginx=nginx:latest deployment.apps/deployment-nginx-test image updated在测试滚动更新升级策略的同时,开一个新的shell窗口,监视Deployment工作负载对象deployment-nginx-test关联Pod的实时状态变化。
[root@node1 ~] kubectl get pods -n=deployment-test --watch NAME READY STATUS RESTARTS AGE deployment-nginx-test-65b5c9746c-cwbhr 1/1 Running 0 4m12s deployment-nginx-test-74859ff6d8-kj2dw 0/1 Pending 0 0s deployment-nginx-test-74859ff6d8-kj2dw 0/1 Pending 0 0s deployment-nginx-test-74859ff6d8-kj2dw 0/1 ContainerCreating 0 0s deployment-nginx-test-74859ff6d8-kj2dw 1/1 Running 0 2s deployment-nginx-test-65b5c9746c-cwbhr 1/1 Terminating 0 4m26s deployment-nginx-test-65b5c9746c-cwbhr 0/1 Terminating 0 4m27s通过监视Deployment工作负载对象deployment-nginx-test关联Pod的实时状态变化可知,如果期望副本数被设置为 1,使用 Deployment 默认滚动升级策略,滚动升级策略属性值也都是默认值(maxSurge: 25%、maxUnavailable: 25%),在更新镜像时,它会启动新的Pod,然后再删除旧的Pod。
2.1.4 减慢滚动更新(Rolling Update)速率
Deployment 还支持使用 spec.minReadySeconds 字段来减慢滚动更新的速度,其默认值为 0,表示新建的 Pod 对象一旦“就绪”将立即被视作可用,随后即可开始下一轮更新过程。而为该字段指定一个正整数值能够定义新建的 Pod 对象至少要成功运行多久才会被视作可用,即就绪之后还要等待 minReadySeconds 指定的时长才能开始下一批次的更新。在此期间,更新操作会被阻塞,因此,它可用用来让kubernetes在每次创建出 Pod 资源后都要等上一部分实践再开始下一轮的替换;因此为minReadySeconds设置一个合理的值,不仅仅能够减慢更新速度,还能够让Deployment发现一部分程序因为BUG而导致的升级故障。
minReadySeconds属性配合就绪探针的配置,可以确保容器真正就绪后才会接收流量,避免将流量发送到尚未完全启动或初始化的容器上。这样可以提高应用程序的可用性和稳定性。
2.1.5 RevisionHistoryLimit
Deployment控制器保留了一部分更新历史中旧版本的ReplicaSet对象,当我们执行回滚操作时,就直接使用旧版本的ReplicaSet,在Deployment资源保存历史版本数量有spec.revisionHistoryLimit属性进行定义,默认值为10。
2.1.6 progressDeadlineSeconds
滚动更新故障超时时长,默认为600秒,k8s在升级过程中有可能由于各种原因升级卡住(这个时候还没有明确的升级失败)比如在拉取被墙的镜像,权限不够等错误,如果配置progressDeadlineSeconds当达到了时间如果还卡着,则会上报这个异常情况,这个时候Deployment的状态就会被标记为false,并且注明原因,但是它不会阻止Deployment继续进行卡住后面的升级操作。
2.1.7 滚动更新(Rolling Update)应用场景
Deployment的Rolling Update升级策略适用于以下场景:
- 无缝升级:滚动更新策略可以确保应用在升级过程中保持可用性。它逐步替换旧版本的Pod,新版本的Pod会逐渐接收流量,从而实现无缝的应用升级,减少对用户的影响。
- 资源平滑过渡:滚动更新策略允许在升级期间逐渐引入新版本的Pod,同时逐渐停止旧版本的Pod。这样可以避免在短时间内突然增加或减少应用实例的数量,有助于平滑地过渡和分配资源。
- 故障恢复:当旧版本的Pod出现故障或不可用时,滚动更新策略可以自动替换这些故障的Pod,保证应用的可用性和稳定性。
- 流量控制和负载均衡:滚动更新策略可以通过逐步替换Pod的方式来控制应用接收的流量。这对于在应用程序层面进行负载均衡或测试新版本性能非常有用。
- 灰度发布和A/B测试:滚动更新策略可以实现灰度发布和A/B测试的需求。通过逐渐引入新版本的Pod,可以将一部分流量导向新版本,以便在生产环境中进行测试和评估新功能或变化。
滚动更新策略在实现应用的平滑升级、故障恢复、资源过渡和流量控制方面具有优势,适用于大多数应用部署场景。它能够减少对用户的影响,提供可靠的应用更新和管理机制。
2.2 删除式更新(Recreate)策略实战
2.2.1 删除式更新(Recreate)策略升级步骤
Recreate策略在更新镜像时,它会先删除现在正在运行的Pod,等彻底杀死后,重新创建新的RS(ReplicaSet),然后启动对应的Pod,在整个更新过程中,会造成服务一段时间无法提供服务。也称之为单批次更新。Recreate升级策略分为三个步骤:
- 杀死所有旧版本的Pod,此时Pod无法正常对外提供服务;
- 创建新的RS,启动新的Pod;
- 等待Pod就绪,对外提供服务;
2.2.2 删除式更新(Recreate)策略实战
(1)应用配置示例
必须在Spec字段中明确定义strategy滚动更新策略和type类型 [root@node1 deploy] cat nginx-deployment-test.yaml apiVersion: apps/v1 kind: Deployment metadata: name: deployment-nginx-test namespace: deployment-test spec: strategy: 滚动更新策略 type: Recreate Recreate表示的是删除式更新,也称为单批次更新; replicas: 2 selector: matchLabels: app: nginx-deployment template: metadata: labels: app: nginx-deployment spec: containers: - name: nginx image: nginx:1.16 imagePullPolicy: IfNotPresent ports: - name: http containerPort: 80
在集群创建Deployment工作负载对象deployment-nginx-test。
[root@node1 deploy] kubectl create ns deployment-test namespace/deployment-test created [root@node1 deploy] kubectl apply -f nginx-deployment-test.yaml deployment.apps/deployment-nginx-test created
查看Deployment工作负载对象deployment-nginx-test状态,可以看到其滚动升级策略类型为Recreate。
[root@node1 deploy] kubectl describe deployments.apps -n=deployment-test deployment-nginx-test Name: deployment-nginx-test Namespace: deployment-test CreationTimestamp: Tue, 27 Jun 2023 07:53:37 +0800 Labels: <none> Annotations: deployment.kubernetes.io/revision: 1 Selector: app=nginx-deployment Replicas: 2 desired | 2 updated | 2 total | 2 available | 0 unavailable StrategyType: Recreate MinReadySeconds: 0 Pod Template: Labels: app=nginx-deployment Containers: nginx: Image: nginx:1.16 Port: 80/TCP Host Port: 0/TCP Environment: <none> Mounts: <none> Volumes: <none> Conditions: Type Status Reason ---- ------ ------ Available True MinimumReplicasAvailable Progressing True NewReplicaSetAvailable OldReplicaSets: <none> NewReplicaSet: deployment-nginx-test-65b5c9746c (2/2 replicas created) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ScalingReplicaSet 2m21s deployment-controller Scaled up replica set deployment-nginx-test-65b5c9746c to 2
查看Deployment工作负载对象deployment-nginx-test关联Pod状态。
[root@node1 deploy] kubectl get pods -n=deployment-test NAME READY STATUS RESTARTS AGE deployment-nginx-test-65b5c9746c-nc875 1/1 Running 0 6m43s deployment-nginx-test-65b5c9746c-rbzsx 1/1 Running 0 6m43s
(2)测试删除式更新升级策略
修改Deployment工作负载对象deployment-nginx-test镜像版本,测试删除式更新升级策略。
[root@node1 deploy] kubectl set image -n=deployment-test deployment/deployment-nginx-test nginx=nginx:latest deployment.apps/deployment-nginx-test image updated
在测试删除式更新升级策略的同时,开一个新的shell窗口,监视Deployment工作负载对象deployment-nginx-test关联Pod的实时状态变化。
[root@node1 ~] kubectl get pods -n=deployment-test --watch NAME READY STATUS RESTARTS AGE deployment-nginx-test-65b5c9746c-927r9 1/1 Running 0 73s deployment-nginx-test-65b5c9746c-vxztk 1/1 Running 0 73s deployment-nginx-test-65b5c9746c-vxztk 1/1 Terminating 0 80s deployment-nginx-test-65b5c9746c-927r9 1/1 Terminating 0 80s deployment-nginx-test-65b5c9746c-927r9 0/1 Terminating 0 83s deployment-nginx-test-65b5c9746c-vxztk 0/1 Terminating 0 84s deployment-nginx-test-65b5c9746c-vxztk 0/1 Terminating 0 92s deployment-nginx-test-65b5c9746c-vxztk 0/1 Terminating 0 92s deployment-nginx-test-65b5c9746c-927r9 0/1 Terminating 0 92s deployment-nginx-test-65b5c9746c-927r9 0/1 Terminating 0 92s deployment-nginx-test-74859ff6d8-zcmz4 0/1 Pending 0 0s deployment-nginx-test-74859ff6d8-zcmz4 0/1 Pending 0 0s deployment-nginx-test-74859ff6d8-h4889 0/1 Pending 0 0s deployment-nginx-test-74859ff6d8-h4889 0/1 Pending 0 0s deployment-nginx-test-74859ff6d8-h4889 0/1 ContainerCreating 0 0s deployment-nginx-test-74859ff6d8-zcmz4 0/1 ContainerCreating 0 0s deployment-nginx-test-74859ff6d8-zcmz4 1/1 Running 0 8s
通过监视Deployment工作负载对象deployment-nginx-test关联Pod的实时状态变化可知,当工作负载更新策略设定为Recreate,在更新镜像时,它会先删除现在正在运行的Pod,等彻底杀死后,重新创建新的RS(ReplicaSet),然后启动对应的Pod,在整个更新过程中,会造成服务一段时间无法提供服务。也称之为单批次更新。
2.2.3 Recreate策略应用场景:
Deployment的Recreate升级策略适用于以下场景:
-
快速回滚:当需要迅速回滚到先前的应用版本时,Recreate策略可以很方便地实现。通过将新版本的Pod全部替换为旧版本的Pod,可以快速恢复到先前稳定的应用状态。
-
环境重建:当需要重新创建整个应用环境时,Recreate策略是一个合适的选择。例如,在测试环境或开发环境中,需要定期清理和重新创建应用实例,以确保环境的一致性和稳定性。
-
应用初始化:在部署新的应用时,Recreate策略可以用来确保所有的Pod都从头开始初始化。这对于一些需要重置状态或执行初始设置的应用非常有用。
-
其他: 对于传统企业大部分业务系统,升级前通常会发升级公告,一般是周五晚上12点左右进行新版本的升级,这个时候使用Recreate策略可以迅速的升级新版本;另外对于一些测试环境,或者说资源比较缺乏的一些环境,使用Recreate策略升级应用可以临时节约集群资源,使用默认Rolling Update升级策略时,如果不对Deployment升级策略做特殊配置,使用其默认滚动升级策略的话,在升级过程中会最多存在“期望实例数+maxSurge”个Pod实例数,尤其对于先增新,后减旧的情况,如果集群资源很缺乏并且Pod资源需求很大,由于旧Pod还占用着资源,集群可能就会没法调度新Pod,就会导致滚动升级失败,现象是客户端访问的还是旧的程序。
注意 1:使用Recreate策略进行滚动升级时,会在更新期间出现应用不可用的瞬间。因为在替换旧版本Pod之前,新版本Pod需要先全部启动完成。因此,在选择使用Recreate策略时,需要确保应用对短暂的停机时间或不可用性可以容忍。
3、总结
Deployment升级策略是在Kubernetes中用于管理应用程序更新的重要机制。它允许在保证服务的可用性的同时,逐步将旧版本的Pod替换为新版本的Pod。Deployment提供了两种主要的升级策略:Recreate(重建)和RollingUpdate(滚动更新)。
-
重建(Recreate)策略:
- 适用情况:适用于无状态应用或不需要保持持久连接的有状态应用;测试环境或者说资源比较缺乏的一些环境,使用Recreate策略升级应用可以临时节约集群资源。
- 工作原理:在升级过程中,会先删除所有旧的Pod,然后创建新的Pod来替换它们。
- 优点:升级速度快,对资源的需求较少。
- 缺点:在升级过程中可能会出现服务中断,因为所有的Pod都会同时停止。
-
滚动更新(RollingUpdate)策略:
- 适用情况:适用于需要保持持久连接、有状态应用或对服务中断敏感的应用。
- 工作原理:通过逐步替换旧版本的Pod来进行升级,保证服务的连续性。
- 优点:避免了服务中断,可以逐步将新版本的Pod引入流量,保证应用的可用性。
- 缺点:升级过程相对较慢,可能会占用更多的资源。
- 建议:为了确保服务不中断,建议结合使用Pod就绪探针和MinReadySeconds。就绪探针检测Pod内容器是否就绪,MinReadySeconds设定等待时间,确保Pod稳定后再进行下一步升级,提高服务可用性。