OpenKruise社区Rollouts组件重磅更新:即插即用的蓝绿发布能力

本文涉及的产品
函数计算FC,每月15万CU 3个月
简介: Kruise Rollouts作为OpenKruise社区提供的旁路组件,其能对原始工作负载进行增强。蓝绿发布是Kruise Rollouts在0.6.0版本中新引入的能力。

【阅读原文】戳:OpenKruise社区Rollouts组件重磅更新:即插即用的蓝绿发布能力

Kruise Rollouts是OpenKruise社区提供的一个旁路组件,它能够对原始工作负载(Deployment、StatefulSet、CloneSet等)进行增强,使其具备分批发布、金丝雀发布、蓝绿发布等高级能力。蓝绿发布是Kruise Rollouts在0.6.0版本中新引入的能力。目前,Rollouts能够为Deployment以及Openkruise社区的 CloneSet两种工作负载添加蓝绿发布能力。

 

 

 

 

一. 蓝绿发布介绍

 

 

 

蓝绿发布是一种降低新版本上线风险的部署策略,通过维护两个相同的生产环境来实现。其中,一个环境为活跃状态(蓝色环境),对外提供服务;另一个则处于待命状态(绿色环境)。

 

发布时,蓝色环境继续提供服务的同时,在绿色环境中部署新版本。部署完成后,可以通过切换路由或负载均衡器将流量在两个环境间进行切换,方便验证与回滚。

 

下图直观地对比了蓝绿发布与金丝雀发布的流程:

 

 

 

 

 

二. Kruise Rollouts蓝绿发布能力介绍

 

 

 

2.1. 通过 Kruise Rollouts 进行蓝绿发布

 

本节将通过一个案例展示如何使用Kruise Rollouts 便捷地一站式管理Deployment的蓝绿发布。在本节的例子中,将当前线上的稳定版本称为“蓝色环境”,新发布的版本称为“绿色环境”。

 

2.1.1. 环境准备

 

本案例使用的环境如下:

1. Kubernetes版本:v1.28.7

2. Ingress-NGINX Controller版本:1.12.0

3. Kruise Rollouts版本:v0.6.0

 

2.1.2. 部署应用

 

通过以下的Yaml文件在K8s集群中部署了Echoserver应用:

 

1. 一个用于部署五个Echoserver副本的Deployment。

 

2. 相应的Service与Ingress用于暴露服务。

 

 

apiVersion: apps/v1
kind: Deployment
metadata:
  name: echoserver
  labels:
    app: echoserver
spec:
  replicas: 5
  selector:
    matchLabels:
      app: echoserver
  template:
    metadata:
      labels:
        app: echoserver
    spec:
      hostname: blue # 稳定环境为蓝色环境
      containers:
        ...
---
apiVersion: v1
kind: Service
metadata:
  name: echoserver-service
spec:
  ...
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: echoserver-ingress
spec:
    ...

 

2.1.3. 声明发布策略

 

在应用的同一个Namespace中,创建以下的Rollout资源,为其声明一条蓝绿发布策略。在发布时,Kruise Rollouts会依次执行该策略中包含的三个步骤,并在步骤之间暂停以供用户进行验证。

 

 

apiVersion: rollouts.kruise.io/v1beta1
kind: Rollout
metadata:
  name: rollouts-demo
spec:
  workloadRef: # 通过 workloadRef 指定应用工作负载
    apiVersion: apps/v1
    kind: Deployment
    name: echoserver
  strategy:
    blueGreen: # 通过 blueGreen 配置蓝绿发布策略
      steps:
      - replicas: 100% # 第一步:拉起 100% 副本的绿色环境
        traffic: 0%
      - replicas: 100% # 第二步:将 10% 的流量导入绿色环境,灰度验证
        traffic: 10%
      - replicas: 100% # 第三步:将所有流量导入绿色环境,推平
        traffic:  100%
      trafficRoutings: # 通过 trafficRoutings 指定应用的网络资源
      - service: echoserver-service
        ingress:
          classType: nginx
          name: echoserver-ingress

 

 

