Kubernetes深入Pod控制器-Deployment控制器

转载于https://abcops.cn/1575.html

Deployment控制器简述介绍

Deployment简写(deploy)是Kubernetes控制器的又一种实现,它构建于 ReplicaSet控制器之上,可为Pod和ReplicaSet资源提供声明式更新,相比较而言,Pod和ReplicaSet是较低级的资源,它们很少被直接使用,Deployment、ReplicaSet和Pod的关系如下图所示:

Deploymnet控制器资源的主要职责同样是为了保证Pod资源的健康运行,其大部分功能均可通过调用ReplicaSet控制器来实现,同时还增添了部分特性,增添特性如下:

  1. 事件和状态查看:必要时可以查看Deployment独享升级的详细进度和状态。
  2. 回滚:升级操作完成后发现问题时,支持使用回滚机制将应用返回到前一个或由用户指定的历史记录的版本上。
  3. 版本记录:对Deployment对象的每一次操作都给予保存,以供后续可能执行的回滚操作使用。
  4. 暂停和启动:对于每一次升级,都能够随时暂停和启动。
  5. 多种自动更新方案:一是Recreate,即重建更新机制,全面停止、删除旧的Pod后用新版本替代;另一个是RollingUpdate,即为滚动升级机制,依次替换旧Pod至新版本。

Deployment的功能:

  1. 部署无状态应用
  2. 管理Pod和ReplicaSet
  3. 具有上线部署、副本设定、滚动升级、回滚等功能
  4. 提供声明式更新,例如只更新一个新的Image

Deployment控制器应用场景:

  1. Web服务
  2. 微服务

Deployment控制器创建配置

Deployment是标准的Kubernetes API资源,它构建于ReplicaSet资源之上,于是其spec字段中嵌套使用的字段包含了ReplicaSet控制器支持的replicas、selector、template和minReadySeconds,它也正是利用这些信息完成了二级资源ReplicaSet对象的构建,下面是一个Deployment控制器资源的配置清单:

1.创建资源配置清单

  1. cat nginx-deploy.yaml
  2. apiVersion: apps/v1
  3. kind: Deployment
  4. metadata:
  5. name: nginx-deployment
  6. namespace: nginx-namespace
  7. annotations:
  8. deployment.k8sops.cn/type: nginx-deploy
  9. labels:
  10. app: nginx-deploy
  11. spec:
  12. replicas: 3
  13. selector:
  14. matchLabels:
  15. app: nginx-proxy
  16. template:
  17. metadata:
  18. labels:
  19. app: nginx-proxy
  20. version: 1.18.0
  21. spec:
  22. containers:
  23. - name: nginx-proxy
  24. image: nginx:1.18.0
  25. ports:
  26. - containerPort: 80
  27. name: http

上面除了控制器类型和名称之外,与上章节讲的ReplicaSet控制器清单内容几乎没有什么不同

2.创建控制器对象及查看状态

  1. #创建deploy控制器
  2. kubectl apply -f nginx-deploy.yaml
  3. deployment.apps/nginx-deployment created
  4. #查看创建的nginx-deployment控制器状态,下面UP-TO-DATE表示已经达到期望状态的Pod副本数量。AVAILABEL表示当前处于可用状态的应用程序数量
  5. kubectl get deploy -n nginx-namespace
  6. NAME READY UP-TO-DATE AVAILABLE AGE
  7. nginx-deployment 3/3 3 3 4s
  8. #查看Pod状态
  9. kubectl get pods -l app=nginx-proxy -n nginx-namespace
  10. NAME READY STATUS RESTARTS AGE
  11. nginx-deployment-84d6c8c7cd-68cr8 1/1 Running 0 25s
  12. nginx-deployment-84d6c8c7cd-jhfrq 1/1 Running 0 25s
  13. nginx-deployment-84d6c8c7cd-q4czp 1/1 Running 0 25s

