DataWorks 微服务集群的 Service Mesh 落地实践

2020 年 3 月 14 日

DataWorks 微服务集群的 Service Mesh 落地实践

初心


DataWorks 是集团内外广泛使用的全域智能大数据平台,包含了 DataStudio、StreamStudio、HoloStudio、AppStudio、GraphStudio、PAIStudio、WebExcel 等众多的线上产品,每个产品都是类似于 IDE 形态的富交互单页应用。



但是,DataWorks 服务于集团各大业务线上万名数据开发者和数据生态的参与者,这艘巨大的航母却不能准确地表达每一个用户的述求,「众口难调」。


因此,DataWorks 在架构升级的关键节点,决心将插件化、服务化定制的能力彻底落地,解开过重的业务共建模式在研发上的耦合羁绊,向更轻量的更开放的平台化迈进,不忘服务初心,帮助我们内外客户的业务定制快速落地。


那么如何开放 DataWorks 的定制化能力?


我们建立了一整套完整的微服务研发管控体系, DataWorks 微服务平台(DMSP:DataWorks MicroService Platform),以满足业务开发者定制服务化需求,帮助业务整合 DataWorks 输出的中台能力,重新定义属于自己的业务数据研发平台。


轻车快马


轻装上阵,是对用户(开发者、业务方)而言的。要做到用户的轻,作为平台方,我们就要做得更多。


对于业务而言,最轻量的,就是「只需要关注业务逻辑」。


即,业务开发者仅仅专注在业务逻辑上,而不需要再自己关注 入流量 的安全认证、路由、负载均衡、镜像、限流;出流量 的超时、重试、访问控制;服务间调用的隔离策略、熔断、分布式追踪等与业务逻辑无关的内容。


过去,微服务生态周边发展出了大量组件、框架,帮助我们很好地解决上述的业务以外的问题。但是这些组件框架门槛高、维护成本高、开发语言耦合,对于大多数开发者而言,成本太高,不适用于有敏捷开发需求的新兴业务。


近年来火热的服务网格(Service Mesh)技术,正能够解开这一困局。参见《Service Mesh 入门》


微服务集群能力


DMSP 是一套基于 Kubernetes 集群的微服务运行平台。我们在 K8S 的基础上,基于 Operator 开发打造了一个完整的微服务生命周期管理体系。


整体上, DMSP 分成几个领域的能力来增强微服务:


领域说明
ServiceService相关的功能包括:
1、服务注册
2、多版本部署
3、AutoScaling
4、资源Quota管理
等workload相关的能力。

主要关注service mesh管控之下的workload生命周期,不属于mesh层有
RouteRoute是指服务路由控制相关的功能(区别于Traffic中的高级流量控制能力),主要包括:
1、金丝雀部署流量控制(按流量比例权重的灰度)
2、规则灰度(基于header、params等判断的规则灰度)
Security服务安全相关的管控,也包括一些全局的安全Filter:
1、CORS
2、CSRF
3、Ingress流量登录认证
4、Egress流量访问白名单
5、服务mTLS认证与访问权限控制(Authentication and Authorization)
TrafficTraffic中包含高级的流量控制能力,除了Route流量路由以外的其它功能,包括:
1、限流(Rate Limit)
2、熔断(Circuit Breaking)
3、镜像(Mirroring)
4、超时(Timeout)
5、故障注入(Fault Injection)
TelemetryTelemetry翻译过来是遥测,这里我们称为服务治理,包括:
1、访问跟踪(Tracing)
2、日志归集(Logging)
3、服务监控&访问统计(Metrics)
4、可视化(Visual)


DMSP Service Mesh 架构


基于上述集群能力的要求,我们将 Istio 的 Service Mesh 能力落地。整体架构如下:



下层 SOA 服务包括了 DataWorks 已有的许多重量级服务,包括租户、数据开发、AI 平台等。


DMS Console 是微服务管控台,它是微服务开发者与服务集群之间的管控交互唯一路径,负责管控所有(包括阿里巴巴内部、阿里云公有云 22 个 Region )的集群,前面提到的部署、流量控制与灰度、动态的安全策略、服务治理(日志 &监控 &报警)等能力都会在这里承上启下。


管控台与集群控制平面 Control Plane 之间的交互,完全基于 K8s ApiServer,通过抽象的一层 CRD 进行交互,再由特定的 Operator 基于 CRD 执行管控逻辑。透过对 Istio 的管控,基于服务 Sidecar 达到对服务能力的延展。业务服务就像插上了翅膀,无缝地获得了集群赋予的能力,用最小的开发成本,享受最多的最健全的微服务能力。


Why Operator and CRD?


扩展 K8s 的最佳实践,是以 Operator + CRD 的方式来实现扩展。


Operator:


https://kubernetes.io/docs/concepts/extend-kubernetes/operator/


基于 Kubernetes 的 Operator ,将服务部署和 Service Mesh 控制层面的工作直接前移到集群上,降低原本需要多集群多配置需求中心部署管控的复杂度



最终一致性保证


管控操作的可靠性强,能够保证最终一致性,依靠两个优势:


1、Operator 框架基于 K8s 的 Event&Watch 机制( Reconcile Cycle ),事件触发通过多发+幂等保证最终一致性。(而实际上幂等性不需要开发者过分关注,因为有下面第二个优势)。


2、 K8s Resource CRUD 的 Generation 机制能保证 CRD 操作的原子性


基于这两个优势,开发 Operator 时只需要专注于最终结果是什么,在任何情况下都往最终你想要的结果推进即可。


业务逻辑边界清晰


利用 Kubernates Operator 操作自定义的一套 CRD ,业务逻辑配置的复杂度降低了,将每一个业务逻辑抽象出一个 CRD 定义,业务功能边界清晰可维护,健壮性非常高。


管控链路安全可控


基于 CRD 的交互,集群不需要透出额外的控制接口,所有外部管控操作都可以基于原生的 apiserver 规范进行控制,完全可复用 k8s 的 rbac 体系,一定程度上也保证了管控链路的安全可靠,权限精细可控。


具体可参考 OpenShift 的这篇最佳实践:


https://blog.openshift.com/kubernetes-operators-best-practices/


对 Istio 的抽象设计


Istio 的 CRD 体系较为复杂,因此我们需要实现一层简单的控制平面,对 Istio 做一层抽象,用简单易懂的 API 做管控交互。


达到四两拨千斤的效果。例如:


基于 Istio 原生的控制配置,需要大约 100 行, 3 个 CRD 协作完成的控制,抽象的一层管控逻辑只需不到 10 行, 1 个 CRD :


spec:  service: myservice1  rules:  - version: "1.1"    weight: 70  - version: "1.2"    weight: 30  - version: "2.0"    weight: 100
复制代码


服务路由(Route)


微服务迭代迅速,开发敏捷。因此,金丝雀版本流量的精细化控制是集群建设的首要重点。


这也是我们常说的「版本灰度」,那么灰度能力的支持主要分为两种:


1、流量权重灰度


2、规则灰度


权重灰度


按比例调整到达服务特定版本的流量。


在这里,我们设计了大小版本,约定了开发流程中,每个大版本升级需要访问不同的域名 /ContextPath 。每个大版本下的小版本流量比例合为 100 。


示例:


spec:  service: httpbin  rules:  - version: "1.0"    weight: 80  - version: "1.1"    weight: 20  - version: "2.0"    weight: 100
复制代码


调整后,对服务流量监控进行可视化的效果:



规则灰度


按照特定的匹配规则,将服务流量定向到特定的版本。


spec:  service: myservice1  rules:  - version: "2.0"    matches:    - headers:        gray:          exact: "1"    - queryParams:        debug:          exact: "true"
复制代码


描述了当 header 中包含 gray=1 或者 query 参数中包含 debug=true 时,流量访问到版本 1.1 。


我们通过埋在 Response 中的 header ,就可以知道灰度的效果:



服务安全


服务安全针对流量方向分为 Mesh 出入口的南北流量管控和 Mesh 内部的东西流量管控:


1、南北流量主要利用 Ingress Gateway 的 VS 能力管控入口流量,基于 Sidecar + Egress Gateway 管控出口流量


2、东西流量需要通过 mTLS + AuthorizationPolicy 进行控制


通过这些手段来增强集群(尤其是公有云集群)中微服务的安全性。


Ingress 入流量


入口流量的一部分管控需求,在前文「服务路由」中包含。在服务安全方面,包括了全局上的能力,例如:


  • CORS 跨域配置

  • CSRF 保护

  • 流量登录认证


CORS 和 CSRF 基于 Sidecar Filter 即可覆盖统一的通用规则,做进一步的细化和动态配置的需求不强。


流量登录认证,主要用于认证前端访问流量的身份是否合法(没有涉及权限体系),会对接各个常用的登录体系,目前支持的主要是 DataWorks 自有的登录体系。


我们设计了一套灵活的认证框架,基于 Filter + 符合规范的认证服务的方式,达到登录认证的需求。


Egress 出流量


Egress 出流量是指访问 Mesh 网格之外的流量,例如,微服务访问阿里云 OSS 服务等操作。


为了防止服务被攻击后,访问未知的恶意网站,特别在高安全级别的集群环境,需要在默认情况下 0 信任任目标地址,再基于白名单的机制来打通特定的信任地址。


目前 Flannel 网络实现没有支持 NetworkPolicy ,阿里云 ACK 提供的集群默认是 flannel 网络(可选 terway 方式避免),所以基于 Pod 的 NetworkPolicy 不会生效,所以在 Istio 管控之外的 Pod 仍然需要防护,被 istio 管控的 pod 也暂时只有一层 istio 的安全机制保障


默认拒绝访问


配置 sidecar( mesh ) 访问所有 Service( Mesh 外部)的 outbound 流量都需要基于 ServiceEntry 注册才能够访问(即,默认拒绝所有连接)。


kind: IstioControlPlanespec:  gateways:    components:      egressGateway:        enabled: true  values:    global:      outboundTrafficPolicy:        mode: REGISTRY_ONLY
复制代码


配置生效之后,任何 pod 之间经过 SideCar 进行互相访问的流量都会检查是否注册过 ServiceEntry 。


