Higress & Kruise Rollout: 渐进式交付为应用发布保驾护航
作者:扬少
前言
在业务高速发展过程中,如何最大化保障功能迭代过程中业务流量无损一直是开发者比较关心的问题。通常在应用发布新功能阶段,我们会采用灰度发布的思想对新版本进行小流量验证,在符合预期之后再进行全量发布,这就是"渐进性交付"。该词最早起源于大型、复杂的工业化项目,它试图将复杂的项目进行分阶段拆解,通过持续进行小型闭环迭代降低交付成本和时间。随着云原生架构不断发展,渐进性交付被广泛应用在互联网业务应用中,开发者通过 GitOps、CI/CD 方式集成渐进式交付框架,让新功能交付以流水线的方式分批执行,利用 A/B 测试、金丝雀发布等技术精细化控制每一批次的流量策略,充分保障应用发布的稳定性。
什么是 Higress
Higress 是一款标准化、高集成、易扩展、热更新的云原生网关。
Higress 源自阿里巴巴内部电商、交易等核心生产场景的实践沉淀,遵循 Ingress/Gateway API 标准,将流量网关、微服务网关、安全网关三合一,并在此基础上扩展了服务管理插件、安全类插件和自定义插件,高度集成 K8s 和微服务生态,包括 Nacos 注册和配置、Sentinel 限流降级等能力,并支持规则变更毫秒级生效等热更新能力。
更多关于 Higress 的介绍,可以参阅 Higress 官网 [ 1] 。
什么是 Kruise Rollout
Kruise Rollout 是阿里云开源的云原生应用自动化管理套件 OpenKruise 在渐进式交付领域的新尝试,支持配合流量和实例灰度的金丝雀发布、蓝绿发布、A/B Testing 发布,以及发布过程能够基于 Prometheus Metrics 指标自动化分批与暂停,并提供旁路的无感对接、兼容已有的多种工作负载(Deployment、CloneSet、DaemonSet)。
这里,熟悉 Kubernetes 的小伙伴可以会疑惑,官方的 Deployment 工作负载不是有控制发布的策略吗?我们为什么还需要 Kruise Rollout 呢?
首先,Kubernetes 官方的 Deployment 中定义发布策略严格上不符合渐进性交付的思想,它实际是滚动发布。虽然 Deployment 对于升级而言提供了 maxUnavailable 和 maxSurge 两个参数,但是本质上来讲 Deployment 它只支持流式的一次性发布,用户并不能控制分批以及精细化的流量策略。比如用户无法严格控制新老版本之间的流量比例,只能根据实际 Pod 数量占比以及调用端的负载均衡策略;用户无法做 A/B testing 策略,例如限制公司内部员工可以访问新版本。当新版本出现问题,只能重新执行一遍滚动发布切回老版本,这样不仅回滚速度慢,而且频繁线上变更本身就具有极高的不稳定因素。
再者,Kubernetes 只提供了应用交付的 Deployment 控制器,以及针对流量的 Ingress、Service 抽象,但是如何将上述实现组合成开箱即用的渐进式交付方案,Kubernetes 并没有出标准的定义。
出于以上问题和考量,阿里云开始发起对渐进式领域的探索,结合多年来容器化、云原生的技术沉淀,推出了无侵入、可扩展、高易用的渐进式交付框架 Kruise Rollout。
Higress & Kruise Rollout 工作机制
简单介绍一下 Higress 和 Kruise Rollout 在一次应用发布过程中的工作机制。
这里,假设集群中有一个 Deployment 应用 A,通过 Higress 网关对外暴露提供服务。应用 A 由于业务发展,需要发布新功能。
1.用户首先在集群中添加渐进性交付策略(Rollout CRD 资源),描述目标工作负载的交付策略,比如批次,每一批次的流量控制,以及关联的 Service 资源和 Ingress 资源。
2.应用 A 发布新版本,用户修改集群上中目标 Deployment 的 Pod 模板中容器镜像为新版本。
3.Kruise Rollout 通过 hook 方式参与到 Deployment 滚动发布流程,修改 Deployment 的 Pause 来暂停滚动发布过程。
4.执行第一次批次发布,根据 Rollout CRD 资源描述的交付策略,控制新版本的 Pod 数量,同时为正式 Ingress 资源生成对应的灰度 Ingress 资源,并配置灰度流量策略,比如流量权重比或者根据请求内容 Header 进行流量分发。Higress 监听到 Ingress 资源变化,实时动态修改路由规则,满足灰度规则的流量被分发到新版本。
5.通过 Prometheus 等监控手段观察应用流量的指标信息,验证新版本是否符合预期。
a.如果符合预期,触发下一次批次发布,重复执行步骤 4
b.如果不符合预期,触发回滚,新发布的 Pod 下线,灰度已下线的部分老版本的 Pod,Ingress 资源自动下线灰度规则,Higress 实时修改路由规则,确保流量只访问老版本服务。
整个 Rollout 过程,自动整合 Deployment、Service、Ingress 一起工作,并向用户屏蔽底层资源变化。这是与现有工作负载能力的一种协同,它尽量复用工作负载的能力,又做到了非 Rollout 过程的零入侵。
实战:金丝雀发布
01:什么是金丝雀发布
金丝雀发布的思想是将少量的请求引流到新版本上,因此部署新版本服务只需极小数的机器。验证新版本符合预期后,逐步调整流量权重比例,使得流量慢慢从老版本迁移至新版本,期间可以根据设置的流量比例,对新版本服务进行扩容,同时对老版本服务进行缩容,使得底层资源得到最大化利用。
如图,某服务当前版本为 v1,现在新版本 v2 要上线。为确保流量在服务升级过程中平稳无损,采用金丝雀发布方案,逐步将流量从老版本迁移至新版本。
02:基于 Higress & Kruise Rollout 实践金丝雀发布
假设集群中有一个服务 demo,通过 Higress 网关对外提供服务。
如何安装 Higress,请参阅 Higress 快速开始 [ 2] 。
如何安装 Kruise Rollout,请参阅安装 Kruise Rollout [ 3] 。
现在,服务 demo 需要发布新版本。在修改应用镜像之前,我们需要为服务 demo 定义金丝雀发布策略,以达到渐进式发布的效果。
其中 workloadRef 旁路式的选择需要 Rollout 的 Workload,此处为 Deployment,支持其他 Workload(如 CloneSet、DaemonSet)。
其中 canary.Steps 定义了整个 Rollout 过程一共分为 3 批,其中第一批只灰度一个新版本 Pod,并且 routing 10% 流量到新版本 Pod,并且需要人工确认是否继续发布;第二批只灰度两个新版本 Pod,并且 routing 30%流量到新版本 Pod,并且需要人工确认是否继续发布;最后一批,无需定义,即全量发布。
其中 trafficRoutings 指向了需要感知流量规则的资源,kruise rollout 会自动更新相关资源,实时反射目标流量规则。
修改服务 A 的 Deployment 中镜像为 registry.cn-hangzhou.aliyuncs.com/mse-ingress/version:v2,观察相关资源变化。
查看 rollout 资源状态,发现当前执行完第一批发布,并且出于暂停状态,需要人工确认才能继续下一批次发布。
查看 pod 状态,发现新版本 pod 只有一个,Deployment 资源没有全部滚动发布。
查看 Ingress 的解析 IP (即 Higress 网关对外的公网 IP 地址)。
测试流量,发现有 10%流量访问新版本。
继续第二批次发布,查看当前 Pod 状态,发现新版本 Pod 有两个。
如何安装 kubectl-kruise,请参阅**安装 kubectl-kruise [ 4] **。
测试流量,观察流量分配比。
发布最后一批,完成全量发布。
测试流量,发现流量全部转发至新版本。至此,我们通过小流量的方式逐步将流量从老版本迁移至新版本。
实战:A/B Testing
01:什么是 A/B Testing
相比于基于权重方式的金丝雀发布,A/B 测试基于用户请求的元信息将流量路由到新版本,这是一种基于请求内容匹配的灰度发布策略。只有匹配特定规则的请求才会被引流到新版本,常见的做法包括基于 Http Header 和 Cookie。基于 Http Header 方式的例子,例如 User-Agent 的值为 Android 的请求 (来自安卓系统的请求)可以访问新版本,其他系统仍然访问旧版本。基于 Cookie 方式的例子,Cookie 中通常包含具有业务语义的用户信息,例如普通用户可以访问新版本,VIP 用户仍然访问旧版本。
如图,某服务当前版本为 v1,现在新版本 v2 要上线。希望安卓用户可以尝鲜新功能,其他系统用户保持不变。
通过在监控平台观察旧版本与新版本的成功率、RT 对比,当新版本整体服务预期后,即可将所有请求切换到新版本 v2,最后为了节省资源,可以逐步下线到旧版本 v1。
02:基于 Higress & Kruise Rollout 实践 A/B Testing
我们仍然利用上面的例子,服务 A 初始镜像为 v1。现在,服务 demo 需要发布新版本。在修改应用镜像之前,我们需要为服务 demo 定义 A/B Testing 策略,以达到渐进式发布的效果。
其中 canary.Steps 定义了整个 Rollout 过程一共分为 2 批,其中第一批只灰度一个新版本 Pod,并且将带有 HTTP Header user-agent: android (即安卓用户)的流量 routing 到新版本 Pod,并且需要人工确认是否继续发布;最后一批,无需定义,即全量发布。
修改服务 A 的 Deployment 中镜像为 registry.cn-hangzhou.aliyuncs.com/mse-ingress/version:v2,观察相关资源变化。
查看 rollout 资源状态,发现当前执行完第一批发布,并且出于暂停状态,需要人工确认才能继续下一批次发布。
查看 pod 状态,发现新版本 pod 只有一个,Deployment 资源没有全部滚动发布。
测试来自安卓的流量是否路由到新版本,非安卓的流量是否路由到老版本。
发布最后一批,完成全量发布。并测试所有流量是否路由到新版本。
总结
相比于传统人工手动方式,Higress & Kruise Rollouts 提供了无侵入、自动化运维方式让应用发布丝滑般顺畅。开发者无需关注发布过程中如何调整 Deployment、Ingress、Service 等资源,只需声明并管理发布策略 Rollouts 资源即可,原生 Deployment 的滚动发布会自动实现为渐进式交付,让应用发布可批次、可灰度、可回滚,助力业务快速迭代发展同时,也提高了应用发布的稳定性和效率问题。
01:Higress 社区
Higress 项目处于开源初期,我们在兼容好现有 Ingress 标准的基础上,会重点发力下一代的 Ingress 标准 Gateway API,利用 Gateway API 带来的契机打通南北向与东西向的全域流量调度,帮助用户使用一套架构架构同时管理外部与内部流量,降低部署运维成本、提升开发及运维效率。欢迎更多的用户参与到 Higress 社区,贡献一份文档、提交一段代码,您就有可能成为 Higress 的第一批 Contributor 甚至 Committer。目前,我们建立了 1 个钉群和 1 个微信群,加入我们,联系群主或群管,共建云原生网关吧。
02:OpenKruise 社区
OpenKruise 是阿里巴巴从容器化转向云原生化过程中,在云原生应用管理方面的最佳实践经验,除本文涉及的 Kruise Rollout 外,OpenKruise 还提供了诸多云原生应用管理相关的能力,如:增强的工作负载、Sidecar 容器管理、弹性拓扑管理等。目前 OpenKruise 上面托管着阿里集群上百万的 Pod,包含:有状态、无状态、通用类型的 Sidecar Aagent。
最后,欢迎感兴趣的同学加入下面的社区钉钉群,我们大家一起讨论云原生应用管理相关的需求与技术。
相关链接
[1] Higress 官网:
[2] Higress 快速开始:
https://higress.io/zh-cn/docs/user/quickstart.html
[3] 安装 Kruise Rollout:
https://github.com/openkruise/rollouts/blob/master/docs/getting_started/installation.md
[4] 安装 kubectl-kruise:
https://github.com/openkruise/kruise-tools/blob/master/README.md
点击此处进入 Higress 官网
版权声明: 本文为 InfoQ 作者【阿里巴巴云原生】的原创文章。
原文链接:【http://xie.infoq.cn/article/f55655b40661ef972cb3e51c9】。文章转载请联系作者。
评论