K8SKubernetes 中滚动发布由浅入深实战

目录

  • 一、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-dep
  name: ngx-dep
  
spec:
  minReadySeconds: 20
  replicas: 4
  selector:
    matchLabels:
      app: ngx-dep
      
  template:
    metadata:
      labels:
        app: ngx-dep
    spec:
      containers:
      - image: nginx:1.24-alpine
        name: nginx

2.2.2 执行命令创建 Deployment 资源对象

在终端窗口中执行命令kubectl apply -f ngx-dep-v1.yaml:

在这里插入图片描述
使用kubectl get podkubectl 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-dep
  name: ngx-dep
  annotations:
  	kubernetes.io/change-cause: 升级Nginx的版本到1.27
  
spec:
  minReadySeconds: 20
  replicas: 4
  selector:
    matchLabels:
      app: ngx-dep
      
  template:
    metadata:
      labels:
        app: ngx-dep
    spec:
      containers:
      - image: nginx:1.27-alpine
        name: nginx

然后执行kubectl apply -f ngx-dep-v3.yaml 命令进行升级。然后我们使用kubectl rollout history 命令再来查看版本记录,可以看到我们记录的具体的变更原因了。

在这里插入图片描述