POD更新与回滚
1. replicaSet控制器应用更新
1.1 清单资源
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 apiVersion: v1 2 kind: Service 3 metadata: 4 name: re-demoapp 5 spec: 6 type: ClusterIP 7 selector: 8 app: re-demoapp 9 release: stable 10 ports: 11 - name: http 12 port: 80 13 targetPort: 80 14 protocol: TCP
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 kind: ReplicaSet 2 apiVersion: apps/v1 3 metadata: 4 name: replicaset-demo 5 spec: 6 replicas: 3 7 selector: 8 matchLabels: 9 app: re-demoapp 10 release: stable 11 template: 12 metadata: 13 labels: 14 app: re-demoapp 15 release: stable 16 spec: 17 containers: 18 - name: re-demoapp 19 image: harbor.myland.com/baseimages/demoapp:v1.0 20 ports: 21 - containerPort: 80 22 name: http 23 livenessProbe: 24 httpGet: 25 path: "/livez" 26 port: 80 27 initialDelaySeconds: 5 28 readinessProbe: 29 httpGet: 30 path: '/livez' 31 port: 80 32 initialDelaySeconds: 15
root@k8s-adm:/data/project/update/replicaSet# kubectl apply -f replicaset.yaml root@k8s-adm:/data/project/update/replicaSet# kubectl apply -f service-replicaset-demo.yaml
结果如下:其中test是手动创建用来测试页面的pod
1.2 单批次更新
一次替换所有的POD对象,也叫重建式更新(recreate),简单高效,但会导致相应服务在一段时间内完全不可可用(没有一个POD处于就绪状态),不能用于对可用性较高的生产环境中。执行过程为,修改资源清单文件image版本并apply,删除原POD,控制器根据新的模板创建新版本的POD。
- 修改replicaset.yaml:
1 image: harbor.myland.com/baseimages/demoapp:v1.1
- 应用并删除原版本的POD
1 root@k8s-adm:/data/project/update/replicaSet# kubectl apply -f replicaset.yaml 2 root@k8s-adm:/data/project/update/replicaSet# kubectl delete pod `kubectl get pods|grep replicaset|awk '{print $1}'` 3 root@k8s-adm:/data/project/update/replicaSet#kubectl get pods
在test pod中也可以看到,删除和使用新的模板创建pod的过程中,会出现服务不可用,待服务正常时,可以看到版本已由1.0切换到v1.1
1.3 滚动更新
- 如果担心单批次更新风险太大,可以一次删除一个原有的POD,待新POD就绪以后,再重复操作。直到所有POD更新完成。
- 也可以新建replicaset控制器,相同的app和release值,version更改为1.1,新控制器POD副本数开始设置为1(步长可以根据环境设置),同时将就控制器POD副本数减去相同的值,待新的POD处于就绪状态,继续设置旧新的POD副本数,直到所有的POD全由新控制起生成
- 蓝绿部署
滚动更新会存在两个不同版本的应用提供服务,且更新和回滚比较耗时,可以完全新建一个控制器,新增标签version:1.1,然后待新控制器创建的POD完全就绪后,再将service中selector中的version更改为:v1.1。这样流量就能完全切换到新POD。如果回滚也可以通过修改service上的version标签为1.0即可。
2. deployment控制器应用更新与回滚
deployment控制器默认使用滚动更新策略,也可以分批次滚动更新,多批次更新默认间隔标准为前一批次的POD对象均已就绪,deployment控制器提供3个用于控制滚动批次更新的字段,用于定义更新期间的POD总数的偏离值和速率
- spec.strategy.rollingUpdate.maxSurge: 升级期间存在的总POD数量最多可以超出期望值的个数或者百分比,例如设置为1,如果期望值为10,则在升级过程中最多可以有11个POD对象;
- spec.strategy.rollingUpdate.maxUnavailable:升级期间正常可用的POD数量最多不能低于期望值的个数或者百分比,例如设置为1,如果期望值为10,则在升级过程中至少要有9个POD处于就绪状态正常提供服务。
- spec.minReadySeconds: 表示新建的POD对象处于就绪状态后等待指定的时长,才能进行下一批次的更新。
deployment控制器可以保留一部分滚动更新历史中旧版本的ReplicaSet对象,可保留的历史版本数量由spec.revisionHistoryLimits属性进行定义,需要保存历史版本需要在创建deployment时增加 --record选项
2.1 清单资源
通过变量VERSION传入版本信息
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 kind: Deployment 2 apiVersion: apps/v1 3 metadata: 4 name: deployment-demo 5 spec: 6 replicas: 3 7 selector: 8 matchLabels: 9 app: de-demoapp 10 release: stable 11 template: 12 metadata: 13 labels: 14 app: de-demoapp 15 release: stable 16 spec: 17 containers: 18 - name: de-demoapp 19 image: harbor.myland.com/baseimages/demoapp:${VERSION} 20 ports: 21 - containerPort: 80 22 name: http 23 livenessProbe: 24 httpGet: 25 path: "/livez" 26 port: 80 27 initialDelaySeconds: 5 28 readinessProbe: 29 httpGet: 30 path: '/livez' 31 port: 80 32 initialDelaySeconds: 15
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 apiVersion: v1 2 kind: Service 3 metadata: 4 name: de-demoapp 5 spec: 6 type: ClusterIP 7 selector: 8 app: de-demoapp 9 release: stable 10 ports: 11 - name: http 12 port: 80 13 targetPort: 80 14 protocol: TCP
1 root@k8s-adm:/data/project/update/deployment#VERSION='v1.0' envsubst< deployment-demo.yaml | kubectl apply --record -f -
envsubst为一个shell命令,用于替换文件中的变量
2.2 滚动更新
- 升级到v1.1
1 #升级 2 root@k8s-adm:/data/project/update/deployment#VERSION='v1.1' envsubst< deployment-demo.yaml | kubectl apply --record -f - 3 #打印滚动更新过程中的信息 4 root@k8s-adm:/data/project/update/deployment#kubectl rollout status deployments/deployment-demo![]()
5 #监视更新过程中POD对象的变动过程 6 root@k8s-adm:/data/project/update/deployment#kubectl get deployments/deployment-demo -w
7 root@k8s-adm:/data/project/update/deployment# kubectl get replicaset -l app=de-demoapp,release=stable
#可以看到存在2个replicaset控制器,旧的控制器无就绪的POD
![](https://img2020.cnblogs.com/blog/2511773/202111/2511773-20211123164643841-478412811.png)
测试,显示版本为1.1
- 回退至v1.0
查看deployment资源的修订(apply)历史
1 root@k8s-adm:/data/project/update/deployment# kubectl rollout history deployments/deployment-demo
回退
1 root@k8s-adm:/data/project/update/deployment# kubectl rollout undo deployments/deployment-demo
验证:
回退也可以在kubectl rollout undo --to-reversion id ,回退至指定版本,如
2.3 金丝雀发布
基于deployment的金丝雀发布,实现方式为分批次发布,当第一批次发布完成后,立即暂停发布,观察进入新POD的访问情况,如确定完全正常,则继续批次的发布
分批设置:MaxSurge: 1,maxUnavailable: 0,一批次为1个POD更新,更新期间一直至少有3个POD对外正常提供服务
root@k8s-adm:/data/project/update/deployment# kubectl patch deployment/deployment-demo -p '{"spec:": {"strategy":{"rollingUpdate":{"maxSurge":1,"maxUnavailable":0}}}}' root@k8s-adm:/data/project/update/deployment# kubectl patch deployment/deployment-demo -p '{"spec":{"minReadySeconds":30}}'
升级为1.2
root@k8s-adm:/data/project/update/deployment# VERSION='v1.2' envsubst < deployment-demo.yaml | kubectl apply --record -f - && kubectl rollout pause deployments/deployment-demo
可以看到,有一个新的replicaset控制器生成,且测试可以看到有4个POD,一个POD为v1.2
如果确定v1.2版本完全正常,可以执行剩余的POD更新
root@k8s-adm:/data/project/update/deployment# kubectl rollout resume deployments/deployment-demo
可以看到全部切换到v1.2
本实例来源:kubernetes进阶实战第二版 马永亮 著