通过kubectl命令查看Rollout资源状态。在没有发布任务时,Rollout处于Completed状态。

 

 

$ kubectl get rollout
NAME            STATUS    CANARY_STEP   CANARY_STATE   MESSAGE                            AGE
rollouts-demo   Healthy   3             Completed      workload deployment is completed   8s

 

2.1.4. 更新应用

 

修改Deployment的配置,将hostname从blue改为green,进行一次更新。

 

apiVersion: apps/v1
kind: Deployment
metadata:
  name: echoserver
  labels:
    app: echoserver
spec:
  ...
  template:
    ...
    spec:
      hostname: green # 拟更新到绿色环境
    ...

 

在更新Deployment后,Kruise Rollouts将会启动蓝绿发布流程,并自动执行第一步。当Rollout资源的CANARY_STATE状态进入StepPaused后,意味着第一步执行完毕,此时绿色环境已被拉起,集群中同时存在两个版本各五个副本。

 

 

# Rollout 状态流转
$ kubectl get rollout
NAME            STATUS        CANARY_STEP   CANARY_STATE   MESSAGE                                                        AGE
rollouts-demo   Progressing   1             StepUpgrade    Rollout is in step(1/3), and upgrade workload to new version   33s
$ kubectl get rollout
NAME            STATUS        CANARY_STEP   CANARY_STATE         MESSAGE                                                        AGE
rollouts-demo   Progressing   1             StepTrafficRouting   Rollout is in step(1/3), and upgrade workload to new version   38s
$ kubectl get rollout
NAME            STATUS        CANARY_STEP   CANARY_STATE   MESSAGE                                                                         AGE
rollouts-demo   Progressing   1             StepPaused     Rollout is in step(1/3), and you need manually confirm to enter the next step   41s
# Pod 统计
+-----------------------------+----------+
|             name            | hostname |
+-----------------------------+----------+
| echoserver-696b76ddd8-9mpbb |   blue   |
| echoserver-696b76ddd8-b7qqb |   blue   |
| echoserver-696b76ddd8-nbdc7 |   blue   |
| echoserver-696b76ddd8-t4zgb |   blue   |
| echoserver-696b76ddd8-vmd2z |   blue   |
| echoserver-7d4744f99c-5mcb5 |  green   |
| echoserver-7d4744f99c-8tgfc |  green   |
| echoserver-7d4744f99c-bnfhc |  green   |
| echoserver-7d4744f99c-m7n9k |  green   |
| echoserver-7d4744f99c-x52mx |  green   |
+-----------------------------+----------+

 

 

此时反复请求网关,可以发现虽然绿色环境已被拉起,但是所有请求依然被蓝色环境所响应。

 

 

Request served by blue
Request served by blue
Request served by blue
Request served by blue
Request served by blue
Request served by blue
Request served by blue
Request served by blue
Request served by blue
Request served by blue

 

 

在发布暂停时,可以通过以下两种方式进入下一步:

 

 

$ kubectl patch rollout rollouts-demo --type merge --subresource status -p "{\"status\":{\"blueGreenStatus\":{\"currentStepState\": \"StepReady\"}}}"

 

 

2. 通过Kruise命令行工具继续发布。

 

 

$ kubectl-kruise rollout approve rollouts/rollouts-demo

 


继续发布,开始第二步的灰度验证阶段。当Rollout资源再次进入StepPaused状态后,再次尝试请求,发现大概每十次就会有一次请求到绿色环境,说明第二步成功导入了10%的流量。

 

 

Request served by blue
Request served by blue
Request served by blue
Request served by blue
Request served by blue
Request served by blue
Request served by green
Request served by blue
Request served by blue
Request served by blue

 

 

验证无误后,再次继续发布进入第三步的推平阶段。可以看到所有流量都已经被导入了绿色环境。此时可以进行端到端测试、压力测试等最终验证。

 

 

Request served by green
Request served by green
Request served by green
Request served by green
Request served by green
Request served by green
Request served by green
Request served by green
Request served by green
Request served by green

 

 

