作者:十眠

什么是全链路灰度?

微服务系统架构中,服务之间的依靠联系错综杂乱,有时某个功用发版依靠多个服务一同升级上线。咱们希望能够对这些服务的新版别一同进行小流量灰度验证,这便是微服务架构中特有的全链路灰度场景,经过构建从网关到整个后端服务的环境阻隔来对多个不同版别的服务进行灰度验证。

在发布过程中,咱们只需布置服务的灰度版别,流量在调用链路上流通时,由流经的网关、各个中间件以及各个微服务来辨认灰度流量,并动态转发至对应服务的灰度版别。如下图:

通过 MSE 实现基于Apache APISIX的全链路灰度

上图能够很好展示这种计划的作用,咱们用不同的颜色来表明不同版别的灰度流量,能够看出无论是微服务网关仍是微服务自身都需求辨认流量,依据管理规矩做出动态决策。当服务版别发生变化时,这个调用链路的转发也会实时改变。相比于利用机器搭建的灰度环境,这种计划不仅能够节省大量的机器本钱和运维人力,而且能够协助开发者实时快速的对线上流量进行精细化的全链路操控。

那么全链路灰度具体是怎么完结呢?经过上面的评论,咱们需求处理以下问题:

1.链路上各个组件和服务能够依据恳求流量特征进行动态路由

2.需求对服务下的所有节点进行分组,能够区别版别

3.需求对流量进行灰度标识、版别标识

4.需求辨认出不同版别的灰度流量

下面将借着介绍 OpenSergo 关于流量路由所界说的 v1alpha1 规范,来告诉大家完结全链路灰度所需的技能细节。

Q:OpenSergo 是什么?

A:OpenSergo是一套敞开、通用的、面向分布式服务架构、覆盖全链路异构化生态的服务管理规范,依据业界服务管理场景与实践构成服务管理通用规范。OpenSergo 的最大特点便是以一致的一套装备/DSL/协议界说服务管理规矩,面向多言语异构化架构,做到全链路生态覆盖。无论微服务的言语是 Java, Go, Node.js 仍是其它言语,无论是规范微服务或 Mesh 接入,从网关到微服务,从数据库到缓存,从服务注册发现到装备,开发者都能够经过同一套 OpenSergo CRD 规范装备针对每一层进行一致的管理管控,而无需关注各结构、言语的差异点,下降异构化、全链路服务管理管控的杂乱度

Q:为什么了解全链路灰度之前先给我介绍 OpenSergo?

A:OpenSergo 界说了一套一致的 YAML 装备方法来针对分布式架构进行全链路的服务管理的规范,介绍规范与规范的一同,咱们能够了解其间的技能细节的完结,一同咱们还能够将新的组件与 OpenSergo 的规范进行完结。

OpenSergo 流量路由 v1alpha1 规范

流量路由,望文生义便是将具有某些特点特征的流量,路由到指定的目标。流量路由是流量管理中重要的一环,开发者能够依据流量路由规范来完结各种场景,如灰度发布、金丝雀发布、容灾路由、标签路由等。

全链路灰度示例:

通过 MSE 实现基于Apache APISIX的全链路灰度

流量路由规矩(v1alpha1) 主要分为三部分:

  • Workload 标签规矩 (WorkloadLabelRule):将某一组 workload 打上对应的标签,这一块能够理解为是为 APISIX 的各个上游打上对应的标签
  • 流量标签规矩 (TrafficLabelRule):将具有某些特点特征的流量,打上对应的标签
  • 依照 Workload 标签和流量标签来做匹配路由,将带有指定标签的流量路由到匹配的 workload 中

咱们能够赋予标签不同的语义,从而完结各个场景下的路由才能。

通过 MSE 实现基于Apache APISIX的全链路灰度

给流量打标:

需求将具有某些特点特征的流量,打上对应的标签。

假定现在需求将内部测试用户灰度到新版主页,测试用户 uid=12345,UID 坐落 X-User-Id header 中:

apiVersion: traffic.opensergo.io/v1alpha1
kind: TrafficLabelRule
metadata:
  name: my-traffic-label-rule
  labels:
    app: my-app
spec:
  selector:
    app: my-app
  trafficLabel: gray
  match:
  - condition: "=="    # 匹配表达式
    type: header       # 匹配特点类型
    key: 'X-User-Id'   # 参数名
    value: 12345       # 参数值
  - condition: "=="
    value: "/index"
    type: path

经过上述装备,咱们能够将 path 为 /index,且 uid header 为 12345 的 HTTP 流量,打上 gray 标,代表这个流量为灰度流量。

给 Workload 打标签:

那么怎么给服务节点增加不同的标签呢?在如今炽热的云原生技能推进下,大多数事务都在活跃进行容器化改造之旅。这里,我就以容器化的运用为例,介绍在运用 Kubernetes Service 作为服务发现和运用比较流行的 Nacos 注册中心这两种场景下怎么对服务 Workload 进行节点打标。

