通过 OpenKruise 实现基于 Higress 的全链路灰度

简介: OpenKruise 是一个基于 Kubernetes 的扩展套件,主要聚焦于云原生应用的自动化,比如部署、发布、运维以及可用性防护。本文介绍通过 OpenKruise 构建自动化运维的方式实现全链路灰度功能。

作者:十眠、立衡

OpenKruise 是一个基于 Kubernetes 的扩展套件,主要聚焦于云原生应用的自动化,比如部署、发布、运维以及可用性防护。本文介绍通过 OpenKruise 构建自动化运维的方式实现全链路灰度功能。


灰度发布提高应用交付的稳定性和效率


在发布应用的过程中,我们通常希望用少量特定流量来验证新版本的发布是否正常,以保障整体稳定性。这个过程被称为灰度发布。关于灰度发布,我们通过逐步增加发布的范围,来验证新版本的稳定性。如果新版本出现问题,我们也能及时发现,控制影响范围,保障整体的稳定性。

渐进式发布一般具有以下特点:

  • 逐步增加发布的影响范围,拒绝一次性全部发布;
  • 阶段性的发布过程,可以通过金丝雀发布方式小心验证,以验证新版本的稳定性;
  • 可暂停、可回滚、可继续、可自动化状态流转,以便灵活地控制发布过程并确保稳定性。

据调研数据 70% 的线上问题都是由于变更导致,我们常说安全生产三板斧,可灰度、可观测、可回滚,也是为了控制变更带来的风险与影响面。通过采用灰度发布的方式,我们能够更加稳健地发布新版本,避免因发布过程中出现的问题而带来的损失。


微服务架构对灰度发布提出了更高的要求



在微服务架构的场景下,传统的灰度发布模式往往不能满足微服务交付的复杂、多样化的需求。这是因为:

  • 微服务调用链路比较长,比较复杂。在微服务架构中,服务之间的调用链路比较复杂,一个服务的改动可能会影响到整个调用链路,从而影响整个应用的稳定性。
  • 一次灰度可能涉及多个模块,整个链路都要调用新版本。由于微服务架构中服务之间相互依赖,一个服务的修改可能需要其他服务的相应调整。这就导致了在进行灰度发布时,需要同时调用多个服务的新版本,增加了发布的复杂度和不确定性。
  • 多个项目并行,需要部署多套环境,环境构建不灵活、成本高。在微服务架构中,往往会有多个项目并行开发,需要部署多套环境来支持不同的项目。这就增加了环境构建的难度和成本,从而导致发布效率低下。

为了解决这些问题,我们需要采用更加灵活、可控并且适用于微服务场景的发布方式,全链路灰度发布的场景也就应运而生。通常每个微服务都会有灰度环境或分组来接受灰度流量。我们希望进入上游灰度环境的流量也能进入下游灰度的环境中,确保1个请求始终在灰度环境中传递,从而形成流量“泳道”。在“泳道”内的流量链路中,即使这个调用链路上有一些微服务应用不存在灰度环境,那么这些微服务应用在请求下游应用的时候依然能够回到下游应用的灰度环境中。

全链路灰度为微服务发布保驾护航


这种方式可以根据服务的实际情况,可以对单个服务可以进行独立的发布和流量控制,也可以控制多个服务同时进行发布变更,从而保证整个系统的稳定性。同时,还可以采用自动化的部署方式,实现快速、可靠的发布过程,提高发布效率和稳定性。


实践全链路灰度的挑战


在 K8s 中实现微服务全链路灰度发布是一个非常复杂的过程,需要涉及多个组件和配置的修改与协调。以下是具体的一些步骤和问题:

  • 在微服务架构中,网关是服务的入口,需要根据灰度发布的要求,调整网关配置,实现路由匹配和流量特征(比如 Header 修改)。
  • 为了实现全链路灰度发布,需要新部署一套灰度应用环境,并为其打上灰度标记(新部署一套 Gray 应用以及 Gray 灰度标)。这样可以将流量流向灰度环境,从而实现灰度发布。
  • 验证流量正常,将基线环境升级,销毁灰度环境,恢复网关配置。在灰度发布过程中,需要对流量进行验证,确保流量的正常流向和服务的正常运行。如果验证通过,可以将基线环境升级到灰度版本,并销毁灰度环境。最后,需要恢复网关的配置,以确保流量正常流向。
  • 如果发生异常,需要快速回滚。由于微服务架构复杂,可能会出现各种异常情况,比如服务崩溃、流量异常等。在这种情况下,需要快速回滚,以避免产生更大的损失。因此,需要预先设计好回滚方案,并在发生异常时快速执行回滚操作。

