基于Istio+云效AppStack实现灰度发布

更新时间:
复制为 MD 格式

本文主要介绍了如何使用Istio和云效AppStack实现灰度发布。

场景描述

为了实现线上发布的灰度控制,可以通过控制不同版本实例的数量来调整流量比例。例如,将发布过程暂停在新、旧实例比为1:4的状态,此时20%的流量进入新版本,从而进行灰度验证。

image

然而,通过流量比例实现灰度发布存在两个不足:

  1. 无法精准控制灰度范围,如无法满足“指定用户请求新版本”的场景。

  2. 无法灵活控制流量比例,如最小灰度比例为20%,这对大部分应用来说不现实。

通过控制不同请求参数进入不同版本服务,并覆盖全链路场景,可以实现全链路的灰度发布。例如,基于阿里云MSE,可支持基于http/https、RocketMq流量的灰度发布,可参考实践:MSE+云效AppStack实现应用服务全链路灰度

本篇将介绍基于开源工具Istio实现全链路灰度发布的原理及在云效应用交付平台AppStack上的配置方法,满足基于http、gRPC、WebSocket的流量灰度发布场景。

原理介绍

image

前置条件

Istio中,为了实现基于特定header的流量路由,需要完成如下操作:

  1. 安装Istio

  2. 给命名空间添加标签,在部署应用的时候自动注入Envoy sidecar代理:

    kubectl label namespace default istio-injection=enabled
  3. 根据规则配置DestinationRuleVirtualService,例如:

    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-av2版本,其余请求将继续访问service-av1版本。

操作步骤

在云效AppStack中,我们提倡将发布规范固化在研发流程中,业务研发团队可自助式地完成发布。我们以官方的Bookinfo微服务为例,演示在云效AppStack中的配置过程:

步骤一:应用配置

  1. 依次创建 details、ratings、reviews、productpage 4个应用(一个微服务对应一个应用)。在应用交付 AppStack控制台的应用页面中,创建以下四个应用:productpagereviewsratingsdetails

  2. 配置应用编排(应用编排定义了应用的部署架构,在k8s中,即 k8s manifest),完整的示例编排已上传至示例库。配置编排示例(部署顺序上,我们推荐将非工作负载放在一个阶段,工作负载独立放在一个阶段)。

    示例中,顺序1(非工作负载阶段)包含 service(类型 Service)和 service-account(类型 ServiceAccount);顺序2(工作负载阶段)包含 deployment(类型 Deployment),两个阶段通过顺序箭头连接,确保非工作负载先于工作负载部署。

  3. 4个应用下创建生产环境(prod),reviews应用额外创建灰度环境(gray),并关联k8s资源。具体操作:进入应用详情页,单击环境页签,单击新建环境按钮,输入环境名称(生产环境填写 prod,灰度环境填写 gray),选择目标 K8s 集群及命名空间,单击确定完成环境创建与集群关联。

  4. 分别进入4个应用的生产环境中完成首次部署,部署后可在环境详情页看到部署后的资源清单。进入各应用的生产环境页面,单击右上角的部署按钮完成应用部署。

  5. 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 实例提供。

步骤三:灰度环境资源清理

  1. 在研发流程最后,添加 AppStack清理环境组件,选择仅清理资源保留环境元数据。在流水线中添加新阶段,新增 AppStack清理环境 任务。构建集群选择 云效北京构建集群,构建环境选择 默认环境,下载流水线源选择 下载全部流水线源。任务步骤中,应用选择 reviews,环境选择 灰度环境-gray,清理类型选择 仅清理资源保留环境元数据

  1. 重新运行研发流程,执行完成 AppStack清理环境步骤后,前往k8s集群查看资源,灰度环境资源已被删除;访问 BookInfo 服务,所有用户都访问生产环境新版本。

    jason 用户登录后,页面底部显示 Reviews served by: reviews-prod-666cdc7bd9-gr249,表明请求由生产环境 Pod 提供服务,评论区显示黑色星级评分。