在运用 Kubernetes Service 作为服务发现的事务系统中,服务提供者经过向 ApiServer 提交 Service 资源完结服务暴露,服务消费端监听与该 Service 资源下相关的 Endpoint 资源,从 Endpoint 资源中获取相关的事务 Pod 资源,读取上面的 Labels 数据并作为该节点的元数据信息。所以,咱们只需在事务运用描绘资源 Deployment 中的 Pod 模板中为节点增加标签即可。

在运用 Nacos 作为服务发现的事务系统中,一般是需求事务依据其运用的微服务结构来决定打标方法。假如 Java 运用运用的 Spring Cloud 微服务开发结构,咱们能够为事务容器增加对应的环境变量来完结标签的增加操作。比如咱们希望为节点增加版别灰度标,那么为事务容器增加 traffic.opensergo.io/label: gray ,这样结构向 Nacos 注册该节点时会为其增加一个 gray 标签。

关于一些杂乱的 workload 打标场景(如数据库实例、缓存实例标签),咱们能够利用 WorkloadLabelRule CRD 进行打标。示例:

apiVersion: traffic.opensergo.io/v1alpha1
kind: WorkloadLabelRule
metadata:
  name: gray-sts-label-rule
spec:
  workloadLabels: ['gray']
  selector:
    app: my-app-gray

流量染色:

恳求链路上各个组件怎么辨认出不同的灰度流量?答案便是流量染色,为恳求流量增加不同灰度标识来便利区别。咱们能够在恳求的源头上对流量进行染色,前端在发起恳求时依据用户信息或许渠道信息的不同对流量进行打标。假如前端无法做到,咱们也能够在微服务网关上对匹配特定路由规矩的恳求动态增加流量标识。此外,流量在链路中流经灰度节点时,假如恳求信息中不含有灰度标识,需求主动为其染色,接下来流量就能够在后续的流经过程中优先拜访服务的灰度版别。

现在在 OpenSergo v1alphal1 并未具体界说流量染色这一块的规范,能够后续社区一同评论来规划流量染色规范。Apache APISIX 也会适配完结 OpenSergo 的规范,开发者能够经过同一套 OpenSergo CRD 规范装备针对流量网关层进行一致的管理管控,能够开释依据 Apache APSIX 的微服务架构的新价值。

全链路灰度是微服务最核心的功用之一,也是云上用户在微服务化深化过程中必须具备的功用。全链路灰度由于涉及到的技能和场景众多,假如企业一一进行自我完结,需求花费大量人力本钱对其进行扩展与运维。

依据 Apache APISIX 全链路灰度计划产品实践

介绍完技能,下面来介绍一下阿里云上依据 Apache APISIX 的全链路灰度的产品实践。

前提条件

第一步:装置 Ingress-APISIX 组件

APISIX 架构如下图所示,咱们需求装置 APISIX。

通过 MSE 实现基于Apache APISIX的全链路灰度

  1. 装置 apisix、apisix-ingress-controller、etcd 等组件
helm repo add apisix https://charts.apiseven.com
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
kubectl create ns ingress-apisix
helm install apisix apisix/apisix \
  --set gateway.type=LoadBalancer \
  --set ingress-controller.enabled=true \
  --set etcd.persistence.storageClass="alicloud-disk-ssd" \
  --set etcd.persistence.size="20Gi" \
  --namespace ingress-apisix \
  --set ingress-controller.config.apisix.serviceNamespace=ingress-apisix
kubectl get service --namespace ingress-apisix

看到在 ingress-apisix命名空间下看到无状况 apisix、apisix-ingress-controller 运用、以及有状况的 etcd 运用。

  1. 装置 APISIX Admin
helm repo add apisix https://charts.apiseven.com
helm repo update
helm install apisix-dashboard apisix/apisix-dashboard --namespace ingress-apisix

装置完结后,能够绑定一个 SLB

通过 MSE 实现基于Apache APISIX的全链路灰度

经过{slb-ip}:9000 拜访 APISIX 操控台(默许暗码admin/admin)

通过 MSE 实现基于Apache APISIX的全链路灰度

第二步:敞开微服务管理

这一过程中,需求开通 MSE 微服务管理、装置 MSE 服务管理组件(ack-onepilot)并为运用敞开微服务管理。具体操作信息可参阅阿里云官方教程

help.aliyun.com/product/123…

第三步:布置 Demo 运用程序

在阿里云容器服务中布置 A、B、C 三个运用,每个运用别离布置⼀个base 版别和⼀个gray 版别;并布置⼀个 Nacos Server 运用,用于完结服务发现。具体可参阅此教程完结运用布置:布置Demo 运用程序。布置完结后,你能够经过 APISIX Dashboard 为运用装备 Service 进行上游装备。

运用场景:依照指定恳求参数进行路由,完结全链路灰度

