談談微服務架構中的基礎設施:Service Mesh與Istio

微服務架構的演進

作為一種架構模式,微服務將復雜系統(tǒng)切分為數十乃至上百個小服務,每個服務負責實現(xiàn)一個獨立的業(yè)務邏輯。這些小服務易于被小型的軟件工程師團隊所理解和修改,并帶來了語言和框架選擇靈活性,縮短應用開發(fā)上線時間,可根據不同的工作負載和資源要求對服務進行獨立縮擴容等優(yōu)勢。

另一方面,當應用被拆分為多個微服務進程后,進程內的方法調用變成了了進程間的遠程調用。引入了對大量服務的連接、管理和監(jiān)控的復雜性。

該變化帶來了分布式系統(tǒng)的一系列問題,例如:

如何找到服務的提供方?

如何保證遠程方法調用的可靠性?

如何保證服務調用的安全性?

如何降低服務調用的延遲?

如何進行端到端的調試?

另外生產部署中的微服務實例也增加了運維的難度,例如:

如何收集大量微服務的性能指標已進行分析?

如何在不影響上線業(yè)務的情況下對微服務進行升級?

如何測試一個微服務集群部署的容錯和穩(wěn)定性?

這些問題涉及到成百上千個服務的通信、管理、部署、版本、安全、故障轉移、策略執(zhí)行、遙測和監(jiān)控等,要解決這些微服務架構引入的問題并非易事。

讓我們來回顧一下微服務架構的發(fā)展過程。在出現(xiàn)服務網格之前,我們最開始在微服務應用程序內理服務之間的通訊邏輯,包括服務發(fā)現(xiàn)、熔斷、重試、超時、加密、限流等邏輯。

在一個分布式系統(tǒng)中,這部分邏輯比較復雜,為了為微服務應用提供一個穩(wěn)定、可靠的基礎設施層,避免大家重復造輪子,并減少犯錯的可能,一般會通過對這部分負責服務通訊的邏輯進行抽象和歸納,形成一個代碼庫供各個微服務應用程序使用,如下圖所示:

公共的代碼庫減少了應用程序的開發(fā)和維護工作量,降低了由應用開發(fā)人員單獨實現(xiàn)微服務通訊邏輯出現(xiàn)錯誤的機率,但還是存在下述問題:

微服務通訊邏輯對應用開發(fā)人員并不透明,應用開發(fā)人員需要理解并正確使用代碼庫,不能將其全部精力聚焦于業(yè)務邏輯。

需要針對不同的語言/框架開發(fā)不同的代碼庫,反過來會影響微服務應用開發(fā)語言 和框架的選擇,影響技術選擇的靈活性。

隨著時間的變化,代碼庫會存在不同的版本,不同版本代碼庫的兼容性和大量運行環(huán)境中微服務的升級將成為一個難題。

可以將微服務之間的通訊基礎設施層和TCP/IP協(xié)議棧進行類比。TCP/IP協(xié)議棧為操作系統(tǒng)中的所有應用提供基礎通信服務,但TCP/IP協(xié)議棧和應用程序之間并沒有緊密的耦合關系,應用只需要使用TCP/IP協(xié)議提供的底層通訊功能,并不關心TCP/IP協(xié)議的實現(xiàn),如IP如何進行路由,TCP如何創(chuàng)建鏈接等。

同樣地,微服務應用也不應該需要關注服務發(fā)現(xiàn),Load balancing、Retries、Circuit Breaker等微服務之間通信的底層細節(jié)。如果將為微服務提供通信服務的這部分邏輯從應用程序進程中抽取出來,作為一個單獨的進程進行部署,并將其作為服務間的通信代理,可以得到如下圖所示的架構:

因為通訊代理進程伴隨應用進程一起部署,因此形象地把這種部署方式稱為“Sidecar”/邊車(即三輪摩托的挎斗)。

應用間的所有流量都需要經過代理,由于代理以Sidecar方式和應用部署在同一臺主機上,應用和代理之間的通訊可以被認為是可靠的。由代理來負責找到目的服務并負責通訊的可靠性和安全等問題。