3.由控制器创建的Pod命名方式
Deployment控制器会自动创建相关的ReplicaSet控制器资源,并以[Deployment-Name]-[Pod-Template-Hash-Value]格式为其命名,其中的hash值由 Deployment控制器自动生成。由Deployment创建的Pod对象会自动使用相同的标签选择器。
上面的命令结果中,Pod对象的名称遵循ReplicaSet控制器的命名格式,它以ReplicaSet控制器的名称前缀,后跟5为随机字符。

Deployment控制器更新策略

ReplicaSet控制器的应用更新需要手动分成多步并以特定的顺序进行,过程繁琐且容易出错,而Deployment却只需要由用户指定在Pod模版中要改动的内容,例如容器镜像文件的版本,余下的步骤可交给控制器自动完成,同样,更新应用程序的规模也只需要修改期望的副本数量,余下的事情交给Deployment控制器即可。
Deployment控制器详细信息中包含了其更新策略的相关配置信息,如下图中命令输出的StrategyTypeRollingUpdateStrategyOldReplicaSets字段等。

1.Deployment控制器默认支持两种更新策略:

  • 滚动更新(rolling update)
  • 重新创建(recreate)

滚动更新(rolling update)

滚动升级是Deployment默认的更新策略,它在删除一部分旧版本Pod资源的同时,补充创建一部分新版本的Pod对象进行应用升级,其优势是升级期间,容器中应用提供的服务不会中断,但要求应用程序能够应对新旧版本同时工作的情况,例如新旧版本兼容同一个数据库方案等。不过更新操作期间,不同客户端得到的响应内容可能会来自不同版本的应用。

帮助文档:kubectl explain deploy.spec.strategy.rollingUpdate

重新创建(recreate)

重新创建更新类似与上章节讲的ReplicaSet的第一种更新方式,首先删除现有的Pod对象,而后由控制器基于新模版重新创建出新版本的资源对象。通常,只应该在应用的新旧版本不兼容时才会使用recreate策略(如依赖的后端数据库的 schema 不同且无法兼容),因为它会导致应用替换期间暂时不可用,好处在于它不存在中间状态,用户访问到的要么是应用的新版本,要么是旧版本。

Deployment控制器的滚动更新操作并非在同一个ReplicaSet控制器对象下删除并创建Pod资源,而是将它们分置于两个不同的控制器之下:旧控制器的Pod对象数量不断减少的同时,新控制器的Pod数量不断增加,直到旧控制器不在拥有Pod对象,而新控制器的副本数量变的完全符合用户期望状态副本数量为止。

滚动更新时,应用升级期间还要确保可用的Pod对象数量不低于某阈值以确保可以持续处理客户端的服务请求,变动的方式和Pod对象的数量范围将通过deployment控制器清单中spec.strategy.rollingUpdate.maxSurgespec.strategy.rollingUpdate.maxUnavailable两个属性协同进行定义。

maxSurge帮助文档:kubectl explain deploy.spec.strategy.rollingUpdate.maxSurge
maxUnavailable帮助文档:kubectl explain deploy.spec.strategy.rollingUpdate.maxUnavailable

maxSurge:

指定升级期间总存在的Pod对象数量,最多可超出期望Pod数量的个数,值可以为0或者整数,也可以是一个期望值的百分比;例如当前Pod副本期望值为3,maxSurge属性值为1,则表示Pod对象在升级期间Pod总数量不能超过4个。

maxUnavailable:

升级期间正常可用的Pod副本数(包括旧版本)最多不能低于期望Pod数量的个数,值可以是一个0或者整数,也可以是一个百分比;默认为1,例如当前Pod副本期望值为3,则表示Pod对象在升级期间Pod总数量不能低2个处于正常服务状态。

注意:
maxSurge和maxUnavailable属性值不可同时为0,否则Pod对象的副本数量在符合用户期望的数量后无法做出合理变动以进行滚动更新操作。

