Categories
程式開發

DataWorks 微服務集群的 Service Mesh 落地實踐


初心

DataWorks 是集團內外廣泛使用的全域智能大數據平台,包含了DataStudio、StreamStudio、HoloStudio、AppStudio、GraphStudio、PAIStudio、WebExcel 等眾多的線上產品,每個產品都是類似於IDE 形態的富交互單頁應用。

DataWorks 微服務集群的 Service Mesh 落地實踐 1

但是,DataWorks 服務於集團各大業務線上萬名數據開發者和數據生態的參與者,這艘巨大的航母卻不能準確地表達每一個用戶的述求,「眾口難調」。

因此,DataWorks 在架構升級的關鍵節點,決心將插件化、服務化定制的能力徹底落地,解開過重的業務共建模式在研發上的耦合羈絆,向更輕量的更開放的平台化邁進,不忘服務初心,幫助我們內外客戶的業務定制快速落地。

那麼如何開放 DataWorks 的定制化能力?

我們建立了一整套完整的微服務研發管控體系, DataWorks 微服務平台(DMSP:DataWorks MicroService Platform),以滿足業務開發者定制服務化需求,幫助業務整合DataWorks輸出的中台能力,重新定義屬於自己的業務數據研發平台。

輕車快馬

輕裝上陣,是對用戶(開發者、業務方)而言的。要做到用戶的輕,作為平台方,我們就要做得更多。

對於業務而言,最輕量的,就是「只需要關注業務邏輯」。

即,業務開發者僅僅專注在業務邏輯上,而不需要再自己關注入流量的安全認證、路由、負載均衡、鏡像、限流;出流量的超時、重試、訪問控制;服務間調用的隔離策略、熔斷、分佈式追踪等與業務邏輯無關的內容。

過去,微服務生態周邊發展出了大量組件、框架,幫助我們很好地解決上述的業務以外的問題。但是這些組件框架門檻高、維護成本高、開發語言耦合,對於大多數開發者而言,成本太高,不適用於有敏捷開發需求的新興業務。

近年來火熱的服務網格(Service Mesh)技術,正能夠解開這一困局。參見《Service Mesh 入門》

微服務集群能力

DMSP 是一套基於 Kubernetes 集群的微服務運行平台。我們在K8S的基礎上,基於 Operator 開發打造了一個完整的微服務生命週期管理體系。

整體上, DMSP 分成幾個領域的能力來增強微服務:

領域 說明
Service Service相關的功能包括:
1、服務註冊
2、多版本部署
3、AutoScaling
4、資源Quota管理
等workload相關的能力。

主要關注service mesh管控之下的workload生命週期,不屬於mesh層有

Route Route是指服務路由控制相關的功能(區別於Traffic中的高級流量控制能力),主要包括:
1、金絲雀部署流量控制(按流量比例權重的灰度)
2、規則灰度(基於header、params等判斷的規則灰度)
Security 服務安全相關的管控,也包括一些全局的安全Filter:
1、CORS
2、CSRF
3、Ingress流量登錄認證
4、Egress流量訪問白名單
5、服務mTLS認證與訪問權限控制(Authentication and Authorization)
Traffic Traffic中包含高級的流量控制能力,除了Route流量路由以外的其它功能,包括:
1、限流(Rate Limit)
2、熔斷(Circuit Breaking)
3、鏡像(Mirroring)
4、超時(Timeout)
5、故障注入(Fault Injection)
Telemetry Telemetry翻譯過來是遙測,這裡我們稱為服務治理,包括:
1、訪問跟踪(Tracing)
2、日誌歸集(Logging)
3、服務監控&訪問統計(Metrics)
4、可視化(Visual)

DMSP Service Mesh 架構

基於上述集群能力的要求,我們將 Istio 的 Service Mesh 能力落地。整體架構如下:

DataWorks 微服務集群的 Service Mesh 落地實踐 2

下層 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 控制層面的工作直接前移到集群上,降低原本需要多集群多配置需求中心部署管控的複雜度

DataWorks 微服務集群的 Service Mesh 落地實踐 3

最終一致性保證

管控操作的可靠性強,能夠保證最終一致性,依靠兩個優勢:

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

調整後,對服務流量監控進行可視化的效果:

DataWorks 微服務集群的 Service Mesh 落地實踐 4

規則灰度

按照特定的匹配規則,將服務流量定向到特定的版本。

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 ,就可以知道灰度的效果:

DataWorks 微服務集群的 Service Mesh 落地實踐 5

服務安全

服務安全針對流量方向分為 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: IstioControlPlane
spec:
  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.com
HTTP/1.1 502 Bad Gateway

502 的意思就是 DNS 和 IP 都通,但是訪問會被 sidecar 攔截掉

觀察流量可以看到,所有流量都到了 BlackHoleCluster ,一個專門用來接收被block的請求的內置 Cluster 。

PassthroughCluster 同理‍‍

DataWorks 微服務集群的 Service Mesh 落地實踐 6

白名單機制

然後,基於默認拒絕的策略,我們在這個基礎之上增加白名單。

全局白名單

首先,ServiceEntry 這套 API 並沒有 selector 支持對單獨某些 workload 生效,一旦配置存在,就是全局有效的。它只支持 namespace 級別的隔離(基於 ExportTo 參數)。

我們將其抽像出一層動態配置,便於未來平滑支持更多的配置規則:

spec:
  service: sleep
  hosts:

  - "www.aliyun.com"

觀察流量,可以看到所有流量都走了 Entry 定義的端點,訪問得以放行:

DataWorks 微服務集群的 Service Mesh 落地實踐 7

服務訪問控制

服務訪問控制是指微服務之間的訪問授權機制。在0信任網絡中,默認是拒絕所有服務的訪問。

在網格中, mTLS 機制用於服務之間身份校驗,每個服務都有自己的基於 K8s 的 ServiceAccount ,根據 istio 提供的 mTLS 機制對證書進行身份校驗。

因此,服務之間互相訪問就有了身份的區別,那麼就可以通過 AuthorizationPolicy 直接進行流量的權限控制。

配置默認拒絕:

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: deny-all
spec:
  {}

生效後:403 RBAC: access denied 。

$ kubectl exec -it sleep-788f7c9bcb-m67rh -c sleep -- curl -i httpbin:8000/get
HTTP/1.1 403 Forbidden
content-length: 19
content-type: text/plain
date: Mon, 13 Jan 2020 16:09:16 GMT
server: envoy
x-envoy-upstream-service-time: 0
RBAC: access denied

未來

我們藉助 Service Mesh 技術,構建了一套 DataWorks 定制化開放 API 的微服務 DevOps 體系。

希望通過我們的努力,能夠極大地降低開發門檻,讓業務接入更敏捷,讓開發迭代更迅速。

未來, DataWorks 團隊將提供更多面向微服務生態的管控和治理能力。

作者介紹

袁賡拓,花名三辰,阿里雲智能-計算平台事業部技術專家,負責數加平台 &DataWorks 的微服務生態建設,目前主要關注微服務、Service Mesh 等相關技術方向。

本文轉載自公眾號阿里巴巴中間件(ID:Aliware_2018)。

原文鏈接

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