當服務大量部署時,隨著服務部署的Sidecar代理之間的連接形成了一個如下圖所示的網格,該網格成為了微服務的通訊基礎設施層,承載了微服務之間的所有流量,被稱之為Service Mesh(服務網格)。

服務網格是一個基礎設施層,用于處理服務間通信。云原生應用有著復雜的服務拓撲,服務網格保證請求可以在這些拓撲中可靠地穿梭。在實際應用當中,服務網格通常是由一系列輕量級的網絡代理組成的,它們與應用程序部署在一起,但應用程序不需要知道它們的存在。?

William Morgan ,?WHAT’S A SERVICE MESH? AND WHY DO I NEED ONE?

服務網格中有數量眾多的Sidecar代理,如果對每個代理分別進行設置,工作量將非常巨大。為了更方便地對服務網格中的代理進行統(tǒng)一集中控制,在服務網格上增加了控制面組件。

這里我們可以類比SDN的概念,控制面就類似于SDN網管中的控制器,負責路由策略的指定和路由規(guī)則下發(fā);數據面類似于SDN網絡中交換機,負責數據包的轉發(fā)。

由于微服務的所有通訊都由服務網格基礎設施層提供,通過控制面板和數據面板的配合,可以對這些通訊進行監(jiān)控、托管和控制,以實現(xiàn)微服務灰度發(fā)布,調用分布式追蹤,故障注入模擬測試,動態(tài)路由規(guī)則,微服務閉環(huán)控制等管控功能。

如果你們想提升自己的技術,想學習以上的技術要點,你們可以加群獲取,在此我向大家推薦一個交流學習群:575745314 里面會分享一些資深架構師錄制的視頻錄像:有Spring,MyBatis,Netty源碼分析,高并發(fā)、高性能、分布式、微服務架構的原理,JVM性能優(yōu)化這些成為架構師必備的知識體系。還能領取免費的學習資源,目前受益良多。

Istio服務網格

Istio是一個Service Mesh開源項目,是Google繼Kubernetes之后的又一力作,主要參與的公司包括Google,IBM和Lyft。

憑借Kubernetes良好的架構設計及其強大的擴展性,Google圍繞Kubernetes打造一個生態(tài)系統(tǒng)。Kubernetes用于微服務的編排(編排是英文Orchestration的直譯,用大白話說就是描述一組微服務之間的關聯(lián)關系,并負責微服務的部署、終止、升級、縮擴容等)。其向下用CNI(容器網絡接口),CRI(容器運行時接口)標準接口可以對接不同的網絡和容器運行時實現(xiàn),提供微服務運行的基礎設施。向上則用Istio提供了微服務治理功能。

由下圖可見,Istio補充了Kubernetes生態(tài)圈的重要一環(huán),是Google的微服務版圖里一個里程碑式的擴張。

Google借Istio的力量推動微服務治理的事實標準,對Google自身的產品Google Cloud有極其重大的意義。其他的云服務廠商,如Redhat、Pivotal、Nginx、Buoyant等看到大勢所趨,也紛紛跟進,宣布自身產品和Istio進行集成,以避免自己被落下,丟失其中的市場機會。

可以預見不久的將來,對于云原生應用而言,采用Kubernetes進行服務部署和集群管理,采用Istio處理服務通訊和治理,將成為微服務應用的標準配置。

Istio服務包括網格由數據面和控制面兩部分。

數據面由一組智能代理(Envoy)組成,代理部署為邊車,調解和控制微服務之間所有的網絡通信。

控制面負責管理和配置代理來路由流量,以及在運行時執(zhí)行策略。



Istio控制面

Istio控制面板包括3個組件:Pilot、Mixer和Istio-Auth。

Pilot

Pilot維護了網格中的服務的標準模型,這個標準模型是獨立于各種底層平臺的。Pilot通過適配器和各底層平臺對接,以填充此標準模型。