2.1.5. 快速回滚

 

如果应用在灰度验证阶段或推平后验证不通过,由于蓝色环境依旧保留,可以通过切流量的方式进行快速回滚。Kruise Rollouts具备在发布的任何阶段之间任意跳转的能力,因而可以在不变更配置的情况下快速回滚,降低后续发布运维的复杂性。

 

在这个案例中,如果在任何时候发现绿色环境不符合预期,可以通过字改Rollout资源的nextStepIndex状态回到第一步,即蓝色环境承载所有流量的状态。这个操作可以通过以下命令实现:

 

 

kubectl patch rollout rollouts-demo --type merge --subresource status -p "{\"status\":{\"blueGreenStatus\":{\"nextStepIndex\": 1}}}"

 

 

⚠️ 注意:Kruise Rollouts的编号是从1开始的,并非0。

 

如果经排查,发现是因为外部因素导致绿色环境不符合预期,那么在排除问题后可以继续发布:可以按照正常发布流程继续依次执行第二步、第三步,或是直接跳转到第三步进行推平。

 

而如果排查结论是绿色环境的变更本身包含Bug,那么可以对Deployment进行回滚操作,将其改回原先的配置:

 

 

apiVersion: apps/v1
kind: Deployment
metadata:
  name: echoserver
  labels:
    app: echoserver
spec:
  ...
  template:
    ...
    spec:
      hostname: blue # 绿色环境有问题,放弃发布,回滚到蓝色
    ...

 

 

在蓝绿发布过程中对Deployment的Pod template进行的变更,除非改回发布前的配置(回滚),否则都不会生效。Kruise Rollouts会提示所有变更都需要先回滚再重新发布。

 

此时查看集群资源,发现回到了最初应用刚部署的状态,即只存在五个蓝色环境副本,Rollout资源则提示发布取消:

 

 

$ kubectl get rollout
NAME            STATUS    CANARY_STEP   CANARY_STATE   MESSAGE                                  AGE
rollouts-demo   Healthy   1             StepReady      Rollout progressing has been cancelled   20m
# Pod 统计
+-----------------------------+----------+
|             name            | hostname |
+-----------------------------+----------+
| echoserver-696b76ddd8-9mpbb |   blue   |
| echoserver-696b76ddd8-b7qqb |   blue   |
| echoserver-696b76ddd8-nbdc7 |   blue   |
| echoserver-696b76ddd8-t4zgb |   blue   |
| echoserver-696b76ddd8-vmd2z |   blue   |
+-----------------------------+----------+

 

 

2.1.6. 发布完成

 

如果在第三步推平后,验证绿色环境符合预期,那么就可以再进行一次继续发布动作,完成这次发布。在发布完成后,蓝色环境将被删除,只保留绿色环境

 

 

$ kubectl patch rollout rollouts-demo --type merge --subresource status -p "{\"status\":{\"blueGreenStatus\":{\"currentStepState\": \"StepReady\"}}}"
rollout.rollouts.kruise.io/rollouts-demo patched
$ kubectl get rollout
NAME            STATUS    CANARY_STEP   CANARY_STATE   MESSAGE                                  AGE
rollouts-demo   Healthy   3             Completed      Rollout progressing has been completed   31m
# Pod 统计
+-----------------------------+----------+
|             name            | hostname |
+-----------------------------+----------+
| echoserver-7d4744f99c-8wf67 |  green   |
| echoserver-7d4744f99c-ct55j |  green   |
| echoserver-7d4744f99c-jzwmn |  green   |
| echoserver-7d4744f99c-lm2vs |  green   |
| echoserver-7d4744f99c-zw4gh |  green   |
+-----------------------------+----------+

 

 

2.1.7. 小结

 

本节通过案例介绍了Kruise Rollout的蓝绿发布能力,包括拉起环境、流量切换、步骤跳转、回滚等。用户无需对工作负载进行任何改造即可便捷地对应用进行蓝绿发布。

 

 

2.2. Kruise Rollouts蓝绿发布的原理

 

