k8s--(8)Deployment:应用升级
容器有个属性imagePullPolicy,默认是IfNotPresent,也就是说,当本节点有这个tag的镜像时,不会拉新的镜像,所以只改镜像内容并推送到镜像仓库是没用的,当然,将imagePullPolicy改为Always即可。(2)所有的请求都是由kubectl客户端发送给API服务器的,也就是说伸缩请求是由kubectl客户端执行的,不是k8s master,这带来的问题就是升级中间出现
一、旧的升级方式
1、手动升级
(1)修改RC的模板文件,改pod的镜像,删除旧pod,自动拉起新pod (RC的标签选择器控制)
缺点:中间会有短暂的服务不可用时间
(2)创建新RC,service的标签选择器指向新pod
kubectl set selector
再删除旧pod
滚动升级:这个图是一次性新建3个,然后一次性删除3个,也可以通过逐步修改RC模板文件中副本数,一个一个切换pod
2、自动滚动升级
保证应用可以多版本运行,比如数据库字段改了,旧版本不能用,那就不要滚动升级了,删了重新部署吧
kubectl rolling-update kubia-v1 kubia-v2 --image=luksa/kubia:v2
kubia-v1和kubia-v2都是RC名称
过程:
(1)开始滚动升级后的系统状态
(2)新RC的模板文件,注意selector
(3)旧RC的模板文件
kubectl describe rc kubia-v1
Name: kubia-v1
Namespace: default
Image(s): luksa/kubia:v1
Selector: app=kubia,deployment=3ddd307.....
(4)旧pod
每个旧pod都增加了一个标签,deployment=3ddd307....
(5)开始伸缩
=======》》
为什么rolling-update过时了?
(1)这个过程会修改旧pod和旧RC的标签,不符合创建时的预期;
(2)所有的请求都是由kubectl客户端发送给API服务器的,也就是说伸缩请求是由kubectl客户端执行的,不是k8s master,这带来的问题就是升级中间出现问题,升级进程就会中断,pod和RC的状态处于中间状态。
避免镜像内容更新了,但是镜像tag没变
容器有个属性imagePullPolicy,默认是IfNotPresent,也就是说,当本节点有这个tag的镜像时,不会拉新的镜像,所以只改镜像内容并推送到镜像仓库是没用的,当然,将imagePullPolicy改为Always即可
二、新的升级方式
1、介绍Deployment
高阶资源,控制的是RS
在rolling-update过程中,会创建第二个RC,这里Deployment的作用就是自动管理多个RS,并且升级过程不是kubectl客户端发起的了,而是由运行在k8s上的一个控制器处理完成
2、创建Deployment
Deployment本身可以管理多版本pod,所以其metadata不用写版本号
3、升级
(1)升级策略
RollingUpdate:滚动
Recreate:删旧pod重建
(2)触发升级:
只需要修改Deployment模板文件即可,修改方式:
kubectl patch deployment kubia -p '{"spec": {"minReadySecond": 10}}' //设置了升级速度
kubectl set image deployment kubia nodejs=luksa/kubia:v2 //修改镜像到v2
kubectl edit //打开模板编辑
kubectl replace //替换新模板
kubectl apply -f //要修改的属性较多,新写一个模板yaml,把要修改或增加的属性都放进去,不想改的不用写,用apply命令合并新旧模板
(3)升级过程
kubectl get po
NAME READY STATUS RESTARTS AGE
kubia2-7b778df8b9-8dz8p 1/1 Running 0 112s
kubia2-7b778df8b9-kcxk8 1/1 Running 0 112s
kubia2-7b778df8b9-lhlfp 1/1 Running 0 112s
kubectl get replicasets
NAME DESIRED CURRENT READY AGE
kubia2-7b778df8b9 3 3 3 2m32s
看到pod和RS后面都有一串相同的数字,这个表示的就是deployment模板的hash,升级后,这个hash肯定是不一样的
观察升级过程:
kubectl rollout status deployment kubia
4、回滚
注意:v1版本的RS没删哦,就是为了升级出问题后回滚
(1)回滚到上次
kubectl rollout undo deployment kubia
如果是在升级过程中执行undo,则滚动升级立即停止,回到旧pod
(2)回滚到指定版本
kubectl rollout undo deployment kubia --to-revision=1
(3)查看版本历史
kubectl rollout history deployment kubia
REVISION CHANGE-CAUSE
2 升级原因。。。
3 升级原因。。。
创建delployment时,加上--record参数才会有CHANGE-CAUSE
如果保留版本太多,RS管理会很混乱,所以默认只会保留2个版本,如果想改,可以设置参数revisionHistoryLimit
5、控制滚动升级速率
两个参数可以控制:
spec:
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
type: RollingUpdate
maxSurge和maxUnavaiable都可以是百分比,也可以是数值,是百分比时四舍五入
maxSurge表示除了期望pod副本数,最多可以超出的pod数,总pod数 = replicas + maxSurge,或 总pod数 = replicas * (1+ maxSurge)
maxUnavailable表示相对于期望pod副本数,允许有多少个pod处于不可用状态,注意是相对于期望值不是实际值,可用pod数 >= replicas - maxUnavailable ,或 可用pod数 >= replicas *(1 - maxUnavailable)
默认值都是25%
下面是一个例子,两个参数都是1,replica = 3
6、暂停滚动升级
本来3个pod,现在想验证新版本的功能,只升级一个pod,保留2个旧版本的pod
kubectl set image deployment kubia nodejs=luksa/kubia:v2
// 立马(几秒内)输入:
kubectl rollout pause deployment kubia
测试新版本没问题了,恢复升级过程:
kubectl rollout resume deployment kubia
暂停期间,undo无效
7、自动阻止出错版本的滚动升级
设置变量minReadySeconds,它表示pod就绪后必须继续成功运行多少秒,才能将其视为可用,并继续升级,所以也可以用来控制升级速率
那判断pod就绪的方式就是设置就绪探针
正常就绪探针重试多次,一次成功后就会视为pod可用,但是设置了minReadySeconds就可以在一次探针成功后,继续执行探针多少秒,并保证每次都要成功,最终才将pod视为可用
升级默认时长10分钟,10分钟升级未完成视为升级失败,可以rollout undo回滚,10分钟的时间是可以修改的,配置参数Deployment.spec.progressDeadlineSeconds
更多推荐
所有评论(0)