2.spec.minReadySeconds控制应用升级速度
配置清单时,还可以使用Deployment控制器的spec.minReadySeconds属性来控制应用的升级速度。新旧更替过程中,新创建的Pod对象一旦成功响应就绪探测即被视作可用,而后即可开始下一轮的替换操作。而spec.minReadySeconds能够定义在新的Pod对象创建后至少要等待多久才会将其视为就绪,在此期间,更新操作会被阻塞。因此它可以用来让Kubernetes在每次创建Pod资源后都要登上一段时间后再开始下一轮更替,这个时间长度的理想值是等到Pod对象中的应用已经可以接受并处理请求流量。

帮助文档:kubectl explain deploy.spec.minReadySeconds

3.spec.revisionHistoryLimit旧版本数量
Deployment控制器也支持用户保留其滚动更新历史中的旧ReplicaSet对象版本,如下图所示,这赋予了控制器进行应用回滚的能力,用户可按需回滚到指定的历史版本。控制器可保存的历史版本由spec.revisionHistoryLimit属性进行定义,当然,也只有保存于revision历史中的ReplicaSet版本可用于回滚,因此,用户要习惯性地在更新操作时指定保留旧版本。

帮助文档:kubectl explain deploy.spec.revisionHistoryLimit

注意:
为了保存版本升级的历史,需要在创建Deployment对象时使用--record选项

尽管滚动更新节约系统资源,但它也存在一些劣势。直接改动现有环境,会使系统引入不确定性风险,而且升级过程中出现问题后,执行回滚操作也较为缓慢。有鉴于此,金丝雀部署可能是较为理想的实现方式,当然如果不考虑系统系统资源的可用性,那么传统的蓝绿部署也是不错的选择。

Deployment控制器更新示例

修改Pod模版相关的配置参数便能完成Deployment控制器资源的更新,由于是声明式配置,因此对Deployment控制器资源的修改尤其适合kubectl applykubectl patch命令来进行,如果仅是修改容器镜像则可以使用kubectl set image命令。

下面将讲解四种方式进行滚动更新:

  1. 修改Deployment控制器清单(非Pod模版内容)。
  2. 修改Deployment控制器清单中Pod模版。
  3. 通过 kubectl set image 命令直接修改由Deployment所管控Pod的镜像。
  4. 通过 kubectl patch 命令直接修改控制器清单中的任何内容。

1.修改Deployment控制器清单(非Pod模版内容)
修改Deployment控制清单,非Pod模版内容,我们修改内容后,则只对下次新创建的Pod生效,对于已存在的Pod则不会进行更新。

先查看没有修改配置前Deployment控制器是什么配置
如下:minReadySeconds默认为0秒,StrategyType默认为滚动更新,RollingUpdateStrategy默认为百分比25%,

更新deploy控制器配置

  1. cat nginx-deploy.yaml
  2. apiVersion: apps/v1
  3. kind: Deployment
  4. metadata:
  5. name: nginx-deployment
  6. namespace: nginx-namespace
  7. annotations:
  8. deployment.k8sops.cn/type: nginx-deploy
  9. labels:
  10. app: nginx-deploy
  11. spec:
  12. replicas: 3
  13. minReadySeconds: 10 #升级等待时间
  14. revisionHistoryLimit: 6 #旧版本历史数量
  15. strategy:
  16. type: RollingUpdate #指定类型为滚动更新
  17. rollingUpdate:
  18. maxSurge: 1 #可超出期望Pod数量的个数
  19. maxUnavailable: 1 #升级期间不能正常提供服务的Pod
  20. selector:
  21. matchLabels:
  22. app: nginx-proxy
  23. template:
  24. metadata:
  25. namespace: nginx-namespace
  26. labels:
  27. app: nginx-proxy
  28. version: 1.18.0
  29. spec:
  30. containers:
  31. - name: nginx-proxy
  32. image: nginx:1.18.0
  33. ports:
  34. - containerPort: 80
  35. name: http