本节将通过进一步拆解3.1的示例中Kruise Rollouts进行的操作,对其蓝绿发布能力的原理进行介绍。

 

2.2.1. 副本管理

 

Kruise Rollouts通过将工作负载保持在滚动发布中的一个特殊的状态,使得两个环境得以暂时稳定共存。对于Deployment的更新,Kruise Rollouts会进行以下操作:

 

1. 将spec.minReadySeconds与spec.progressDeadlineSeconds设置为无穷大(具体值为2^31-1)。这样,Deployment更新永远都不会被认为失败或成功。通过将 Deployment 一直保持在更新中状态,蓝色环境绿色环境得以共存。

 

2. 将spec.strategy.rollingUpdate.maxSurge设置为适当的值,这个值来自于Rollout步骤中配置的副本数(百分比或绝对值)。这个值配置了Deployment在更新时允许创建的额外Pod 数量,也就是绿色环境的副本数量。

 

下图的对比是Kruise Rollouts对Deployment操作的参考:

 

 

2.2.2. 流量管理

 

为了管理两个环境之间的流量,Kruise Rollouts会分别操作应用的Service、Ingress等网络资源。

 

对于Service资源,Kruise Rollouts会创建一个与原始的Service(echoserver-service)内容完全一致的拷贝(命名为echoserver-service-canary),并分别给两个Service加上pod-template-hash选择器,使原始Service选中蓝色环境拷贝Service选中绿色环境。两个Service的差别可参考下图:

 

 

对于ingress-NGINX的入口流量,Kruise Rollouts会根据应用的Ingress拷贝一个新的Ingress资源,并根据发布步骤中配置的流量比例打上相应的流量标签。两个Ingress的差别可参考下图:

 

⚠️ :Kruise Rollouts集成了ingress-NGINX、ALB、Higress等Ingress Controller的流量控制规则,同时支持Gateway API与Istio。对于不同类型的入口资源类型,有不同的操作实现。此处仅供参考。

 

 

2.2.3. 资源清理

 

一次发布可能由许多种因素导致停止:比如发布成功、回滚、删除Rollout、禁用Rollout等。在发布停止后,Kruise Rollouts会执行以下操作对管理的资源进行清理。

 

⚠️:为了防止流量损失与泄漏,在不同的情况下,以下步骤的顺序可能不同

 

1. 恢复原始Service资源的选择器

2. 调整入口流量策略指向正确的目标

3. 恢复对工作负载的调整,根据具体情况删除蓝色环境绿色环境的副本

 

因此,发布前后,集群中的资源是不变的,这也体现了Kruise Rollouts的旁路特性:不工作时对应用没有干涉。

 

2.2.4. 小结

 

本节通过拆解Kruise Rollouts针对ingress-NGINX + Deployment场景的工作流程,介绍了其蓝绿发布的基本原理。需要注意的是,针对不同流量入口与工作负载的组合,其操作的细节会有所不同,碍于篇幅所限,不再展开。

 

 

2.3. Kruise Rollouts与其他开源发布方案的对比

 

Argo Rollouts与Flux Flagger是比较流行的两个开源发布方案。本节将从设计理念、灵活性、迁移成本等方面将Kruise Rollouts与这两种方案进行对比,介绍更加适合使用Kruise Rolouts的场景。

 

2.3.1. 与Argo Rollouts对比

 

Argo Rollouts通过一个新的工作负载(也叫 Rollout)同时指定发布策略和Pod模板,并通过多个ReplicaSet来管理Pod。下面是Argo社区官方的通过Argo Rollouts进行蓝绿发布的例子:

 

 

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: rollout-bluegreen
spec:
  replicas: 2
  selector:
    matchLabels:
      app: rollout-bluegreen
  template:
    ...
  strategy:
    blueGreen: 
      activeService: rollout-bluegreen-active
      previewService: rollout-bluegreen-preview
      autoPromotionEnabled: false
---
kind: Service
apiVersion: v1
metadata:
  name: rollout-bluegreen-active
spec:
  selector:
    app: rollout-bluegreen
  ports:
    ...