例如Pilot中的Kubernetes適配器通過Kubernetes API服務器得到Kubernetes中Pod注冊信息的更改,入口資源以及存儲流量管理規(guī)則等信息,然后將該數據被翻譯為標準模型提供給Pilot使用。通過適配器模式,Pilot還可以從Mesos、Cloud Foundry、Consul中獲取服務信息,也可以開發(fā)適配器將其他提供服務發(fā)現(xiàn)的組件集成到Pilot中。

除此以外,Pilo還定義了一套和數據面通信的標準API,API提供的接口內容包括服務發(fā)現(xiàn) 、負載均衡池和路由表的動態(tài)更新。通過該標準API將控制面和數據面進行了解耦,簡化了設計并提升了跨平臺的可移植性?;谠摌藴蔄PI已經實現(xiàn)了多種Sidecar代理和Istio的集成,除Istio目前集成的Envoy外,還可以和Linkerd、Nginmesh等第三方通信代理進行集成,也可以基于該API自己編寫Sidecar實現(xiàn)。

Pilot還定義了一套DSL(Domain Specific Language)語言,DSL語言提供了面向業(yè)務的高層抽象,可以被運維人員理解和使用。運維人員使用該DSL定義流量規(guī)則并下發(fā)到Pilot,這些規(guī)則被Pilot翻譯成數據面的配置,再通過標準API分發(fā)到Envoy實例,可以在運行期對微服務的流量進行控制和調整。

Mixer

在微服務應用中,通常需要部署一些基礎的后端公共服務以用于支撐業(yè)務功能。這些基礎設施包括策略類如訪問控制,配額管理;以及遙測報告如APM、日志等。微服務應用和這些后端支撐系統(tǒng)之間一般是直接集成的,這導致了應用和基礎設置之間的緊密耦合,如果因為運維原因需要對基礎設置進行升級或者改動,則需要修改各個微服務的應用代碼,反之亦然。

為了解決該問題,Mixer在應用程序代碼和基礎架構后端之間引入了一個通用中間層。該中間層解耦了應用和后端基礎設施,應用程序代碼不再將應用程序代碼與特定后端集成在一起,而是與Mixer進行相當簡單的集成,然后Mixer負責與后端系統(tǒng)連接。

Mixer主要提供了三個核心功能:

前提條件檢查。允許服務在響應來自服務消費者的傳入請求之前驗證一些前提條件。前提條件可以包括服務使用者是否被正確認證,是否在服務的白名單上,是否通過ACL檢查等等。

配額管理。 使服務能夠在分配和釋放多個維度上的配額,配額這一簡單的資源管理工具可以在服務消費者對有限資源發(fā)生爭用時,提供相對公平的(競爭手段)。Rate Limiting就是配額的一個例子。

遙測報告。使服務能夠上報日志和監(jiān)控。在未來,它還將啟用針對服務運營商以及服務消費者的跟蹤和計費流。

Mixer的架構如圖所示:

首先,Sidecar會從每一次請求中收集相關信息,如請求的路徑,時間,源IP,目地服務,tracing頭,日志等,并請這些屬性上報給Mixer。Mixer和后端服務之間是通過適配器進行連接的,Mixer將Sidecar上報的內容通過適配器發(fā)送給后端服務。

由于Sidecar只和Mixer進行對接,和后端服務之間并沒有耦合,因此使用Mixer適配器機制可以接入不同的后端服務,而不需要修改應用的代碼,例如通過不同的Mixer適配器,可以把Metrics收集到Prometheus或者InfluxDB,甚至可以在不停止應用服務的情況下動態(tài)切換后臺服務。

其次,Sidecar在進行每次請求處理時會通過Mixer進行策略判斷,并根據Mixer返回的結果決定是否繼續(xù)處理該次調用。通過該方式,Mixer將策略決策移出應用層,使運維人員可以在運行期對策略進行配置,動態(tài)控制應用的行為,提高了策略控制的靈活性。例如可以配置每個微服務應用的訪問白名單,不同客戶端的Rate limiting,等等。