更新配置文件

  1. kubectl apply -f nginx-deploy.yaml

查看Pod状态,已存在的Pod未发生任何改变

  1. kubectl get pods -o wide -n nginx-namespace
  2. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
  3. nginx-deployment-84d6c8c7cd-68cr8 1/1 Running 0 3h39m 10.244.5.115 k8s-node03 <none> <none>
  4. nginx-deployment-84d6c8c7cd-jhfrq 1/1 Running 0 3h39m 10.244.3.128 k8s-node01 <none> <none>
  5. nginx-deployment-84d6c8c7cd-q4czp 1/1 Running 0 3h39m 10.244.3.129 k8s-node01 <none> <none>

查看控制器详细信息,如下图,我们修改的信息已发生改变,对下次新创建的Pod生效

2.修改Deployment控制器清单中Pod模版
这次我们修改Pod中使用的镜像,将nginx镜像改为latest版本

  1. cat nginx-deploy.yaml
  2. apiVersion: apps/v1
  3. kind: Deployment
  4. metadata:
  5. name: nginx-deployment
  6. namespace: nginx-namespace
  7. annotations:
  8. deployment.k8sops.cn/type: nginx-deploy
  9. labels:
  10. app: nginx-deploy
  11. spec:
  12. replicas: 3
  13. minReadySeconds: 10
  14. revisionHistoryLimit: 6
  15. strategy:
  16. type: RollingUpdate
  17. rollingUpdate:
  18. maxSurge: 1
  19. maxUnavailable: 1
  20. selector:
  21. matchLabels:
  22. app: nginx-proxy
  23. template:
  24. metadata:
  25. namespace: nginx-namespace
  26. labels:
  27. app: nginx-proxy
  28. version: latest #标签也改了下
  29. spec:
  30. containers:
  31. - name: nginx-proxy
  32. image: nginx:latest #修改nginx镜像版本为latest
  33. ports:
  34. - containerPort: 80
  35. name: http

更新配置文件

  1. kubectl apply -f nginx-deploy.yaml

查看更新后的镜像,已经成功更新

  1. kubectl get pods -n nginx-namespace -o custom-columns=Name:metadata.name,Image:spec.containers[0].image
  2. Name Image
  3. nginx-deployment-698f87c954-d8299 nginx:latest
  4. nginx-deployment-698f87c954-g27sh nginx:latest
  5. nginx-deployment-698f87c954-slqq8 nginx:latest

通过kubectl describe查看deployment控制器滚动更新的过程

  1. kubectl describe deploy nginx-deployment -n nginx-namespace | grep -A 10 Events
  2. Events:
  3. Type Reason Age From Message
  4. ---- ------ ---- ---- -------
  5. Normal ScalingReplicaSet 9m3s deployment-controller Scaled up replica set nginx-deployment-698f87c954 to 1
  6. Normal ScalingReplicaSet 9m3s deployment-controller Scaled down replica set nginx-deployment-84d6c8c7cd to 2
  7. Normal ScalingReplicaSet 9m3s deployment-controller Scaled up replica set nginx-deployment-698f87c954 to 2
  8. Normal ScalingReplicaSet 8m50s deployment-controller Scaled down replica set nginx-deployment-84d6c8c7cd to 0
  9. Normal ScalingReplicaSet 8m50s deployment-controller Scaled up replica set nginx-deployment-698f87c954 to 3

如上日志:
第一行:新的ReplicaSet控制器nginx-deployment-698f87c954启动一个新Pod,这个时候是有4个Pod。对外提供服务的Pod还是3个。
第二行:旧的ReplicaSet控制器nginx-deployment-84d6c8c7cd将旧Pod由三个缩小至2个,这个时候对外提供服务的Pod,只有两个旧的。
第三行:新的ReplicaSet控制器nginx-deployment-698f87c954启动第二个新Pod,这个时候对外提供服务的Pod有4个,两个新Pod,和两个旧Pod。
第四行:旧的ReplicaSet控制器nginx-deployment-84d6c8c7cd将旧Pod全部关闭。这个时候提供服务的Pod只有两个新的Pod
第五行:新的ReplicaSet控制器nginx-deployment-698f87c954启动第三个新Pod,对外提供服务的Pod有三个新的Pod。

