Cloud Native未來值得關注的方向:Service Mesh簡介
導讀:本文簡單介紹了Service Mesh出現的基本理念,對其關鍵元件做了對比分析。同時也對istio這一Service Mesh關鍵元件做了架構分析。
王啟軍,目前就職於華為公司架構部,負責華為公司的Cloud Native、微服務架構推進落地,前後參與了華為手機祥雲4.0、物聯網IoT 2.0的架構設計。曾任知名電商平臺架構師,主導電商平臺架構設計,包括訂單、支付、價格、庫存、物流等。曾就職於搜狐,負責手機微博的研發。十餘年的技術歷練,也曾作為技術負責人帶領過近百人的團隊。公眾號“奔跑中的蝸牛”的作者。
1.1 Service Mesh
1.1.1 什麼是Service Mesh
Service Mesh是最近才興起的一個名詞,最早在2016年9月29日由開發Linkerd的Buoyant公司首次提出[1]。2016年10月,Alex Leong開始在Buoyant公司的官方部落格中連載一系列關於“A Service Mesh for Kubernetes”的文章。隨著2017年Linkerd加入CNCF,Service Mesh開始大規模出現在各個技術論壇。Service Mesh在國內被翻譯為“服務齧合層”或“服務網格”。那到底什麼是Service Mesh呢?目前比較公認的是Buoyant的CEO William Morgan在部落格中給出的定義[2],具體描述如下。
Service Mesh是用於處理服務到服務通訊的專用基礎架構層。Cloud Native有著複雜的服務拓撲,它負責可靠的傳遞請求。實際上,Service Mesh通常作為一組輕量級網路代理實現,這些代理與應用程式程式碼部署在一起,應用程式無感知。
隨著Cloud Native的崛起,Service Mesh逐步發展為一個獨立的基礎設施層。在Cloud Native架構下,單個應用程式可能由數百個服務組成;每個服務可能有數千個例項;並且這些例項中的每一個例項都可能處於不斷變化的狀態,因為它們是由諸如Kubernetes之類的資源排程系統動態排程的。這個世界中的服務通訊不僅非常複雜,而且是執行時行為的普遍和基本部分,管理它對於確保端到端的效能和可靠性至關重要。
Azure的雲設計模式庫中,也描述了類似的模式,名為Sidecar[3],這個概念很形象。就是我們以前在戰爭片中看到的那種挎斗車,如圖8-2所示。
在模式庫中,Sidecar被這樣描述:
-
將應用程式的元件部署到單獨的程序或容器中以提供隔離和封裝。這種模式還可以使應用程式由異構元件和技術組成。
-
這種模式被命名為Sidecar,因為它類似於連線到摩托車的邊車。在該模式中,輔助車被附加到父應用程式併為應用程式提供支援功能。邊車也與父應用程式共享相同的生命週期,與父程序一起被建立和退出。
簡單來說,Service Mesh幫助應用程式在海量服務、複雜的架構和網路中建立穩定的通訊機制,業務所有的流量都轉發到Service Mesh的代理服務中,不僅如此,Service Mesh還承擔了微服務框架所有的功能,包括服務註冊發現、負載均衡、熔斷限流、認證鑑權、快取加速等能力。不同的是,Service Mesh強調的是通過獨立的程序代理的方式,除此之外,還承擔了上報日誌、監控的責任。Service Mesh架構,如圖8-3所示。
1.1.2 為什麼需要Service Mesh
Service Mesh的出現是由微服務架構推動的,原本一個應用,被拆分成幾百個甚至幾萬個應用,服務治理面臨這巨大的挑戰。這個時候,微服務框架出現,例如,Finagle、Dubbo、Spring Cloud、Netflix OSS等。這些框架都是基於客戶端負載均衡、直連的方式,此方案的優勢是效能高、應用性好,如Dubbo,如果你使用Java語言,可以直接引入JAR包,通過簡單的配置,就可以實現微服務之間的通訊。
歸根結底,在微服務架構中,我們要解決的問題是讓開發人員感覺不到微服務之間的通訊。當服務數量越來越多,升級微服務框架變得越來越複雜的時候,你不可能要求微服務框架一直不變,而且是沒有bug的。在技術更新速度如此之快的年代,就更不可能了。因此,微服務框架的部分功能開始逐步向服務端移動,希望客戶端可以儘量“薄”,但是客戶端不可能無限制的“薄”,剩餘部分仍然比較“厚”。
因為使用客戶端更像一種交付的模式,不容易變更,控制力較差,而Service Mesh則從業務程序整合客戶端的方式,演進為獨立程序的方式,也就是說,原本的客戶端變成了一個獨立程序。對這個獨立程序升級、運維要比綁在一起強得多。
微服務架構更強調去中心化、獨立自治、跨語言,但是通常微服務框架限制了這一點,不可能為每種語言都實現一個框架,要麼都用一種語言,要麼實現多種語言的框架。而Service Mesh通過獨立程序的方式進行了隔離,可以低成本實現跨語言。
隨著Docker及Kubernetes的崛起,微服務的部署模式開始發生轉變,越來越趨向於輕量級,越來越強調隔離自治。每個服務獨立佔用一個容器,將服務、依賴包、作業系統、監控運維所需的代理打包成一個映象。這種模式促成了Service Mesh的發展,讓Service Mesh實現起來更容易。否則開發人員需要額外維護Service Mesh程序,就非常麻煩了。
1.1.3 Service Mesh的現狀
目前Service Mesh的框架如雨後春筍般快速湧現,以下幾個框架是目前為止被提到次數最多的。
Linkerd
2016年1月15日,Twitter前基礎設施工程師William Morgan和Oliver Gould組建了一個名為Buoyant的公司,同時在GitHub上釋出了Linkerd 0.0.7版本。它由Scala實現,業界第一個Service Mesh專案誕生。2016年下半年,Linkerd陸續釋出了0.8和0.9版本,宣佈支援HTTP/2和gRPC。2017年1月23日,Linkerd加入CNCF。2017年4月25日,Linkerd釋出了1.0版本。
Linkerd在生產環境得到了大規模使用,但是隨著Istio的誕生,Linkerd開始走下坡路。由於Istio背後有強大的Google和IBM的支援,社群非常活躍,雖然到目前為止還沒有大規模使用,但是業界已將Istio列為第二代Service Mesh。2017年7月11日,Linkerd迫於壓力釋出版本1.1.1,宣佈和Istio專案整合,但是Linkerd在Istio中替代Envoy的難度非常大,前景並不是特別樂觀。
Envoy
2016年9月13日,Lyft的Matt Klein宣佈Envoy在GitHub開源,釋出1.0.0版本。Envoy由C++實現,效能和資源消耗上非常出色。和Linkerd相比,Envoy發展得更平穩,被Istio收編之後,Envoy專注於資料平面。2017年9月14日,Envoy加入CNCF,成為CNCF繼Linkerd之後的第二個Service Mesh專案。目前,Envoy已用於生產系統中,據Lyft介紹:“Envoy在Lyft上可以管理一百多個服務,跨域上萬臺虛擬機器,每秒可處理近兩百萬次請求。”
nginMesh
2017年9月,在波特蘭舉行的nginx.conf大會上,Nginx宣佈了nginMesh在GitHub上釋出了0.1.6版本。nginMesh的定位是作為Istio的服務代理,也就是專注於資料平面,替代Envoy,和Linkerd與Istio整合的思路一致。nginMesh的發展一直比較緩慢,目前它還沒有應用到生產環境中。
Conduit
由於Buoyant在Linkerd上受到Istio壓制,2017年12月5日,Buoyant在KubeConf上釋出了Conduit 0.1.0版本,作為Istio的競爭產品。Conduit的架構幾乎和Istio一樣,也分成了資料平面和控制平面,為了效能和資源佔用方面的優勢,它直接採用Rust語言開發。Conduit也被稱為第二代Service Mesh。
Istio
2017年5月24日,Istio 0.1版本釋出,目前已經到了0.7版本。Istio背後是強大的Google和IBM,所以Istio自誕生之日起就備受矚目。Istio的初期版本只支援Kubernetes平臺,從0.3版開始支援非Kubernetes平臺,可以獨立執行。
雖然它的架構思想被很多人認同,功能也很多,但是Istio的問題仍然較多,可用性較差,幾乎沒有生產級的案例。儘管如此,Istio被認為是Service Mesh的未來,很多公司都在跟隨這個框架。
實際上,如果在一個小公司,Service Mesh的優勢體現的並不是十分明顯。例如小公司很少會考慮採用多語言,因為多一種語言就意味著要分散額外的精力進行維護,所以到目前為止,大多數公司在後端只使用一兩種語言。另外,微服務框架相對來說比較穩定,就如同Spring Framework一樣,不會輕易進行不相容的升級,只要保持好節奏,問題不會太多。因此,像Netflix、阿里這樣的公司,基本上還是沿用類似Spring Cloud的模式。
此外,Service Mesh降低開發人員的門檻也並沒有那麼明顯,因為完全不考慮是不可能的,Service Mesh在沒有理解業務的情況下,是不能私自做決定的。例如A服務呼叫B服務的超時時間,設定多少合理呢?還是需要開發人員根據業務進行配置的。
另外,Service Mesh對業務開發人員友好,但是基礎設施層的研發會更復雜,需要依賴更多的服務、元件,否則將帶來極大的架構、運維複雜度。對於很多公司來說,門檻稍高,且需要投入成本。
因此,對於絕大多數公司來說,Service Mesh並不具備壓倒性的優勢,在沒有成熟起來以前,大多都是觀望狀態。
1.1.4 Istio架構分析
Istio架構如圖8-4所示。Istio從邏輯上可以分為資料平面(Data Plane)和控制平面(Control Plane)。如果用服務化框架類比Istio,那麼控制平面可以認為是註冊中心及管理配置面板,資料平面可以認為是服務化框架依賴的元件獨立而成的一個程序,資料平面代理業務服務的註冊發現、負載均衡、容錯等能力。
資料平面也就是代理,使用Envoy實現,獨立程序,和業務服務部署在一起,主要是管理微服務之間的網路通訊及執行控制平面下發的指令。Envoy支援的通訊協議包括:HTTP/1.1、HTTP/2、gRPC、TCP等,它支援TLS。
控制平面負責管理和配置這些代理,並動態執行策略。主要包括三個部分,分別是Pilot、Mixer、Istio-Auth,都是有Go語言開發。
Pilot主要的責任就是管理Envoy例項的生命週期。Pilot通過Envoy API接入Envoy例項,主要是服務發現以及流量控制。運維人員可以通過Rules API自定義流量管理規則,轉化為配置資訊下發到Envoy,Envoy例項按照自定義的規則執行流控。從理論上說,Pilot抽象了模型,通過介面卡可以適配Kubernetes、Mesos、CloudFoundry等平臺,但是目前只支援Kubernetes。Pilot架構如圖8-5所示。
利用Pilot可以輕鬆實現流量控制,如限流、灰度釋出、熔斷等能力。圖8-6中的配置代表了Pilot分發到v1版本75%的流量,分發到v2版本25%的流量。
此外,利用Pilot還可以輕鬆的注入故障。圖8-7中的示例就表示選擇“reviews”服務的“v1”版本的10%的請求中引入5秒的延遲。
Mixer負責通過策略進行訪問控制,並從Envoy代理收集資料,代理提取請求級屬性,傳送到Mixer進行決策。要理解Mixer,首先需要理解Istio中屬性的意義。屬性是具有名稱和型別的元資料片段,用來描述流量和這些流量所在的上下文環境。請求的路徑、大小、時間、源IP地址及目標服務如下所示。
request.path: blog/article
request.size: 200
request.time: 13:34:56.789 04/17/2018
source.ip: 10.10.0.1
target.service: article
Mixer提供如下三個核心功能。
-
校驗。在響應之前,先驗證呼叫者的身份、是否在服務的白名單、是否通過ACL檢查等。
-
配額。例如訪問頻率控制。當服務消費者對有限的資源進行爭搶時,配額就成了一種有效的資源管理工具,它為服務之間的資源搶佔提供相對的公平。
-
報告。使服務通過Envoy上報日誌和監控。
Istio Auth的目標是在不修改業務服務程式碼的前提下,提升業務服務之間通訊的安全性。Istio Auth利用secret volume mount,從Istio CA向Kubernetes容器傳遞keys/certs。由於Envoy代理一切流量,因此Envoy客戶端和Envoy服務端之間使用TLS非常簡單。Istio Auth為我們提供的能力如下。
-
每個服務都可以被設定身份,代表其角色,以實現跨叢集和雲的互通性。
-
可以加密服務間通訊和終端使用者到服務的通訊。
-
提供金鑰管理系統來自動執行金鑰和證書的生成、分發、輪換和撤銷。
在很多場景下,微服務通常不對外網開放訪問許可權,只有邊緣服務才會通過API Gateway進行開放,而加密往往意味著效能的降低,因此通常會選擇不加密,除非部署的環境比較特殊。
文中註釋:
[1] 2016年1月15日,離開Twitter的基礎設施工程師William Morgan和Oliver Gould,在GitHub上釋出了Linkerd 0.0.7版本,他們同時組建了一個創業公司Buoyant,業界第一個Service Mesh專案在這個公司誕生。
[2] 來自https://blog.buoyant.io/2017/04/25/whats-a-service-mesh-and-why-do-i-need-one/
[3] 來自https://docs.microsoft.com/en-us/azure/architecture/patterns/sidecar
[4] 來自圖片來自http://www.atobo.com.cn/Products/Detailed/5618736.html
[5] 圖片來自https://istio.io/docs/concepts/what-is-istio/overview/
[6] 圖片來自https://istio.io/docs/concepts/traffic-management/pilot/
本文節選自電子工業出版社《持續演進的Cloud Native:雲原生架構下微服務最佳實踐》第 8 章,由電子工業出版社博文視點授權。基於篇幅的考慮,部分內容進行了簡化,想了解本書全部詳細內容,可以在各大書店購買。