目录
- 前言
- 一、升级
- 二、回滚
前言
Rolling Update
即滚动更新,先更新一部分副本,成功后再继续更新更多副本,最终完成所有的副本更新。前面说到动态伸缩容并不会触发上线,仅当 Deployment Pod 模板(即 .spec.template
)发生改变时才会触发上线。且上线实现了滚动特点,其好处就是无需停服的状态下即可完成服务升级,从而保证了业务的连续性。
接下来以更新 Nginx 容器镜像的版本号为例进行演示与验证。
一、升级
刚刚把副本数从 2 ——> 3
,执行 kubectl apply -f nginx.yml
启动服务,可看到并没有触发上线/滚动更新:
接着修改镜像的版本号,从 1.20.0 ——> 1.21.4
:
再次启动服务,看看镜像版本是否已更新:
看看 Pod 是否正常运行:
小结:可看到,原来 ReplicaSet nginx-6b6cf7569
的三个 nginx:1.20.0 Pod
已经被ReplicaSet nginx-7bfd89cc74
的三个nginx:1.21.4 Pod
替换了。
再来看看 deployment
的详情,看看具实现过程:
其流程就是:
ReplicaSet nginx-7bfd89cc74
新增一个 Pod,总数为 1;ReplicaSet nginx-6b6cf7569
减少一个 Pod,总数为 2(也就是说至少还有两个 Pod 是正常对外提供服务的);ReplicaSet nginx-7bfd89cc74
新增一个 Pod,总数为 2;ReplicaSet nginx-6b6cf7569
减少一个 Pod,总数为 2(也就是说至少还有一个 Pod 是正常对外提供服务的);ReplicaSet nginx-7bfd89cc74
新增一个 Pod,总数为 3;ReplicaSet nginx-6b6cf7569
减少一个 Pod,总数为 0(此时ReplicaSet nginx-6b6cf7569
已经没有 Pod 了)。
可看到,其更新方式是以滚动的形式实现的,从而保证了业务的连续性。
二、回滚
K8s 在每次 kubectl apply
更新应用时,都会记录当前的配置,比如我原本的 Nginx 镜像为 1.20.0,那这个 1.20.0 及其其他信息都会被记录下来,其目的就是方便我们上线失败后可以回到正常的那个镜像版本。
默认情况下,K8s 只会保留近 10 个的 revision
,我们可以在 Deployment 配置文件中使用 revisionHistoryLimit
字段来指定 revision 的保留数量。
kubectl edit deployment nginx
看看可回滚的历史版本:
kubectl rollout history deployment nginx
虽然可看到有 2、3、4 这三个可会退的版本,但是 CHANGE-CAUSE
这个字段均为 <none>
,这就不太利于我们进行版本会退,想要显示CHANGE-CAUSE
值,需要在 kubectl apply
时添加 --record
参数。所以这里重新在写两个 Deployment 的 YML 文件再来启动服务。
-
nginx-a.yml
-
nginx-b.yml
分别进行 kubectl apply
更新应用:
kubectl apply -f nginx-a.yml --record
kubectl apply -f nginx-b.yml --record
这样就能看到你是指定的哪个 YAML 文件启动的,但是这个 --record
已经被弃用了,除了这种方法之外,我们可以通过指定具体的 revision 编号来查看其详细信息,这样你就可以根据实际情况会退到具体版本,比如我们查看 revision 为 4 的版本信息。
kubectl rollout history deployment nginx --revision=4
版本会退验证:
-
先看看当前的 Pod 的 image 版本
kubectl get deployment nginx -o wide
-
比如就回到我们 revision 为 4 的版本
kubectl rollout undo deployment nginx --to-revision=4
-
会退完成,再次验证当前 image 镜像
kubectl get deployment nginx -o wide
可看到版本会退成功!
以上就是 K8s Pod 版本升级/回滚的详细流程。