目录
- 一、Kubernetes中滚动发布的需求背景
- 1.1 滚动发布
- 1.2 滚动发布、蓝绿发布、金丝雀发布的区别
- 二、Kubernetes中实现滚动发布
- 2.1 定义Kubernetes中的版本
- 2.2 创建 `Deployment` 资源对象
- 2.2.1 在 Yaml 中定义 `Deployment` 资源对象
- 2.2.2 执行命令创建 `Deployment` 资源对象
- 三、Kubernetes中滚动发布的管理
- 3.1 查看 `Deployment` 资源对象对应Pod在滚动发布中的状态
- 3.1.1 查看滚动发布状态
- 3.1.2 查看滚动发布历史
- 3.2 版本回退
- 3.2.1 回滚掉最新的滚动发布
- 3.2.2 回滚至指定版本
- 3.3 增加版本说明
一、Kubernetes中滚动发布的需求背景
1.1 滚动发布
- Kubernetes及其强大的特点之一就是超大规模集群应用的自动化部署,这其中包括了应用的扩容、缩容及其自适应扩缩容(HPA、VPA)。
- 在滚动发布的过程中,Kubernetes会对要进行升级的应用所属Pod进行逐个的替换,直至将所有的Pod都替换为新版本的Pod。整个过程中新老版本的Pod都处于在线、提供服务的状态。
1.2 滚动发布、蓝绿发布、金丝雀发布的区别
-
蓝绿发布:蓝绿发布是存在2个系统,一个是正在提供服务的系统,标记为绿色,一个是准备发布的带有新功能的系统,标记为蓝色。蓝色系统用来做发布前的测试,测试过程中发现的任何问题都可以直接在蓝色系统上直接更改,不干扰用户正在使用的系统。蓝色系统经过充分、有效的测试、验证后,被证明可以安全上线后,会将所有的用户切到蓝色系统上。
-
金丝雀发布(灰度发布):金丝雀发布是只有一个系统,对该系统中的应用实例进行逐步替换。例如系统中有100个服务实例,我们可以先替换掉其中的10个实例,然后系统给这10个实例切分流量,通过一段时间的线上流量的测试,如果发现这10个实例在功能及体验上没有任何问题,那我们继续扩大新实例的比例,并给新版本的实例切分更多的流量,直至全部实例替换完成。
- 滚动发布:滚动发布只有一个系统,虽然也是逐个替换掉系统中的服务实例,但是新老实例会同时在系统中提供服务,不存在特意的流量切分。不过,在Kubernetes集群中,可以利用标签选择器实现金丝雀发布(灰度发布)的效果。
二、Kubernetes中实现滚动发布
2.1 定义Kubernetes中的版本
- 我们常说的版本可能就是跟代码挂钩,就是代码或者配置发生变动就产生一个新的版本,Kubernetes中将在Yaml中对Pod的定义定义为一个版本,可参考文章Kubernetes 中 Pod 定义与操作实践快速了解Pod定义。
- K8S中版本定义范围。我们在Pod模版中定义了Pod使用的镜像及其版本、镜像拉取策略、环境变量参数等。定义Pod的Yaml内容的变化都会产生一个新的版本。对Pod的定义不光是通过创建Pod资源对象直接创建,我们在Deployment 资源对象或者 DaemonSet 资源对象中的
template
字段中定义的Pod 的变化也会导致Pod的版本变化。 - 版本号。Kubernetes中的版本号一般是对Deployment 资源对象或者 DaemonSet 资源对象中的
template
字段的定义部分进行哈希,计算哈希值,取哈希值作为版本号。
2.2 创建 Deployment
资源对象
2.2.1 在 Yaml 中定义 Deployment
资源对象
Yaml 内容如下:
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: ngx-depname: ngx-depspec:minReadySeconds: 20replicas: 4selector:matchLabels:app: ngx-deptemplate:metadata:labels:app: ngx-depspec:containers:- image: nginx:1.24-alpinename: nginx
2.2.2 执行命令创建 Deployment
资源对象
在终端窗口中执行命令kubectl apply -f ngx-dep-v1.yaml
:
使用kubectl get pod
、 kubectl get deploy
或者 kubectl describe deploy
命令查看创建出的资源对象的状态。
三、Kubernetes中滚动发布的管理
3.1 查看 Deployment
资源对象对应Pod在滚动发布中的状态
3.1.1 查看滚动发布状态
执行命令 kubectl rollout status deploy ngx-dep
,查看deploy资源名为ngx-dep
的状态:
终端会不断输出当前滚动发布的进程状态,直接滚动发布完成,完成时该命令结束会输出deployment "xxxxxx" successfully rolled out
的字样。
3.1.2 查看滚动发布历史
执行命令 kubectl rollout history deploy ngx-dep
,查看 deploy资源名为ngx-dep
的滚动发布记录:
查到滚动发布记录之后,我们可以通过--revision
参数来具体指定某个具体的版本,来查看该发布相对于上一个版本的变更,例如执行 kubectl rollout history deploy --revision=2
:
3.2 版本回退
3.2.1 回滚掉最新的滚动发布
使用 kubectl rollout undo deploy ngx-dep
回滚掉名为 ngx-dep
的 deploy 资源对象最新的滚动发布:
我们使用kubectl rollout history
命令查看发布记录可以看到多出一个记录4,因为回滚也会产生一个新的发布记录。
3.2.2 回滚至指定版本
我们使用kubectl rollout history
命令先看下当前有哪些版本可用:
我们使用kubectl rollout history deploy --revision
命令再看下版本3和版本5的内容:
可以看到,这2个版本的差别仅在与所使用的Nginx 镜像的版本号不同,现在使用 kubectl rollout history
命令的--to-revision
选项回退到我们指定的版本3(1.24-alpine):
可以看到提示回滚成功了。我们看下当前最新版本Pod的NGINX的版本号:
确实是我们预期的1.24-alpine
。
3.3 增加版本说明
我们需要在Deployment 资源对象的metadata字段下添加annotations 字段,就可以为查询滚动发布记录的CHANGE-CAUSE
处添加对应说明了。此处对文件 ngx-dep-v3.yaml
进行更改如下:
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: ngx-depname: ngx-depannotations:kubernetes.io/change-cause: 升级Nginx的版本到1.27spec:minReadySeconds: 20replicas: 4selector:matchLabels:app: ngx-deptemplate:metadata:labels:app: ngx-depspec:containers:- image: nginx:1.27-alpinename: nginx
然后执行kubectl apply -f ngx-dep-v3.yaml
命令进行升级。然后我们使用kubectl rollout history
命令再来查看版本记录,可以看到我们记录的具体的变更原因了。