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

1. 场景描述

为了达成线上发布可灰度的目的,一种做法是控制不同版本的实例数量,从而达到基于流量比例灰度的目的,例如典型的分批发布场景。如下图所示,我们将发布过程暂停在新、旧实例比为1:4的状态,此时将有20%的流量进入到新版本,从而达到灰度验证的目的。

image

然而,通过流量比例实现灰度发布,会存在2个关键的不足:

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

(2)无法灵活的控制流量比例。如:线上服务有5个Pod,此时最小灰度比例即20%;如果想要达到1%的灰度流量比例,线上至少需要100个Pod,这对大部分应用来说是不现实的。

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

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

2. 原理介绍

image

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

  1. 安装Istio,参考:https://istio.io/latest/zh/docs/setup/getting-started/

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

kubectl label namespace default istio-injection=enabled
  1. 根据规则配置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版本。

3. 操作实践

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

  • 前提条件:预先在k8s集群中完成Istio的安装,并为相关namespace打上 istio-injection=enabled 的标签。做法可参考上文“原理介绍”部分。

3.1 应用配置

  1. 依次创建 details、ratings、reviews、productpage 4个应用(在云效AppStack中,我们推荐一个微服务对应一个应用)。

image.png

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

image.png

  1. 在4个应用下创建生产环境(环境名称:prod),reviews应用额外创建一个灰度环境(环境名称:gray),创建环境时需要关联k8s资源。

image.png

  1. 分别进入4个应用的生产环境中完成首次部署,部署后可在环境详情页看到部署后的资源清单。

image.png

  1. 针对需要灰度发布验证的reviews应用,编辑研发流程流水线添加灰度环境部署任务,经过人工卡点验证后再发布生产环境。

image.png

3.2 运行验证

在运行验证前,需要参考官方示例创建网关,确保后续能够从集群外部访问应用。

image.png

运行研发流程并部署灰度环境后,访问BookInfo服务:

  • 以 jason 用户登录,访问的是灰度环境:

image.png

  • 匿名或以其他用户身份登录,访问的是生产环境:

image.png

3.3 灰度环境资源清理

生产环境发布完成后,可以通过配置自动清理灰度环境,删除灰度环境相关资源并将流量全部导入生产环境。

  1. 在研发流程最后,添加 AppStack清理环境组件;

  • 清理环境组件配置示例,清理类型选择“仅清理资源保留环境元数据”:

image.png

  1. 重新运行研发流程,执行完成 AppStack清理环境步骤后

  • 前往k8s集群查看资源,灰度环境资源已经被删除;访问 BookInfo 服务,所有用户都访问到生产环境新的版本

image.png