另外一方面,生产的流量是端到端的,那么意味着我们需要控制流量在前端、网关、后端各个微服务等组件中闭环。不仅仅是 RPC/Http 的流量,对于异步调用比如 MQ 流量我们也需要符合全链路“泳道”调用的规则,这整个过程中涉及到的流量控制的复杂度也是非常高的。

为了简化微服务全链路灰度发布的过程,可以使用一些自动化工具和产品,如 MSE、Kruise Rollout 等。这些工具和产品可以帮助我们更加便捷地实现微服务全链路灰度发布,并提高发布的效率和稳定性。


Kruise Rollout+MSE 端到端的全链路灰度发布实践


为什么要 Kruise Rollout?
Kruise Rollout[1]是 OpenKruise 社区开源提出的一个渐进式交付框架。其设计理念是提供一组能够将流量发布与实例灰度相结合,支持金丝雀、蓝绿、A/B Testing 等多样化发布形式,以及支持基于 Prometheus Metrics 等自定义 Metrics 实现发布过程自动化,无感对接、易扩展的旁路式标准 Kubernetes 发布组件。主要特性如下:

  • 非侵入性:不对用户的应用交付配置做任何的侵入,使用旁路的方式来扩展渐进式交付的能力,并且能够做到即插即用的效果。
  • 可扩展性:充分考虑了对多种类似的工作负载的支持(Deployment、StatefulSet、CloneSet 以及自定义 CRD 工作负载);在流量调度方面,通过 lua 脚本的方案能够支持 Nginx、Alb、Mse、Gateway API 等多种流量调度方案。

       


Kruise Rollout 本身就支持各种灰度发布的能力(金丝雀、A/B Testing、蓝绿发布),深入了解后发现它的发布模型非常契合 MSE 全链路灰度,因此与 Kruise Rollout 结合后可以非常方便的让用户实现 MSE 全链路灰度发布能力。


MSE 全链路灰度发布的最佳实践


01. 部署应用 & 配置全链路灰度发布 CRD

我们可以参考 MSE 云原生网关全链路灰度[2]文档部署 Demo 应用。

➜  ~ kubectl get deployments         
NAME             READY   UP-TO-DATE   AVAILABLE   AGE
demo-mysql       1/1     1            1           30h
nacos-server     1/1     1            1           46h
spring-cloud-a   2/2     2            2           30h
spring-cloud-b   2/2     2            2           30h
spring-cloud-c   2/2     2            2           30h

部署完应用之后,我们首先要区分线上流量和灰度流量。

我们通过创建 Rollout CRD 来定义全链路灰度发布的流程。1. 将整个链路涉及到的应用创建 Rollout 配置

# a rollout configuration
---
apiVersion: rollouts.kruise.io/v1alpha1
kind: Rollout
metadata:
  name: rollout-a
spec:
  objectRef:
    workloadRef:
      apiVersion: apps/v1
      kind: Deployment
      name: spring-cloud-a
  ...
# b rollout configuration
---
apiVersion: rollouts.kruise.io/v1alpha1
kind: Rollout
metadata:
  name: rollout-b
  annotations:
    rollouts.kruise.io/dependency: rollout-a
spec:
  objectRef:
    workloadRef:
      apiVersion: apps/v1
      kind: Deployment
      name: spring-cloud-b
  ...
# c rollout configuration
---
apiVersion: rollouts.kruise.io/v1alpha1
kind: Rollout
metadata:
  name: rollout-c
  annotations:
    rollouts.kruise.io/dependency: rollout-a
spec:
  objectRef:
    workloadRef:
      apiVersion: apps/v1
      kind: Deployment
      name: spring-cloud-c
  ...

2. 然后为了表明线上流量与灰度流量的特征,即在入口服务上配置灰度流量规则

canary:
  steps:
    - matches:
        - headers:
            - type: Exact
              name: x-user-id
              value: '100'
      requestHeaderModifier:
        set:
          - name: x-mse-tag
            value: gray
  trafficRoutings:
    - service: spring-cloud-a
      ingress:
        name: spring-cloud-a
        classType: mse

3. 针对灰度发布中的应用,Kruise 会自动给他标识 gray 版本

# only support for canary deployment type
patchCanaryMetadata:
  labels:
    alicloud.service.tag: gray

安装完成 Rollout CRD 后,我们可以查看一下:

➜  ~ kubectl get Rollout             
NAME        STATUS    CANARY_STEP   CANARY_STATE   MESSAGE                            AGE
rollout-a   Healthy   1             Completed      workload deployment is completed   4s
rollout-b   Healthy   1             Completed      workload deployment is completed   4s
rollout-c   Healthy   1             Completed      workload deployment is completed   4s

