作者:十眠
什么是全链路灰度?
微服务体系架构中,服务之间的依赖关系盘根错节,有时某个性能发版依赖多个服务同时降级上线。咱们心愿能够对这些服务的新版本同时进行小流量灰度验证,这就是微服务架构中特有的全链路灰度场景,通过构建从网关到整个后端服务的环境隔离来对多个不同版本的服务进行灰度验证。
在公布过程中,咱们只需部署服务的灰度版本,流量在调用链路上流转时,由流经的网关、各个中间件以及各个微服务来辨认灰度流量,并动静转发至对应服务的灰度版本。如下图:
上图能够很好展现这种计划的成果,咱们用不同的色彩来示意不同版本的灰度流量,能够看出无论是微服务网关还是微服务自身都须要辨认流量,依据治理规定做出动静决策。当服务版本发生变化时,这个调用链路的转发也会实时扭转。相比于利用机器搭建的灰度环境,这种计划不仅能够节俭大量的机器老本和运维人力,而且能够帮忙开发者实时疾速的对线上流量进行精细化的全链路管制。
那么全链路灰度具体是如何实现呢?通过下面的探讨,咱们须要解决以下问题:
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 规范
流量路由,顾名思义就是将具备某些属性特色的流量,路由到指定的指标。流量路由是流量治理中重要的一环,开发者能够基于流量路由规范来实现各种场景,如灰度公布、金丝雀公布、容灾路由、标签路由等。
全链路灰度示例:
流量路由规定 (v1alpha1) 次要分为三局部:
- Workload 标签规定 (WorkloadLabelRule):将某一组 workload 打上对应的标签,这一块能够了解为是为 APISIX 的各个上游打上对应的标签
- 流量标签规定 (TrafficLabelRule):将具备某些属性特色的流量,打上对应的标签
- 依照 Workload 标签和流量标签来做匹配路由,将带有指定标签的流量路由到匹配的 workload 中
咱们能够赋予标签不同的语义,从而实现各个场景下的路由能力。
给流量打标:
须要将具备某些属性特色的流量,打上对应的标签。
假如当初须要将内部测试用户灰度到新版主页,测试用户 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。
- 装置 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 利用。
- 装置 APISIX Admin
helm repo add apisix https://charts.apiseven.com
helm repo update
helm install apisix-dashboard apisix/apisix-dashboard --namespace ingress-apisix
装置实现后,能够绑定一个 SLB
通过 {slb-ip}:9000 拜访 APISIX 控制台(默认明码 admin/admin)
第二步:开启微服务治理
这一步骤中,须要开明 MSE 微服务治理、装置 MSE 服务治理组件(ack-onepilot)并为利用开启微服务治理。具体操作信息可参考阿里云官网教程:
https://help.aliyun.com/produ…
第三步:部署 Demo 应用程序
在阿里云容器服务中部署 A、B、C 三个利用,每个利用别离部署⼀个 base 版本和⼀个 gray 版本;并部署⼀个 Nacos Server 利用,用于实现服务发现。具体可参考此教程实现利用部署:部署 Demo 应用程序。部署实现后,你能够通过 APISIX Dashboard 为利用配置 Service 进行上游配置。
利用场景:依照指定申请参数进行路由,实现全链路灰度
有些客户端没法改写域名,心愿能拜访 www.demo.com 通过传入不同的参数来路由到灰度环境。例如下图中,通过 env=gray 这个申请参数,来拜访灰度环境。
调用链路 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 对应的路由配置,如下图所示:
{
"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:https://opensergo.io/zh-cn
- MSE 微服务引擎:https://www.aliyun.com/produc…
MSE 注册配置核心专业版首购享 9 折优惠,MSE 云原生网关预付费全规格享 9 折优惠。点击此处,即享优惠~