未注册的服务效果如下:


$ kubectl exec -it sleep-788f7c9bcb-m67rh -c sleep -- curl -I www.aliyun.comHTTP/1.1 502 Bad Gateway
复制代码



502 的意思就是 DNS 和 IP 都通,但是访问会被 sidecar 拦截掉


观察流量可以看到,所有流量都到了 BlackHoleCluster ,一个专门用来接收被 block 的请求的内置 Cluster 。


PassthroughCluster 同理‍‍



白名单机制


然后,基于默认拒绝的策略,我们在这个基础之上增加白名单。


全局白名单


首先,ServiceEntry 这套 API 并没有 selector 支持对单独某些 workload 生效,一旦配置存在,就是全局有效的。它只支持 namespace 级别的隔离(基于 ExportTo 参数)。


我们将其抽象出一层动态配置,便于未来平滑支持更多的配置规则:


spec:  service: sleep  hosts:
- "www.aliyun.com"
复制代码


观察流量,可以看到所有流量都走了 Entry 定义的端点,访问得以放行:



服务访问控制


服务访问控制是指微服务之间的访问授权机制。在 0 信任网络中,默认是拒绝所有服务的访问。


在网格中, mTLS 机制用于服务之间身份校验,每个服务都有自己的基于 K8s 的 ServiceAccount ,根据 istio 提供的 mTLS 机制对证书进行身份校验。


因此,服务之间互相访问就有了身份的区别,那么就可以通过 AuthorizationPolicy 直接进行流量的权限控制。


配置默认拒绝:


apiVersion: security.istio.io/v1beta1kind: AuthorizationPolicymetadata:  name: deny-allspec:  {}
复制代码


生效后:403 RBAC: access denied 。


$ kubectl exec -it sleep-788f7c9bcb-m67rh -c sleep -- curl -i httpbin:8000/getHTTP/1.1 403 Forbiddencontent-length: 19content-type: text/plaindate: Mon, 13 Jan 2020 16:09:16 GMTserver: envoyx-envoy-upstream-service-time: 0RBAC: access denied
复制代码


未来


我们借助 Service Mesh 技术,构建了一套 DataWorks 定制化开放 API 的微服务 DevOps 体系。


希望通过我们的努力,能够极大地降低开发门槛,让业务接入更敏捷,让开发迭代更迅速。


未来, DataWorks 团队将提供更多面向微服务生态的管控和治理能力。


作者介绍


袁赓拓,花名三辰,阿里云智能-计算平台事业部技术专家,负责数加平台 &DataWorks 的微服务生态建设,目前主要关注微服务、Service Mesh 等相关技术方向。


本文转载自公众号阿里巴巴中间件(ID:Aliware_2018)。


原文链接


https://mp.weixin.qq.com/s/cD9kNstaUAbcRmySGVhL0w


2020 年 3 月 14 日 10:001646

评论

发布
暂无评论
发现更多内容

架构师训练营第 7 周学习总结

菜青虫

极客大学架构师训练营

第十一周学习总结

Meow

架构师训练营第十一周课程笔记及心得

Airs

架构师训练营第 7 周课后练习

菜青虫

极客大学架构师训练营

架构师训练营第 1 期 week11 总结

张建亮

极客大学架构师训练营

Architecture Phase1 Week11:HomeWork

phylony-lu

极客大学架构师训练营

Week7-性能优化-作业1

shuyaxx

架构师训练营week11作业

FG佳

极客大学架构师训练营

一文彻底搞懂前端监控

执鸢者

前端 前端监控

Week7 作业

evildracula

学习 架构

Architecture Phase1 Week11:Summarize

phylony-lu

极客大学架构师训练营

架构一期第十一周作业

Airs

架构师第二期 第7周总结

月下独酌

极客大学架构师训练营

11 安全稳定课后作业

ABS

架构师训练营第七周作业

李日盛

性能测试

第 7 周 系统架构作业

心在那片海

LeetCode题解:55. 跳跃游戏,贪心,JavaScript,详细注释

Lee Chen

算法 LeetCode 前端进阶训练营

第十一周作业

Meow

架构师训练营第2期 第7周命题作业

月下独酌

极客大学架构师训练营

架构师训练营 - 第 11 周课后作业(1 期)

阿甘

第 11 周 怎么又翻车了???

Pyr0man1ac

架构师训练营week11作业

陈皓07

架构师训练营第 1 期 -- 第十一周学习总结

发酵的死神

极客大学架构师训练营

Week7-性能优化-总结

shuyaxx

第十一周 架构方法学习总结 —— 安全稳定

兵长

安全架构 高可用架构

什么样的股权,才算“到手”?| 法庭上的CTO(3)

赵新龙

股权 CTO 法庭上的CTO

nodejs事件和事件循环简介

程序那些事

事件驱动 nodejs 事件循环 异步编程 程序那些事

架构师训练营第七周小结

韩儿

第 7 周 系统架构总结

心在那片海

架构师训练营第 1 期 week11

张建亮

极客大学架构师训练营

第 11 周 作业

Pyr0man1ac

DataWorks 微服务集群的 Service Mesh 落地实践-InfoQ