到目前为止我们定义了这样一组全链路灰度发布的规则,发布链路涉及 MSE 云原生网关、A、B、C 应用,其中 x-user-id=100 的流量为灰度流量。

接下来,我们快速进行一次灰度发布与验证吧。

02. 灰度发布&验证流量

1. 本次发布涉及到应用 A、C 的改动,因此我们直接编辑应用 A、C 的 Deployment yaml,进行变更操作

# a application
---        
apiVersion: apps/v1
kind: Deployment
metadata:
  name: spring-cloud-a
spec:
  ...
  template:
    ...
    spec:
        # 修改 mse-1.0.0 -> mse-2.0.0,触发应用A发布,以及MSE全链路灰度
        image: registry.cn-hangzhou.aliyuncs.com/mse-demo-hz/spring-cloud-a:mse-2.0.0
# c application
---        
apiVersion: apps/v1
kind: Deployment
metadata:
  name: spring-cloud-c
spec:
  ...
  template:
    ...
    spec:
        # 修改 mse-1.0.0 -> mse-2.0.0,触发应用A发布,以及MSE全链路灰度
        image: registry.cn-hangzhou.aliyuncs.com/mse-demo-hz/spring-cloud-c:mse-2.0.0

2. 变更完成之后,我们查看我们当前应用的形态

➜  ~ kubectl get deployments
NAME                   READY   UP-TO-DATE   AVAILABLE   AGE
demo-mysql             1/1     1            1           30h
nacos-server           1/1     1            1           46h
spring-cloud-a         2/2     0            2           30h
spring-cloud-a-84gcd   1/1     1            1           86s
spring-cloud-b         2/2     2            2           30h
spring-cloud-c         2/2     0            2           30h
spring-cloud-c-qzh9p   1/1     1            1           113s

我们发现,Kruise Rollout 并没有直接修改我们原先的 deployment,而是先给我们创建了两个灰度应用 spring-cloud-a-84gcd、spring-cloud-c-qzh9p。


3. 等应用启动就绪我们分别来验证线上正常流量以及灰度流量
a. 访问网关,如果不符合灰度规则,走基线环境:

➜  ~ curl -H "Host: example.com" http://39.98.205.236/a
A[192.168.42.115][config=base] -> B[192.168.42.118] -> C[192.168.42.101]% 

b. 如何符合灰度规则,走灰度环境:

➜  ~ curl -H "Host: example.com" http://39.98.205.236/a -H "x-user-id: 100"
Agray[192.168.42.119][config=base] -> B[192.168.42.118] -> Cgray[192.168.42.116]% 

4. 如果碰到预期外的行为,我们如何进行快速回滚?我们尝试回滚一下 C 应用,只需将 C 应用的 Deployment 改回原先配置即可。

# c application
---        
apiVersion: apps/v1
kind: Deployment
metadata:
  name: spring-cloud-c
spec:
  ...
  template:
    ...
    spec:
        # 修改 mse-2.0.0 -> mse-1.0.0,回滚c应用
        image: registry.cn-hangzhou.aliyuncs.com/mse-demo-hz/spring-cloud-c:mse-2.0.0

修改完成后,我们发现 C 应用的灰度 Deployment 已经没了。

➜  ~ kubectl get deployments
NAME                   READY   UP-TO-DATE   AVAILABLE   AGE
demo-mysql             1/1     1            1           30h
nacos-server           1/1     1            1           46h
spring-cloud-a         2/2     0            2           30h
spring-cloud-a-84gcd   1/1     1            1           186s
spring-cloud-b         2/2     2            2           30h
spring-cloud-c         2/2     0            2           30h

5. 如何完成发布?只需 kubectl-kruise rollout approve rollouts/rollout-a 将灰度中的应用进行完成发布

03. 整合 ArgoCD 实现基于 GitOps 的全链路灰度

GitOps 是一种持续交付的方式,它的核心思想是将应用系统的声明性基础架构和应用程序存放在 Git 版本库中。将 Git 作为交付流水线的核心,每个开发人员都可以提交拉取请求(Pull Request)并使用 Git 来加速和简化 Kubernetes 的应用程序部署和运维任务。通过使用像 Git 这样的简单工具,开发人员可以更高效地将注意力集中在创建新功能而不是运维相关任务上(例如,应用系统安装、配置、迁移等)。




