一、旧的升级方式

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

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