---
kind: Service
apiVersion: v1
metadata:
  name: rollout-bluegreen-preview
spec:
  selector:
    app: rollout-bluegreen
  ports:
    ...

 

 

很显然地,要使用Argo Rollouts,需要对现有应用做较大的改造:

 

1. 需要从原先的Deployment、StatefulSet、CloneSet等工作负载迁移到Argo Rollout,对于企业的发布PaaS而言,需要做新的工作负载的对接工作

 

2. 需要手动维护两个Service

 

因而,Argo Rollouts具有相当高的迁移成本,并且会在技术上收到较大的限制,降低系统的灵活性,对上层PaaS的要求也较高。

 

额外地,Kruise Rollouts还拥有Argo Rollouts所不具备的热插拔能力:用户可以随时(即使在发布的任意过程中)新建、修改、删除Kruise Rollout资源,从而快速地对发布策略进行修改。Kruise Rollouts对这些异常场景的特别的优化,能够保证随意插拔Rollout资源的同时,应用的流量无损、副本满足预期。

 

所以,如果现有应用依赖于CloneSet等工作负载的高级能力、PaaS改造成本高、或是对发布策略的灵活性较高的要求,更适合使用Kruise Rollouts进行蓝绿发布。

 

2.3.2. 与Flux Flagger对比

 

Kruise Rollouts与Flux Flagger都是以旁路组件的形式进行工作,它们的主要区别在于对工作负载的管理上。

 

 

上图是Flux Flagger的蓝绿发布原理。Flagger会在发布时,创建一个新的工作负载运行新版本。在发布完毕后,Flagger会通过滚动更新的方式将原始工作负载下的Pod升级到新版本,再删除临时新建的工作负载。与此相对的,Kruise Rollouts采用下图的单负载模式,即通过在原始工作负载中扩容额外的副本,再删除老副本的形式完成环境切换。

 

Flux Flagger的蓝绿发布原理其实是与Kruise Rollouts的金丝雀发布相同的。

 

 

Flux Flagger由于存在两个工作负载,因而会对有其他针对工作负载组件存在的场景具有影响。比如,使用OpenKruise社区的WorkloadSpread组件对Pod进行分组打散,或使用VPA组件对Pod进行自动变配等场景下,都需要通过WorkloadRef来指定目标工作负载,因而这些组件无法对新环境生效。

 

同时,Flagger还存在另一个问题,即最终提供服务的所谓“绿色环境”与当初验证的绿色环境并不是同一个。这对无状态应用没有影响,但是如果应用是游戏服务器等有状态应用,或对Pod进行了IP绑定、云盘绑定等操作,就可能会出现问题。

 

因此,对于使用了其他Workload敏感的组件,或是要保证绿色环境Pod不可变的场景,更适合使用Kruise Rollouts进行蓝绿发布。

 

 

 

 

三. ACS Serverless集群在蓝绿发布场景下的优势

 

 

 

蓝绿发布最大的问题在于其大量的资源消耗。具体地对应到K8s中,存在以下局限性:

 

1. 集群中至少需要额外预留一个环境的节点资源用于拉起新环境。对于大型应用(可能消耗上百个节点)来说,浪费的资源成本不可接受。

 

2. 当集群中存在多个应用,且同时进行发布时,可能因为资源不足而无法拉起完整环境。

 

因此在生产实践中,在K8s中推广蓝绿发布可能会导致不止一倍的资源浪费,大大增加了成本。

 

随着云计算技术的发展,出现了阿里云容器计算服务ACS(Container Compute Service)等以Serverless形态而非通过节点交付算力的K8s产品。在使用Serverless集群时,由于按照实时Pod资源用量计费,使用蓝绿发布的应用仅会在两环境共存时产生额外费用,当蓝色环境销毁后,不会再有后续开销。同时,得益于Serverless产品的弹性能力,也不会存在因资源限制而拉不起环境从而导致发布不流畅的情况。因此,在成本节省补齐短板后,蓝绿发布可能是Serverless场景下更优秀的一种发布方式。

 

 

 

 