试想一下,做为Developer,我们希望提交的 YAML 编写的应用程序定义(Deployment)可以先进行自动化的灰度环境发布,流量经过充分验证后,确定新版本的应用程序没有问题后,再进一步进行全量的应用发布。如何可以做到呢?接下来我们演示通过整合 ArgoCD 来实现的全链路灰度能力。

前提条件

安装 ArgoCD,参考 ArgoCD[3],ArgoCD 是用于 Kubernetes的 声明性 GitOps 连续交付工具。

通过 ArgoCD 配置部署应用资源

1. 在 ArgoCD 中创建 spring-cloud-c 应用

2. 在 ArgoCD 管理界面,单击 NEW APP,进行如下配置。

    a. 在 GENERAL 区域,配置 Application为spring-cloud-c,Project 为 default。 b. 在 SOURCE 区域,配置 Repository URL 为 https://github.com/aliyun/alibabacloud-microservice-demo.git ,Revision 为 argocd-samples,Path 为 argocd-samples/spring-cloud-c。 c. 在 DESTINATION 区域,配置 Cluster URL 为 https://kubernetes.default.svc,Namespace为 default。 d. 配置完成,单击页面上方的 CREATE。

3. 创建完成后,在 ArgoCD 管理界面,即可查看 spring-cloud-c 应用状态



4. 单击对应应用即可查看资源部署状态



5. 我们修改 argocd-samples/spring-cloud-c 中的 spring-cloud-c.yaml,并通过 git 提交


6. 我们可以发现,自动部署了 spring-cloud-c 应用的灰度版本

✗ kubectl get pods -o wide  | grep spring-cloud
NAME                                   READY   STATUS    RESTARTS   AGE    IP              NODE                      NOMINATED NODE   READINESS GATES
spring-cloud-a-69d577cc9-g7sbc         1/1     Running   0          16h    192.168.0.191   us-west-1.192.168.0.187   <none>           <none>
spring-cloud-b-7bc9db878f-n7pzp        1/1     Running   0          16h    192.168.0.193   us-west-1.192.168.0.189   <none>           <none>
spring-cloud-c-554458c696-2vp74        1/1     Running   0          137m   192.168.0.200   us-west-1.192.168.0.145   <none>           <none>
spring-cloud-c-554458c696-g8vbg        1/1     Running   0          136m   192.168.0.192   us-west-1.192.168.0.188   <none>           <none>
spring-cloud-c-md42b-74858b7c4-qzdxz   1/1     Running   0          53m    192.168.0.165   us-west-1.192.168.0.147   <none>           <none>

架构图如下:


7. 等应用启动就绪我们分别来验证线上正常流量以及灰度流量
a. 访问网关,如果不符合灰度规则,走基线环境:

➜  ~ curl -H "Host: example.com" http://39.98.205.236/a
A[192.168.0.191][config=base] -> B[192.168.0.193] -> C[192.168.0.200]%

b. 如何符合灰度规则,走灰度环境:

➜  ~ curl -H "Host: example.com" http://39.98.205.236/a -H "x-user-id: 100"
A[192.168.0.191][config=base] -> B[192.168.0.193] -> Cgray[192.168.0.165]%

8. 回滚只需我们通过 git 回滚 argocd-samples/spring-cloud-c 中的 spring-cloud-c.yaml 的上一次提交即可。

9. 结束发布通过 kubectl-kruise rollout approve rollouts/rollout-c 将灰度中的应用进行完成发布。


展望与总结


Kruise Rollout 是 OpenKruise 社区在渐进式交付领域的探索,此次与 MSE 合作在云原生领域落地了微服务场景的灰度发布场景。未来,Kruise Rollout 将在可扩展性方面做出持续的努力,比如:基于 Lua 脚本的可扩展流量调度方案,从而兼容社区更多的网关与架构(Istio、Apifix 等)。

在微服务治理架构中,全链路灰度功能能提供流量泳道,极大的方便了测试、发布时的快速验证,通过精确的引流规则将“爆炸半径”控制到最小,能够帮助 DevOps 提升线上稳定性。




MSE 的全链路灰度能力也在随着客户场景的深入而不断扩展与迭代。我们除了通过 MSE 全链路灰度能力保障发布态的稳定性外,还可以在运行态通过 MSE 解决流量、依赖、基础设施等不稳定的风险,MSE 微服务引擎一直致力于帮助企业打造永远在线的应用,相信只有经过客户场景持续打磨的产品才会愈发历久弥新。


相关社区


加入 OpenKruise 社区
最后,非常欢迎你通过 Github/Slack/钉钉/微信 等方式加入我们来参与 OpenKruise 开源社区。

  • 加入社区 Slack channel (English)
  • 加入社区钉钉群:搜索群号 23330762 (Chinese)
  • 加入社区微信群(新):添加用户 openkruise 并让机器人拉你入群 (Chinese)