查看ReplicaSet控制器,如下两个RS控制器,上面的是新RS控制器,下面的是老的RS控制器。

  1. kubectl get rs -n nginx-namespace
  2. NAME DESIRED CURRENT READY AGE
  3. nginx-deployment-698f87c954 3 3 3 50m
  4. nginx-deployment-84d6c8c7cd 0 0 0 4h41m

kubectl rollout status命令用于打印滚动更新过程中的状态信息

  1. kubectl rollout status deploy nginx-deployment -n nginx-namespace
  2. deployment "nginx-deployment" successfully rolled out

kubectl get deploy --watch命令监控其更新过程中Pod对象的变动过程

  1. kubectl get deploy nginx-deployment -n nginx-namespace --watch
  2. NAME READY UP-TO-DATE AVAILABLE AGE
  3. nginx-deployment 3/3 3 3 3h47m
  4. nginx-deployment 3/3 3 3 3h50m
  5. nginx-deployment 3/3 3 3 3h50m
  6. nginx-deployment 3/3 1 3 3h50m
  7. nginx-deployment 3/3 1 3 3h50m
  8. nginx-deployment 2/3 2 2 3h50m
  9. nginx-deployment 3/3 2 2 3h50m
  10. nginx-deployment 4/3 2 2 3h50m
  11. nginx-deployment 4/3 2 4 3h50m
  12. nginx-deployment 4/3 3 4 3h50m
  13. nginx-deployment 2/3 3 2 3h50m
  14. nginx-deployment 3/3 3 2 3h51m
  15. nginx-deployment 3/3 3 3 3h51m

查看更新的版本

  1. kubectl rollout history deployment nginx-deployment -n nginx-namespace
  2. deployment.apps/nginx-deployment
  3. REVISION CHANGE-CAUSE
  4. 1 <none> #第一个版本是没更新Pod之前的
  5. 2 <none> #目前我们在第二个版本

查看版本详细信息

  1. kubectl rollout history deployment nginx-deployment --revision=1 -n nginx-namespace
  2. deployment.apps/nginx-deployment with revision #1
  3. Pod Template:
  4. Labels: app=nginx-proxy
  5. pod-template-hash=84d6c8c7cd #第一个版本的模版hash
  6. version=1.18.0
  7. Containers:
  8. nginx-proxy:
  9. Image: nginx:1.18.0 #第一个版本使用的1.18.0镜像
  10. Port: 80/TCP
  11. Host Port: 0/TCP
  12. Environment: <none>
  13. Mounts: <none>
  14. Volumes: <none>
  15. kubectl rollout history deployment nginx-deployment --revision=2 -n nginx-namespace
  16. deployment.apps/nginx-deployment with revision #2
  17. Pod Template:
  18. Labels: app=nginx-proxy
  19. pod-template-hash=698f87c954 #第二个版本的模版hash
  20. version=latest
  21. Containers:
  22. nginx-proxy:
  23. Image: nginx:latest #第二个版本使用的latest镜像
  24. Port: 80/TCP
  25. Host Port: 0/TCP
  26. Environment: <none>
  27. Mounts: <none>
  28. Volumes: <none>

3.通过 kubectl set image 命令直接修改由Deployment所管控Pod的镜像
我们可以通过kubectl set image命令直接修改deployment控制器中Pod使用的镜像,修改完后Pod就会自动更新。

  1. #set:在资源对象上设定特定功能
  2. #image:在资源对象上设定镜像
  3. #deploy:指定我们资源及资源名称
  4. #nginx:为容器名称
  5. #nginx:latest:为镜像版本
  6. kubectl set image deployment nginx-deployment nginx-proxy=nginx:1.17.10 -n nginx-namespace