有些客户端没法改写域名,希望能拜访 www.demo.com 经过传入不同的参数来路由到灰度环境。例如下图中,经过 env=gray 这个恳求参数,来拜访灰度环境。

通过 MSE 实现基于Apache APISIX的全链路灰度

调用链路 Ingress-APISIX -> A -> B -> C ,其间 A 能够是一个 spring-boot 的运用。

装备APISIX路由规矩

在 APISIX Dashboard 挑选路由并单击创建。匹配条件中新建高档匹配规矩、恳求路径挑选 /*,挑选对应的上游。别离装备如下路由:

  • 当 host 为 www.demo.com,恳求参数 env=gray 时,路由优先匹配 id 为 401163331936715388 所对应的上游,即 spring-cloud-a-gray-svc;
  • 当 host 为www.demo.com时,路由经会匹配 id 为 401152455435354748 所对应的上游,即 spring-cloud-a-svc。

然后进行 base 对应的路由装备:

{
  "uri": "/*",
  "name": "spring-cloud-a",
  "methods": [
    "GET",
    "POST",
    "PUT",
    "DELETE",
    "PATCH",
    "HEAD",
    "OPTIONS",
    "CONNECT",
    "TRACE"
  ],
  "host": "www.demo.com",
  "upstream_id": "401152455435354748",
  "labels": {
    "API_VERSION": "0.0.1"
  },
  "status": 1
}

进行 gray 对应的路由装备,如下图所示:

通过 MSE 实现基于Apache APISIX的全链路灰度

{
  "uri": "/*",
  "name": "spring-cloud-a-gray",
  "priority": 1,
  "methods": [
    "GET",
    "POST",
    "PUT",
    "DELETE",
    "PATCH",
    "HEAD",
    "OPTIONS",
    "CONNECT",
    "TRACE"
  ],
  "host": "www.demo.com",
  "vars": [
    [
      "arg_env",
      "==",
      "gray"
    ]
  ],
  "upstream_id": "401163331936715388",
  "labels": {
    "API_VERSION": "0.0.1"
  },
  "status": 1
}

装备 MSE 全链路灰度

你需求装备完结 MSE 的全链路发布,具体操作细节可参阅此教程:装备全链路灰度。

成果验证

此时,拜访 www.demo.com 路由到 基线环境

curl -H"Host:www.demo.com" http://47.97.253.177/a
A[172.18.144.15] -> B[172.18.144.125] -> C[172.18.144.90]%

此时,拜访 www.demo.com 一同env=gray时路由到灰度环境

curl -H"Host:www.demo.com" http://47.97.253.177/a?env=gray
Agray[172.18.144.16] -> Bgray[172.18.144.57] -> Cgray[172.18.144.157]%

注意:其间 47.97.253.177 为 APISIX 的公网 IP

总结

现在 MSE 服务管理全链路灰度才能已经支撑了云原生网关、ALB、APISIX、Apache Dubbo、Spring Cloud、RocketMQ 以及数据库。

依据 Apache APISIX 灵活的路由才能,配合 MSE 全链路灰度才能,能够快速完结企业级的全链路灰度的才能。APSIX 支撑依照 Header、Cookie、Params、域名等多种方法进行路由,只需求在网关侧依据需求将流量路由至不同的“泳道”环境后,流量在对应标签的“泳道”中主动闭环,当泳道中并不存在调用链中所依靠的其他服务时,流量需求回退至基线环境,进一步在必要的时分路由回对应标签的泳道。

服务管理是微服务改造深化到必定阶段之后的必经之路,在这个过程中咱们不断有新的问题出现。

  • 除了全链路灰度,服务管理还有没其他才能?
  • 服务管理才能有没一个规范的界说,服务管理才能包括哪些?
  • 多言语场景下,有无全链路的最佳实践或许规范?
  • 异构微服务怎么能够一致管理?

当咱们在探究服务管理的过程中,咱们在对接其他微服务的时分,咱们发现管理系统不同造成的困扰是巨大的,打通两套甚者是多套管理系统的本钱也是巨大的。为此咱们提出了 OpenSergo 项目。OpenSergo 要处理的是不同结构、不同言语在微服务管理上的概念碎片化、无法互通的问题。

OpenSergo 社区也在联合 Apache APISIX 社区进行进一步的协作,社区来一同评论与界说一致的服务管理规范。当前社区也在联合 bilibili、字节跳动等企业一同共建规范,也欢迎感兴趣的开发者、社区与企业一同加入到 OpenSergo 服务管理规范共建中。欢迎大家加入 OpenSergo 社区沟通群(钉钉群)进行评论:34826335

相关链接

  • OpenSergo:opensergo.io/zh-cn
  • MSE 微服务引擎:www.aliyun.com/product/ali…

MSE 注册装备中心专业版首购享 9 折优惠,MSE 云原生网关预付费全规格享 9 折优惠。点击此处,即享优惠~