服务网格的最佳实践
微服務發展的這幾年,新的技術和概念層出不窮,這些技術的引入本質上都是在圍繞服務穩定性和業務開發效率提升,最近兩年服務網格越來越被廣大的微服務用戶所認知。
在 Kubernetes 已經成為云原生時代的操作系統的今天,如何更好的擁抱 Kubernetes 生態,實現業務快速上云,享受云計算帶來的能力,其中服務網格是一個必須要提的關鍵技術,但是在服務網格使用過程中我們會碰到很多的問題,比如:如何讓現有的應用遷移到服務網格,如何支持多種語言、框架的互通和治理,如何使用可觀測產品排查問題,接下來我將從如何接入服務網格、異構服務框架、語言的互通和可觀測三個方面回答這個問題。
遷移應用到服務網格中
服務網格
服務網格是用于處理服務間通信的專用基礎設施層,它負責通過包含現代云原生應用程序的復雜服務拓撲來可靠地傳遞請求。實際上,服務網格通常通過一組輕量級網絡代理來實現,這些代理與應用程序代碼一起部署,而不需要感知應用程序本身。
目前主流的服務網格開源軟件是 Istio,其整體架構如下:
從圖中可以看到服務網格與業務容器是在同一個 Pod 中的不同容器,帶來的優勢有如下三點:
1.微服務治理與業務邏輯的解耦。服務網格把 SDK 中的大部分能力從應用中剝離出來,拆解為獨立進程,以 Sidecar 的模式進行部署,服務網格通過將服務通信及相關管控功能從業務程序中分離并下沉到基礎設施層,使其和業務系統完全解耦,使開發人員更加專注于業務本身。
2.異構語言/框架的統一治理。隨著新技術的發展和人員更替,在同一家公司中往往會出現不同語言、不同框架的應用和服務,為了能夠統一管控這些服務,以往的做法是為每種語言、每種框架都開發一套完整的 SDK,維護成本非常之高,而且給公司的中間件團隊帶來了很大的挑戰,有了服務網格之后,通過將主體的服務治理能力下沉到基礎設施,多語言的支持就輕松很多了。
3.服務網格不但可以承擔流量代理,對于業務共用的、通用的場景和需求都可以成為服務網格的一部分,這樣能有效提高業務開發效率。
應用接入服務網格
目前服務網格對 Kubernetes 支持最完整,同時也支持了 VM 的應用接入,但是需要較多的配置,我們推薦首先將 VM 上的服務容器化后在接入網格中,逐步遷移已有的應用,通過網關來打通服務網格中的應用和 VM 中沒有接入服務網格的應用。
服務網格的接入首先是需要安裝 Istiod,然后通過對 Namespace 打標來完成 Sidecar 的自動注入,可以選擇性的對一些服務不進行 Sidecar 的注入,比如類似 MySQL、Redis 等中間件應用,主要是減少 Envoy 帶來的延遲,在 EDAS 中可以針對每個應用進行打標,對需要加入服務網格的應用才進行 Sidecar 的注入。
異構微服務的互通、治理
由于業務的發展,基于業務產品的選擇,業務開發語言越來越多種多樣,這些語言之間的互通成為大家關注的問題,目前常見的場景如 Java 語言和非 Java 語言的互通,互通中最重要的問題就是服務發現和通信協議的支持。
服務發現
通常我們在使用 Kubernetes 上部署服務如下,其中定義了 Kubernetes Service 用于服務間請求的域名:
apiVersion: apps/v1 kind: Deployment metadata:name: details-v1labels:app: detailsversion: v1 spec:replicas: 1selector:matchLabels:app: detailsversion: v1template:metadata:labels:app: detailsversion: v1spec:containers:- name: detailsimage: docker.io/istio/examples-bookinfo-details-v1:1.16.2imagePullPolicy: IfNotPresentports:- containerPort: 9080apiVersion: v1 kind: Service metadata:name: detailslabels:app: detailsservice: details spec:ports:- port: 9080name: httpselector:app: detailsIstio 監聽 Kubernetes Api Server,獲取服務的 Service、Pod 等數據,通過 XDS 方式提供給 Envoy,Envoy 會通過獲取的數據做負載均衡。
很多微服務框架都在使用如 Nacos、Consul、Zookeeper 等注冊中心,這部分微服務如何在不進行大規模改造下使用服務網格呢,這就設計到 Istiod 跟注冊中心的打通,目前社區提供了以下的幾種方式實現注冊中心數據打通:
1.MCP Server
編寫自定義的 MCP Server 從第三方注冊中心獲取服務數據,轉換為 ServiceEntry 和 WorkloadEntry 資源,通過 MCP 協議提供給 Istio 中的 MCP Config Controller, Istiod 需要配置MCP Server地址,目前在開源項目中包含 MCP Server 的注冊中心的有很多,阿里云 MSE 提供托管的 Nacos 注冊中心,直接提供 MCP Server 能力。
2.ServiceEntry 和 WorkloadEntry
編寫獨立的第三方組件,該組件從注冊中心中獲取服務數據,然后轉換為 Istio 中 ServiceEntry 和 WorkloadEntry CRD,寫入到 Kubernetes API Server 中。Pilot 的 Kube Controller 會監聽 Kubernetes API Server 中和 Istio 相關資源的變化,并將 ServiceEntry 和 WorkloadEntry 轉換為內部Service模型,通過Xds協議同步給Sidecar。
3.自定義適配器
編寫自定義的 Adapter 來集成第三方注冊中心,該適配器從注冊中心中獲取服務和服務實例,轉換為 Pilot 內部的Service模型,集成到 Service Controller 中,類似現有的Consul Service Registry的適配方式,這種方式的優點就是不需要通過第三方進行轉換,但是跟Istio耦合在一起,在 Istio 版本升級較快的時候,需要不斷的適配對應的新版本。
MSE 注冊中心
第一種方式需要注冊中心提供支持,第二種方式需要獨立的三方組件進行同步,可用性、維護是一個負擔,第三種需要對 Istio 非常熟悉,維護升級成本很高,目前 MSE 注冊中心已經支持 MCP Over XDS 的方式對接 Istio,可用性高,免維護。
我們通過 Java Agent 支持Xds協議的方式對接 Istio,同時 Istio 也通過 MCP Over XDS 對接 Nacos 注冊中心,這樣服務發現的數據在 Java Agent 和 Sidecar 中都能拿到, Java 和非 Java 的服務可以互相發現,互相調用。
服務網格的服務治理
服務網格 Sidecar 通過容器的方式與業務容器共享網絡,通過Iptables的方式將 inbound 和 outbound 流量都劫持到 Sidecar 上,Sidecar 解析數據包,獲取請求后通過匹配服務發現數據找到對應的服務端,然后匹配對應的路由規則找到滿足條件的服務端發送請求。
服務網格的服務治理中Istio的路由規則最關鍵的兩個CRD是VirtualService和DestinationRule,他們描述了請求匹配、路由的過程,如下所示:
apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata:name: reviews spec:host: reviewssubsets:- name: v1labels:version: v1- name: v2labels:version: v2- name: v3labels:version: v3 --- apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata:name: reviews spec:hosts:- reviewshttp:- route:- destination:host: reviewssubset: v1DestinationRule 中包含了 reviews 服務的三個版本,VirtualService 描述了對 reviews 服務的請求會發送到 subset 為 v1 的版本中。其他的服務治理能力還包括了故障注入、服務鑒權、服務超時、熔斷等,可以通過寫入對應的規則來完成,目前Istio也沒有提供非常好使用的白屏化服務治理界面,在 EDAS/MSE 中提供白屏界面操作如服務鑒權、服務查詢、離群摘除、金絲雀發布等,保證在操作過程中流量不丟失,路由規則的操作需要遵循以下幾個原則:
1、通常使用服務網格服務治理的最佳實踐方式是從一開始就為每一個服務創建具有默認路由的 VirtualService,即當你只有一個版本的時候,就寫入該版本的 VirtualService 規則,這樣在你部署第二個版本中,不至于流量會打到第二個版本中,需要配置路由規則才可以,保證新版本驗證過程中不會出現由于新版本自身問題導致的大規模報錯。
2、VirtualService 和 DestinationRule 在使用的過程中,Envoy 會首先查看 VirtualService 中的路由規則,以決定是否路由到特定的子集去,只有路由到對應的子集才會激活在 DestinationRule 中對應子集配置的如熔斷、離群摘除等規則,同時可以看出 VirtualService 和DestinationRule 的配置也是有順序的,首先配置 DestinationRule,然后在配置 VirtualService,否則會導致找不到對應的 Subset 報錯。
3、更新 DestinationRule 添加一個新的 Subset 后,需要等待 DestinationRule 傳播到 Envoy Sidecar,然后再更新對應的 VirtualService。
雙模微服務治理
互通的問題通過對接注冊中心的方式解決了,那異構框架的服務治理則通過 MSE 來支持,MSE 的服務治理中心可以對接 Java 服務,同時也可以支持服務網格的服務。
MSE 在控制面上支持雙模微服務治理,即 Java 服務治理和非 Java 服務治理,控制面對外提供統一的治理模型,我們參考 Istio 的路由規則設計模型,提出一個統一的服務治理規則模型,模型的設計主要考慮到 Dubbo、Spring Cloud 和服務網格治理的通用性。
{"RegisterConfig":Object{...},"protocol":"springcloud","rule_type":"fault_inject","rule":{"hosts":Array[1],"rule_policy":[{"match":Array[1],"fault":Object{...},"route":Array[1],"Timeout":"10s","retries":Object{...},"mirror":Object{...},"mirror_percent":100,"headers":Object{...},"tls":Object{...}},{"route":[{"destination":Object{...},"weight":"100","headers":Object{...}}]}]} }上述模型中包含了注冊中心、協議、規則類型、路由規則,路由規則中包含了匹配的規則和路由的目的地,MSE通過生成對應這樣的CRD來定義不同類型的路由規則,Java Agent 的和服務網格都可以通過監聽這樣的 CRD 來管理自己的流量,后續我們也會在 OAM 中推出這一套微服務治理規則,用于統一服務治理模型。
MSE微服務治理
服務查詢:
標簽路由:
離群實例摘除:
可觀測
社區開源方案
可觀測是微服務能力的重要組成部分,服務網格可以跟目前開源的可觀測產品結合,可觀測性上主要圍繞 Metrics、Tracing 和 Logging 來展開,在 Metrics 上提供數據供 Prometheus 采集,在 Tracing上,Istio 支持 Apache SKyWalking、Zipkin、Jaeger 的鏈路追蹤,這三個中間件都支持 OpenTracing 協議,在 Logging 上,對于日志采集組件的要求也越來越高,目前比較流行的方案是使用 Fluentd 或者 Filebeat 替代 Logstash。
阿里云 EDAS 方案
阿里云 Xtrace 為服務網格提供可觀測能力,包含鏈路追蹤、應用概覽、拓撲、Metrics 統計,在應用發布后直接可以通過應用詳情查看,如下圖所示:
拓撲圖如下:
可以通過鏈路追蹤查看每個請求過程中的問題,協助問題定位,同時 Xtrace 也提供了不同語言的 SDK,接入 SDK 后可以查看更細粒度的數據。
原文鏈接:https://developer.aliyun.com/article/781566?
版權聲明:本文內容由阿里云實名注冊用戶自發貢獻,版權歸原作者所有,阿里云開發者社區不擁有其著作權,亦不承擔相應法律責任。具體規則請查看《阿里云開發者社區用戶服務協議》和《阿里云開發者社區知識產權保護指引》。如果您發現本社區中有涉嫌抄襲的內容,填寫侵權投訴表單進行舉報,一經查實,本社區將立刻刪除涉嫌侵權內容。總結
- 上一篇: 传统企业如何在数字化时代实现进化?
- 下一篇: DataX在数据迁移中的应用