查看升级过程

查看升级后的镜像版本

  1. kubectl get pods -n nginx-namespace -o custom-columns=Name:metadata.name,Image:spec.containers[0].image
  2. Name Image
  3. nginx-deployment-7764fd4547-gjq5s nginx:1.17.10
  4. nginx-deployment-7764fd4547-rxscv nginx:1.17.10
  5. nginx-deployment-7764fd4547-xgp9c nginx:1.17.10

4.通过 kubectl patch 命令直接修改控制器清单中的任何内容
将升级等待时间改为5秒

  1. kubectl patch deployment nginx-deployment -p '{"spec": {"minReadySeconds": 5}}' -n nginx-namespace

kubectl patch命令的补丁形式为JSON格式,以-p选项指定,上面命令中的 '{"spec": {"minReadySeconds": 5}}'表示设置spec.minReadySeconds为5秒,若要改变Pod的镜像,也可以使用patch命令,但我们往往不使用kubectl patch命令修改镜像。

Deployment控制器金丝雀发布

Deploymnet控制器还支持自定义控制更新过程中的滚动节奏,如“暂停”pause或“继续”resume更新操作,尤其是借助于上面降到的maxSurgemaxUnavailable属性还能实现更为精巧的过程控制,比如,待第一批新的Pod资源创建完成后立即暂停更新过程,此时,仅存在一小部分新版本的应用,主体部分还是旧的版本,然后在根据用户特征精心筛选出小部分用户的请求路由至新版本的Pod应用,并持续观察其是否稳定地按期望的方式运行。确定没有问题后在继续完成余下Pod资源的滚动更新,否则立即回滚更新操作。这便是所谓的金丝雀发布Canary Release

扩展知识:矿井中的金丝雀
17世纪时,英国矿井工人发现,金丝雀对瓦斯这种气体十分敏感。空气中哪怕有极其微量的瓦斯气体,金丝雀也会停止歌唱;当瓦斯含量超过一定限度时,人类依旧毫无察觉,而金丝雀却早已毒发身亡。当时采矿设备相对简陋的条件下,工人们每次下井都会带上一只金丝雀作为瓦斯检测工具,以便在危险的情况下紧急撤离。

为了尽可能地降低对现有系统及其容量的影响,金丝雀发布过程中通常建议采用“先添加、再删除”,且可用Pod资源对象总数不低于期望值的方式进行。首次添加的Pod对象数量取决于其接入的第一批请求的规则及单个Pod承载能力,视具体需求而定。

1.查看现存Pod状态
现存Pod使用nginx: 1.17.10版本镜像

  1. kubectl get pods -n nginx-namespace -o custom-columns=Name:metadata.name,Image:spec.containers[0].image
  2. Name Image
  3. nginx-deployment-7764fd4547-gjq5s nginx:1.17.10
  4. nginx-deployment-7764fd4547-rxscv nginx:1.17.10
  5. nginx-deployment-7764fd4547-xgp9c nginx:1.17.10

2.配置清单修改如下

  1. cat nginx-deploy.yaml
  2. apiVersion: apps/v1
  3. kind: Deployment
  4. metadata:
  5. name: nginx-deployment
  6. namespace: nginx-namespace
  7. annotations:
  8. deployment.k8sops.cn/type: nginx-deploy
  9. labels:
  10. app: nginx-deploy
  11. spec:
  12. replicas: 3
  13. minReadySeconds: 10 #每个Pod升级后的等待时长
  14. revisionHistoryLimit: 6
  15. strategy:
  16. type: RollingUpdate
  17. rollingUpdate:
  18. maxSurge: 1
  19. maxUnavailable: 0 #升级过程中不可用的Pod为0个
  20. selector:
  21. matchLabels:
  22. app: nginx-proxy
  23. template:
  24. metadata:
  25. namespace: nginx-namespace
  26. labels:
  27. app: nginx-proxy
  28. version: latest
  29. spec:
  30. containers:
  31. - name: nginx-proxy
  32. image: nginx:latest #使用nginx:latest版本镜像
  33. ports:
  34. - containerPort: 80
  35. name: http