加入 Higress 社区


如果您觉得 Higress 对您有帮助,欢迎前往 github: Higress[4]为我们 star 一下!


相关链接:

[1] Kruise Rollout

https://openkruise.io/rollouts/introduction

[2] MSE云原生网关全链路灰度

https://help.aliyun.com/zh/mse/configure-an-end-to-end-canary-release-based-on-mse-ingress-gateways#p-omu-6xu-8wm

[3] ArgoCD

https://argo-cd.readthedocs.io/en/stable/getting_started/

[4] github: Higress

https://github.com/alibaba/higress

相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。 &nbsp; &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
运维 Cloud Native 安全
阿里平台工程的发展历程与关键实践
什么是平台工程,怎么在企业内落地平台工程,云效负责人陈鑫在2023云栖大会上,结合云效过去在阿里内部十多年的经验和在各大企业的实践,给出了非常详细的解答。
4058 3
|
缓存 数据安全/隐私保护 iOS开发
2023最新mac开启ntfs读写功能 ntfs硬盘如何在mac上读写教程
在日常的工作中,总是避免不了跨平台的传输文件、文件共享等,例如一些用户使用Mac电脑修图或者剪辑视频之后需要拷贝到Windows电脑上查看。对于需要同时使用Mac和Windows的用户来说,系统之间不兼容是很大的阻碍,尤其是使用NTFS移动硬盘,用户会遇到Mac电脑无法写入NTFS硬盘的情况,本文就来教大家ntfs硬盘如何在mac上读写以及mac如何移动硬盘的文件。
4684 0
2023最新mac开启ntfs读写功能 ntfs硬盘如何在mac上读写教程
|
Linux iOS开发 MacOS
PowerShell命令行输出和添加系统环境变量
主要介绍使用PowerShell命令如何查看、修改和删除系统环境变量,对于需要操作添加PATH环境变量非常实用 。由于 Powershell 的跨平台,其环境变量修改可以在linux、macos...
4911 0
PowerShell命令行输出和添加系统环境变量
|
9月前
|
人工智能 数据安全/隐私保护
什么样的“软技能”可以跨越周期、终身成长?
在快速变化的数字化时代,软技能成为职场人士实现终身成长的关键。本文探讨了学习能力、适应能力、沟通能力、领导力和创新思维等跨越周期的软技能,并介绍了生成式人工智能(GAI)认证作为提升软技能的新途径。GAI认证不仅涵盖技术知识,还强调软技能培养,助力职场人士增强竞争力、促进职业发展,同时强化道德与合规意识。通过系统学习与实践,个人可在未来职业生涯中脱颖而出,实现持续成长。
|
28天前
|
人工智能 算法 数据可视化
深度解析:Geo优化的核心要素与“两大核心+四轮驱动”方法论的系统融合
随着AI搜索兴起,生成式引擎优化(GEO)成为新焦点。于磊老师提出“两大核心+四轮驱动”方法论,倡导人性化Geo与内容交叉验证,强调内容质量、权威性、结构化与用户体验,构建AI信任体系,助力企业提升引用率、降低获客成本,实现AI时代精准获客与高效转化。
128 10
|
SQL Prometheus 运维
Higress on K8s 5分钟开箱即用
Higress on K8s 5分钟开箱即用
Higress on K8s 5分钟开箱即用
|
运维 Cloud Native Java
MSE-Higress
MSE-Higress
477 1
|
Kubernetes 负载均衡 容器
在K8S中,nodePort的externalTrafficPolicy字段有什么作用?
在K8S中,nodePort的externalTrafficPolicy字段有什么作用?
|
人工智能 负载均衡 异构计算
灵骏可预期网络:Built for AI Infrastructure
灵骏可预期网络:Built for AI Infrastructure
灵骏可预期网络:Built for AI Infrastructure
|
tengine 自然语言处理 Kubernetes
Nacos2.0的K8s服务发现生态应用及规划
Nacos 是阿里巴巴于 2018 年开源的注册中心及配置中心产品,帮助用户的分布式微服务应用进行服务发现和配置管理功能。随着 Nacos2.0 版本的发布,在性能和扩展性上取得较大突破后,社区开始考虑如何提供更加云原生方向的功能和用法。本次分享主要介绍 Nacos 在 2.0 版本在Kubernetes 环境下对服务发现生态的应用探索成果及后续探索方向的规划。
Nacos2.0的K8s服务发现生态应用及规划

热门文章

最新文章