本文主要介绍了如何使用Istio和云效AppStack实现灰度发布。
场景描述
为了实现线上发布的灰度控制,可以通过控制不同版本实例的数量来调整流量比例。例如,将发布过程暂停在新、旧实例比为1:4的状态,此时20%的流量进入新版本,从而进行灰度验证。

然而,通过流量比例实现灰度发布存在两个不足:
-
无法精准控制灰度范围,如无法满足“指定用户请求新版本”的场景。
-
无法灵活控制流量比例,如最小灰度比例为20%,这对大部分应用来说不现实。
通过控制不同请求参数进入不同版本服务,并覆盖全链路场景,可以实现全链路的灰度发布。例如,基于阿里云MSE,可支持基于http/https、RocketMq流量的灰度发布,可参考实践:MSE+云效AppStack实现应用服务全链路灰度 。
本篇将介绍基于开源工具Istio实现全链路灰度发布的原理及在云效应用交付平台AppStack上的配置方法,满足基于http、gRPC、WebSocket的流量灰度发布场景。
原理介绍

前置条件
在Istio中,为了实现基于特定header的流量路由,需要完成如下操作:
-
安装Istio。
-
给命名空间添加标签,在部署应用的时候自动注入Envoy sidecar代理:
kubectl label namespace default istio-injection=enabled -
根据规则配置DestinationRule和VirtualService,例如:
apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: service-a spec: host: service-a subsets: - name: v1 labels: version: v1 - name: v2 labels: version: v2 --- apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: service-a spec: hosts: - service-a http: - match: - headers: end-user: exact: jason route: - destination: host: service-a subset: v2 - route: - destination: host: service-a subset: v1
配置完上述规则后,header 中包含 end-user=jason 的请求将全部路由到service-a的v2版本,其余请求将继续访问service-a的v1版本。
操作步骤
在云效AppStack中,我们提倡将发布规范固化在研发流程中,业务研发团队可自助式地完成发布。我们以官方的Bookinfo微服务为例,演示在云效AppStack中的配置过程:
步骤一:应用配置
-
依次创建 details、ratings、reviews、productpage 4个应用(一个微服务对应一个应用)。在应用交付 AppStack控制台的应用页面中,创建以下四个应用:productpage、reviews、ratings、details。
-
配置应用编排(应用编排定义了应用的部署架构,在k8s中,即 k8s manifest),完整的示例编排已上传至示例库。配置编排示例(部署顺序上,我们推荐将非工作负载放在一个阶段,工作负载独立放在一个阶段)。
示例中,顺序1(非工作负载阶段)包含 service(类型 Service)和 service-account(类型 ServiceAccount);顺序2(工作负载阶段)包含 deployment(类型 Deployment),两个阶段通过顺序箭头连接,确保非工作负载先于工作负载部署。
-
在4个应用下创建生产环境(prod),reviews应用额外创建灰度环境(gray),并关联k8s资源。具体操作:进入应用详情页,单击环境页签,单击新建环境按钮,输入环境名称(生产环境填写 prod,灰度环境填写 gray),选择目标 K8s 集群及命名空间,单击确定完成环境创建与集群关联。
-
分别进入4个应用的生产环境中完成首次部署,部署后可在环境详情页看到部署后的资源清单。进入各应用的生产环境页面,单击右上角的部署按钮完成应用部署。
-
在reviews应用的研发流程流水线中添加灰度环境部署任务,人工验证后发布生产环境。reviews 应用的灰度发布流水线在流程配置页签中编排如下阶段:流水线源 → AppStack灰度部署(部署阶段) → 人工卡点(验证阶段) → AppStack生产部署(部署阶段)。流水线源阶段需在应用设置 - 关联代码和制品中添加应用代码库。
步骤二:运行验证
参考官方示例创建网关,确保从集群外部访问应用。
流水线的部署阶段(AppStack灰度部署)完成后,进入验证阶段的人工卡点,流水线状态变为等待中,需人工确认验证通过后才会继续执行后续阶段。
运行研发流程并部署灰度环境后,访问BookInfo服务:
-
以 jason 用户登录,访问灰度环境。
登录后页面右上角显示当前用户为 jason,页面底部显示 Reviews served by: reviews-gray-78595b5bc-tssvh,表明评论服务已由灰度版本的 Pod 提供,流量路由配置生效。
-
匿名或以其他用户身份登录,访问生产环境。
访问生产环境后,Bookinfo 示例应用页面正常显示,页面底部显示
Reviews served by: reviews-prod-666cdc7bd9-gr249,表明评论服务由生产版本的 Pod 实例提供。
步骤三:灰度环境资源清理
-
在研发流程最后,添加 AppStack清理环境组件,选择仅清理资源保留环境元数据。在流水线中添加新阶段,新增 AppStack清理环境 任务。构建集群选择 云效北京构建集群,构建环境选择 默认环境,下载流水线源选择 下载全部流水线源。任务步骤中,应用选择 reviews,环境选择 灰度环境-gray,清理类型选择 仅清理资源保留环境元数据。
-
重新运行研发流程,执行完成 AppStack清理环境步骤后,前往k8s集群查看资源,灰度环境资源已被删除;访问 BookInfo 服务,所有用户都访问生产环境新版本。
以 jason 用户登录后,页面底部显示
Reviews served by: reviews-prod-666cdc7bd9-gr249,表明请求由生产环境 Pod 提供服务,评论区显示黑色星级评分。