邏輯上微服務之間的每一次請求調用都會經過兩次Mixer的處理:調用前進行策略判斷,調用后進行遙測數據收集。Istio采用了一些機制來避免Mixer的處理影響Envoy的轉發(fā)效率。

從上圖可以看到,Istio在Envoy中增加了一個Mixer Filter,該Filter和控制面的Mixer組件進行通訊,完成策略控制和遙測數據收集功能。Mixer Filter中保存有策略判斷所需的數據緩存,因此大部分策略判斷在Envoy中就處理了,不需要發(fā)送請求到Mixer。另外Envoy收集到的遙測數據會先保存在Envoy的緩存中,每隔一段時間再通過批量的方式上報到Mixer。

Auth

Istio支持雙向SSL認證(Mutual SSL Authentication)和基于角色的訪問控制(RBAC),以提供端到端的安全解決方案。

認證

Istio提供了一個內部的CA(證書機構),該CA為每個服務頒發(fā)證書,提供服務間訪問的雙向SSL身份認證,并進行通信加密,其架構如下圖所示:

其工作機制如下:

部署時:

CA監(jiān)聽Kubernetes API Server,為集群中的每一個Service Account創(chuàng)建一對密鑰和證書,并發(fā)送給Kubernetes API Server。注意這里不是為每個服務生成一個證書,而是為每個Service Account生成一個證書。Service Account和Kubernetes中部署的服務可以是一對多的關系。Service Account被保存在證書的SAN(Subject Alternative Name)字段中。

當Pod創(chuàng)建時,Kubernetes根據該Pod關聯(lián)的Service Account將密鑰和證書以Kubernetes Secrets資源的方式加載為Pod的Volume,以供Envoy使用。

Pilot生成數據面的配置,包括Envoy需使用的密鑰和證書信息,以及哪個Service Account可以允許運行哪些服務,下發(fā)到Envoy。


備注:如果是虛機環(huán)境,則采用一個Node Agent生成密鑰,向Istio CA申請證書,然后將證書傳遞給Envoy。

運行時:

服務客戶端的出站請求被Envoy接管。

客戶端的Envoy和服務端的Envoy開始雙向SSL握手。在握手階段,客戶端Envoy會驗證服務端Envoy證書中的Service Account有沒有權限運行該請求的服務,如沒有權限,則認為服務端不可信,不能創(chuàng)建鏈接。

當加密TSL鏈接創(chuàng)建好后,請求數據被發(fā)送到服務端的Envoy,然后被Envoy通過一個本地的TCP鏈接發(fā)送到服務中。

鑒權

Istio“基于角色的訪問控制”(RBAC)提供了命名空間、服務、方法三個不同大小粒度的服務訪問權限控制。其架構如下圖所示:

管理人員可以定制訪問控制的安全策略,這些安全策略保存在Istio Config Store中。 Istio RBAC Engine從Config Store中獲取安全策略,根據安全策略對客戶端發(fā)起的請求進行判斷,并返回鑒權結果(允許或者禁止)。

Istio RBAC Engine目前被實現(xiàn)為一個Mixer Adapter,因此其可以從Mixer傳遞過來的上下文中獲取到訪問請求者的身份(Subject)和操作請求(Action),并通過Mixer對訪問請求進行策略控制,允許或者禁止某一次請求。

Istio Policy中包含兩個基本概念:

ServiceRole,定義一個角色,并為該角色指定對網格中服務的訪問權限。指定角色訪問權限時可以在命名空間,服務,方法的不同粒度進行設置。

ServiceRoleBinding,將角色綁定到一個Subject,可以是一個用戶,一組用戶或者一個服務。


Istio數據面

Istio數據面以“邊車”(Sidecar)的方式和微服務一起部署,為微服務提供安全、快速、可靠的服務間通訊。由于Istio的控制面和數據面以標準接口進行交互,因此數據可以有多種實現(xiàn),Istio缺省使用了Envoy代理的擴展版本。