四. 总结

 

 

 

本文深入探讨了蓝绿发布的概念,剖析其优劣之处,并详细阐述了适用场景。此外,还通过一个具体案例展示了如何利用Kruise Rollouts组件来增强现有工作负载,从而实现高效的蓝绿发布策略。在实际生产环境中,企业选择何种发布方式及配套工具时,需综合考量多方面因素。最后,我们精心编制了一系列对比表格,旨在为读者提供直观且全面的参考依据。

 

蓝绿发布与金丝雀发布的对比:

 

 

Kruise Rollouts与其他开源方案对比(下表引用自Kruise Rollouts官方文档):

 

 

相关链接:

 

Kruise Rollouts蓝绿发布文档

https://openkruise.io/zh/rollouts/user-manuals/strategy-bluegreen-update/

 

Kruise Rollouts v0.6.0 release note:

https://github.com/openkruise/rollouts/releases/tag/v0.6.0




我们是阿里巴巴云计算和大数据技术幕后的核心技术输出者。

欢迎关注 “阿里云基础设施”同名微信微博知乎

获取关于我们的更多信息~

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
10月前
|
小程序 IDE 开发工具
【社区每周】AMPE新版本发布(12月第三期)
【社区每周】AMPE新版本发布(12月第三期)
74 6
|
5月前
|
Kubernetes 监控 测试技术
k8s学习--OpenKruise详细解释以及原地升级及全链路灰度发布方案
k8s学习--OpenKruise详细解释以及原地升级及全链路灰度发布方案
129 0
|
10月前
OpenKruise蓝绿部署的实现思路
【1月更文挑战第11天】【1月更文挑战第52篇】OpenKruise蓝绿部署的实现思路
90 1
|
10月前
|
前端开发 JavaScript IDE
蚂蚁CodeFuse新版发布,前端能力优化,支持安卓开发
蚂蚁百灵研发助手 CodeFuse 插件发布新版,本版本新增支持 Android Studio,并针对 JavaScript、TypeScript 等前端语言优化了模型效果,同时还将输出Token增加到最多 1024 个。目前 CodeFuse 处于邀请测试阶段,欢迎各位开发者前往官网申请资格参与测试。在之前已安装插件的用户需要下载最新版本,才可享受 CodeFuse 插件最新能力。
281 1
|
域名解析 运维 测试技术
不容闪失的灰度发布简介
不容闪失的灰度发布简介
189 0
|
机器学习/深度学习 人工智能 资源调度
隐语1.0正式发布|MVP部署体验包、资源调度框架Kuscia全新亮相!
隐语1.0正式发布|MVP部署体验包、资源调度框架Kuscia全新亮相!
380 0
|
边缘计算 Prometheus 运维
OpenYurt v1.2 新版本深度解读(三):五步搭建一个OpenYurt集群
OpenYurt v1.2 新版本深度解读(三):五步搭建一个OpenYurt集群
OpenYurt v1.2 新版本深度解读(三):五步搭建一个OpenYurt集群
|
运维 监控 JavaScript
如何用一个插件解决 Serverless 灰度发布难题?
灰度发布又称为金丝雀发布( Canary Deployment )。对于部署在 Serverless 平台上的函数应该怎么进行灰度发布呢?
|
存储 消息中间件 缓存
SREWorks v1.2 版本发布 | 运维市场能力发布
在v1.1版本发布之后,SREWorks团队开始了常态化的功能版本迭代,v1.1提供了组件插拔能力,v1.2更进一步,将会发布规划已久的运维市场,助力团队构筑运维生态,也会发布诸多企业用户关注的纯内网源码构建方案。
|
运维 Kubernetes 监控
KubeVela 1.1 发布,开启混合环境应用交付新里程碑
KubeVela 作为一个开箱即用、面向现代微服务架构的应用交付与管理平台,今天正式发布了 1.1 版本,以更加用户友好和完善的功能集,开启了“让混合环境应用交付更加简单高效”的重要里程碑。
KubeVela 1.1 发布,开启混合环境应用交付新里程碑