下面将使用kubectl apply进行对容器进行进行更新,在更新过程中我们使用kubectl rollout pause命令来暂停更新,然后查看其更新状态。

3.更新deployment控制器并暂停

  1. #更新deployment控制器
  2. kubectl apply -f nginx-deploy.yaml
  3. #更新大概几秒后暂停更新
  4. kubectl rollout pause deploy nginx-deployment -n nginx-namespace

4.查看当前控制器状态

  1. kubectl describe deploy nginx-deployment -n nginx-namespace

如下图所示:
deployment控制器调用了一个新的ReplicaSet控制器nginx-deployment-698f87c954启动了一个新的Pod,使用的是nginx:latest 镜像,

查看当前Pod数量,由于我们在清单中通过maxUnavailable参数设置升级过程中不可用的Pod为0个,所以我们在启动新Pod的时候,不会将原来旧的Pod移除

  1. kubectl get pods -o wide -n nginx-namespace
  2. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
  3. nginx-deployment-698f87c954-hn7wh 1/1 Running 0 2m14s 10.244.3.139 k8s-node01 <none> <none>
  4. nginx-deployment-7764fd4547-gjq5s 1/1 Running 0 15h 10.244.3.138 k8s-node01 <none> <none>
  5. nginx-deployment-7764fd4547-rxscv 1/1 Running 0 15h 10.244.3.136 k8s-node01 <none> <none>
  6. nginx-deployment-7764fd4547-xgp9c 1/1 Running 0 15h 10.244.3.137 k8s-node01 <none> <none>

查看当前Pod使用的镜像版本,如下nginx-deployment-698f87c954-hn7wh Pod是新启动的Pod

  1. kubectl get pods -n nginx-namespace -o custom-columns=Name:metadata.name,Image:spec.containers[0].image
  2. Name Image
  3. nginx-deployment-698f87c954-hn7wh nginx:latest
  4. nginx-deployment-7764fd4547-gjq5s nginx:1.17.10
  5. nginx-deployment-7764fd4547-rxscv nginx:1.17.10
  6. nginx-deployment-7764fd4547-xgp9c nginx:1.17.10

监控Pod的状态可以发现如下,控制器创建并启动了一个新的Pod

最后Pod可用数量为4个,就绪Pod为3个

通过kubectl rollout status查看控制器更新状态,可以看到,在创建一个新版本的Pod资源后滚动更新暂停

  1. kubectl rollout status deploy nginx-deployment -n nginx-namespace
  2. Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 3 new replicas have been updated...

查看当前ReplicaSet控制器数量,目前新的RS控制器是nginx-deployment-698f87c954

  1. kubectl get rs -n nginx-namespace -o wide
  2. NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
  3. nginx-deployment-698f87c954 1 1 1 16h nginx-proxy nginx:latest app=nginx-proxy,pod-template-hash=698f87c954
  4. nginx-deployment-7764fd4547 3 3 3 15h nginx-proxy nginx:1.17.10 app=nginx-proxy,pod-template-hash=7764fd4547
  5. nginx-deployment-84d6c8c7cd 0 0 0 20h nginx-proxy nginx:1.18.0 app=nginx-proxy,pod-template-hash=84d6c8c7cd

暂停更新后,我们可以通过网络策略将service或者Ingress资源的流量引入新创建的Pod之上进行发布验证,运行一段时间后,如果确认没有问题,即可使用kubectl rollout resume命令继续此前的滚动更新过程:

5.恢复更新

  1. kubectl rollout resume deploy nginx-deployment -n nginx-namespace

6.查看更新过程

  1. kubectl rollout status deploy nginx-deployment -n nginx-namespace
  2. Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
  3. Waiting for deployment spec update to be observed...
  4. Waiting for deployment spec update to be observed...
  5. Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
  6. Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
  7. Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
  8. Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
  9. Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
  10. Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
  11. Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending termination...
  12. Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending termination...
  13. Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending termination...
  14. deployment "nginx-deployment" successfully rolled out

如下看到更新过程中,始终的就绪Pod都为3

我们可以使用多种命令动态检测更新过程中的deploy状态,Pod状态等,以下列出几个

动态查看deploy控制器状态变化:kubectl get deploy nginx-deployment -n nginx-namespace --watch
动态查看Pod状态变化:kubectl get pods -o wide -n nginx-namespace --watch
动态查看Pod镜像变化:kubectl get pods -n nginx-namespace -o custom-columns=Name:metadata.name,Image:spec.containers[0].image --watch
动态查看控制器更新过程:kubectl rollout status deploy nginx-deployment -n nginx-namespace
查看deploy控制的时间信息:kubectl describe deploy nginx-deployment -n nginx-namespace
动态查看被deploy调用的RS控制器变化:kubectl get rs -n nginx-namespace -o wide --watch

Deployment控制器回滚操作

如果在发布过程后导致某种问题,或者金丝雀“遇险”等,则需要将该应用回滚到此前的版本,或则回滚到由用户指定的历史记录的版本。Deployment控制器的回滚操作可使用kubectl rollout undo命令完成。

1.查看发布的历史记录
通过kubectl rollout history命令可以看到控制器的版本记录

  1. kubectl rollout history deploy nginx-deployment -n nginx-namespace
  2. deployment.apps/nginx-deployment
  3. REVISION CHANGE-CAUSE
  4. 1 <none>
  5. 3 <none>
  6. 4 <none>

2.查看发布历史版本的详细信息
通过kubectl rollout history --revision=[number]命令可以看到某个版本的详细记录

  1. kubectl rollout history deploy nginx-deployment -n nginx-namespace --revision=3
  2. deployment.apps/nginx-deployment with revision #3
  3. Pod Template:
  4. Labels: app=nginx-proxy
  5. pod-template-hash=7764fd4547
  6. version=latest
  7. Containers:
  8. nginx-proxy:
  9. Image: nginx:1.17.10
  10. Port: 80/TCP
  11. Host Port: 0/TCP
  12. Environment: <none>
  13. Mounts: <none>
  14. Volumes: <none>

3.回滚到上一个版本
回滚到上一个版本直接使用kubectl rolloute undo命令即可完成

  1. kubectl rollout undo deploy nginx-deployment -n nginx-namespace

4.查看回滚后的镜像版本

  1. kubectl get pods -n nginx-namespace -o custom-columns=Name:metadata.name,Image:spec.containers[0].image --watch
  2. Name Image
  3. nginx-deployment-7764fd4547-g7zhv nginx:1.17.10
  4. nginx-deployment-7764fd4547-lj5n9 nginx:1.17.10
  5. nginx-deployment-7764fd4547-qjxw7 nginx:1.17.10

5.回滚到指定版本
通过kubectl rollout undo --to-revision=[number]来进行回滚到指定版本

  1. kubectl rollout undo deploy nginx-deployment --to-revision=1 -n nginx-namespace

回滚操作中,其revision记录中的信息会发生变动,回滚操作会被当作一次滚到更新追加到历史记录中,而被回滚的条目则会被删除,需要注意的是,如果此前的滚动更新过程处于"暂停"状态,那么回滚操作就需要先将Pod模版的版本改回到之前的版本,然后“继续”更新,否则将一直处于暂停状态而无法回滚。

原文地址:https://www.cnblogs.com/cheyunhua/p/13395767.html