Envoy是以C++開發(fā)的高性能代理,用于調解服務網格中所有服務的所有入站和出站流量。Envoy的許多內置功能被Istio發(fā)揚光大,例如動態(tài)服務發(fā)現(xiàn)、負載均衡、TLS加密、HTTP/2 & gRPC代理、熔斷器、路由規(guī)則、故障注入和遙測等。

Istio數據面支持的特性如下:

備注:Outbound特性是指服務請求側的Sidecar提供的功能特性,而Inbound特性是指服務提供側Sidecar提供的功能特性。一些特性如遙測和分布式跟蹤需要兩側的Sidecar都提供支持;而另一些特性則只需要在一側提供,例如鑒權只需要在服務提供側提供,重試只需要在請求側提供。

典型應用場景

Istio服務管控包括下列的典型應用場景:

分布式調用追蹤

在微服務架構中,業(yè)務的調用鏈非常復雜,一個來自用戶的請求可能涉及到幾十個服務的協(xié)同處理。因此需要一個跟蹤系統(tǒng)來記錄和分析同一次請求在整個調用鏈上的相關事件,從而幫助研發(fā)和運維人員分析系統(tǒng)瓶頸,快速定位異常和優(yōu)化調用鏈路。

Istio通過在Envoy代理上收集調用相關數據,實現(xiàn)了對應用無侵入的分布式調用跟蹤分析。 Istio實現(xiàn)分布式調用追蹤的原理如下圖所示:

Envoy收集一個端到端調用中的各個分段的數據,并將這些調用追蹤信息發(fā)送給Mixer,Mixer Adapter將追蹤信息發(fā)送給相應的服務后端進行處理。整個調用追蹤信息的生成流程不需要應用程序介入,因此不需要將分布式跟蹤相關代碼注入到應用程序中。

注意:應用仍需要在進行出口調用時將收到的入口請求中tracing相關的header轉發(fā)出去,傳遞給調用鏈中下一個邊車進行處理。

度量收集

Istio 實現(xiàn)度量收集的原理如下圖所示:

Envoy收集指標相關的原始數據,如請求的服務、HTTP狀態(tài)碼、調用時延等,這些收集到的指標數據被送到Mixer,通過Mixer Adapters將指標信息轉換后發(fā)送到后端的監(jiān)控系統(tǒng)中。由于Mixer使用了插件機制,后端監(jiān)控系統(tǒng)可以根據需要在運行期進行動態(tài)切換。

如果你們想提升自己的技術,想學習以上的技術要點,你們可以加群獲取,在此我向大家推薦一個交流學習群:575745314 里面會分享一些資深架構師錄制的視頻錄像:有Spring,MyBatis,Netty源碼分析,高并發(fā)、高性能、分布式、微服務架構的原理,JVM性能優(yōu)化這些成為架構師必備的知識體系。還能領取免費的學習資源,目前受益良多。

灰度發(fā)布

當應用上線以后,運維面臨的一大挑戰(zhàn)是如何能夠在不影響已上線業(yè)務的情況下進行升級。無論進行了多么完善的測試,都無法保證線下測試時發(fā)現(xiàn)所有潛在故障。在無法百分百避免版本升級故障的情況下,需要通過一種方式進行可控的版本發(fā)布,把故障影響控制在可以接受的范圍內,并可以快速回退。

可以通過灰度發(fā)布(又名金絲雀發(fā)布)來實現(xiàn)業(yè)務從老版本到新版本的平滑過渡,并避免升級過程中出現(xiàn)的問題對用戶造成的影響。

Istio通過高度的抽象和良好的設計采用一致的方式實現(xiàn)了灰度發(fā)布。在發(fā)布新版本后,運維人員可以通過定制路由規(guī)則將特定的流量(如具有指定特征的測試用戶)導入新版本服務中以進行測試。通過漸進受控地向新版本導入生產流量,可以最小化升級中出現(xiàn)的故障對用戶的影響。

采用Istio進行灰度發(fā)布的流程如下圖所示:

首先,通過部署新版本的服務,并將通過路由規(guī)則將金絲雀用戶的流量導入到新版本服務中。

測試穩(wěn)定后,使用路由規(guī)則將生產流量逐漸導入到新版本系統(tǒng)中,如按5%、10%、50%、80%逐漸導入。

如果新版本工作正常,則最后將所有流量導入到新版本服務中,并將老版本服務下線;如中間出現(xiàn)問題,則可以將流量重新導回老版本,在新版本中修復故障后采用該流程重新發(fā)布。

斷路器

在微服務架構中,存在著許許多多的服務單元,若一個服務出現(xiàn)故障,就會因依賴關系形成故障蔓延,最終導致整個系統(tǒng)的癱瘓,這樣的架構相較傳統(tǒng)架構就更加的不穩(wěn)定。為了解決這樣的問題,因此產生了斷路器模式。

斷路器模式指,在某個服務發(fā)生故障時,斷路器的故障監(jiān)控向調用放返回一個及時的錯誤響應,而不是長時間的等待。這樣就不會使得調用線程因調用故障被長時間占用,從而避免了故障在整個系統(tǒng)中的蔓延。

Istio實現(xiàn)斷路器的原理如下圖所示:

管理員通過destination policy設置斷路觸發(fā)條件,斷路時間等參數。例如設置服務B發(fā)生10次5XX錯誤后斷路15分鐘。則當服務B的某一實例滿足斷路條件后,就會被從LB池中移除15分鐘。在這段時間內,Envoy將不再把客戶端的請求轉發(fā)到該服務實例。

Istio的斷路器還支持配置最大鏈接數,最大待處理請求數,最大請求數,每鏈接最大請求數,重試次數等參數。當達到設置的最大請求數后,新發(fā)起的請求會被Envoy直接拒絕。

故障注入

對于一個大型微服務應用而言,系統(tǒng)的健壯性非常重要。在微服務系統(tǒng)中存在大量的服務實例,當部分服務實例出現(xiàn)問題時,微服務應用需要具有較高的容錯性,通過重試、斷路、自愈等手段保證系統(tǒng)能夠繼續(xù)對外正常提供服務。因此在應用發(fā)布到生產系統(tǒng)強需要對系統(tǒng)進行充分的健壯性測試。

對微服務應用進行健壯性測試的一個最大的困難是如何對系統(tǒng)故障進行模擬。在一個部署了成百上千微服務的測試環(huán)境中,如果想通過對應用,主機或者交換機進行設置來模擬微服務之間的通信故障是非常困難的。

Istio通過服務網格承載了微服務之間的通信流量,因此可以在網格中通過規(guī)則進行故障注入,模擬部分微服務出現(xiàn)故障的情況,對整個應用的健壯性進行測試。

故障注入的原理如下圖所示:

測試人員通過Pilot向Envoy注入了一個規(guī)則,為發(fā)向服務MS-B的請求加入了指定時間的延遲。當客戶端請求發(fā)向MSB-B時,Envoy會根據該規(guī)則為該請求加入時延,引起客戶的請求超時。通過設置規(guī)則注入故障的方式,測試人員可以很方便地模擬微服務之間的各種通信故障,對微服務應用的健壯性進行較為完整的模擬測試。

總結

服務網格為微服務提供了一個對應用程序透明的安全、可靠的通信基礎設施層。采用服務網格后,微服務應用開發(fā)人員可以專注于解決業(yè)務領域問題,將一些通用問題交給服務網格處理。采用服務網格后,避免了代碼庫帶來的依賴,可以充分發(fā)揮微服務的異構優(yōu)勢,開發(fā)團隊可以根據業(yè)務需求和開發(fā)人員能力自由選擇技術棧。

Istio具有良好的架構設計,提供了強大的二次開發(fā)擴展性和用戶定制能力。雖然Istio目前還處于beta階段,但已經獲得眾多知名公司和產品的支持,是一個非常具有前景的開源服務網格開源項目。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容