【Microservice & Istio】Microservice & Istio

        微服務是一種應用程序架構風格,它將應用程序劃分爲組件,其中每個組件都是一個完整但微型的應用程序,專注於根據單一責任原則生成單個業務任務。從GUI到數據庫或從服務API到數據庫,以便不同的GUI和客戶端應用程序可以重用相同的業務任務功能。每個微服務都有明確定義的接口和依賴關係(例如,對於其他微服務和外部資源),以便微服務可以相當獨立地運行。

        微服務的宗旨:使得開發更高效。通過最大限度地減少人與人之間的溝通和協調它(少一些會議多一些開發等),以及減少變更範圍和風險來加速交付。

       微服務架構的目標是將app組件彼此完全decouple/分離,以便可以維護、擴展等。

===========SOA VS Microservices】================

  • SOA/service-oriented architecture : Focus on reuse, technical integration issues, technical APIs
  • Microservices: Focus on functional decomposition, business capabilities, business APIs

翻譯爲:

  • SOA:專注於重用,技術集成問題,技術API
  • 微服務:專注於功能分解,業務功能,業務API

=====Key tenets of a microservices architecture========

1)大型整體結構分爲許多小型服務

  • 每個服務都在自己的進程中運行
  • 適用的雲規則是每個容器一服務

2)服務針對單個功能進行了優化

  • 每項服務只有一個業務功能
  • 單一責任原則:微服務應該只有一個改變的理由

3) 通過REST API和消息代理進行通信

  • 避免通過DB通信引入緊密耦合

4) 每個服務定義CI/CD(持續集成和持續部署)

  • 服務以不同的速度發展
  • 設置架構原則以指導系統進化發展

5) 每個服務定義HA(高可用性)和羣集決策

  • 一種規模或擴展策略並不適合所有微服務
  • 並非所有服務都需要擴展,其他微服務需要自動擴展到大數

===========【Monolithic VS Microservices】===========

/

Monolithic

Microservice

架構

以單個邏輯可執行文件構建

以一套小型服務構建

模塊化

基於語言功能

基於業務能力

敏捷度

更改涉及構建和部署整個應用程序的新版本

更改可以獨立應用於每個服務

擴展

當有一部分是瓶頸時,需要整個應用程序進行擴展。

每個服務在需要時獨立擴展

實現

通常全部由一種編程語言開發實現

每種服務都可以用不同的編程語言開發實現

可維護性

大型代碼庫對新開發人員是一種intimidating/威脅

較小的代碼庫更易於管理

部署

複雜部署,需要維護窗口和計劃停機時間。

簡單部署,因爲每個服務都可以單獨部署,停機時間最短。

       微服務最大的要求是操作複雜性,因爲有更多的移動部件需要監控和管理,一個大型的業務需求有可能需要上千個應用程序,這就需要管理和監控上千個應用程序運行情況,這對企業來說是個巨大的挑戰。微服務存在的隱患:

  • 微服務重視服務之間的重用獨立性,重用會產生依賴關係就會存在團隊之間的交互因此無法獨立工作。
  • 獨立運行的部分越多,分佈式系統就會越成爲問題(網絡延遲、斷開連接、容錯、序列化);那麼找到bugEnd2End測試難度就會增加。

============= Microservice Advantages ==============

  • 獨立開發,並對其他服務存在有限的、顯式的依賴
  • 可以由一個所有團隊成員都理解整個代碼庫的小團隊開發
  • 根據本團隊時間表開發,以便獨立於其他服務提供新版本
  • 獨立擴展和失敗,可以隔離任何問題,不影響整個app
  • 每種服務都可以用不同的語言開發實現
  • 管理自己的數據以選擇最佳技術和架構

===============應用架構發展—從SOA到微服務===========

       SOA和微服務處理的都是通過網絡進行通信的服務系統,但兩者存在差異,如下面表格和diagram:

架構

關注點

結果

SOA

複用

1.tends to align with a centrally funded model.

2. tend to be "servants of many masters"

3. 對SOA服務的更改可能會影響多個消費者。

Micro services

將monolithic應用程序分解爲更小,更易於管理的組件


1.目標更靈活,解耦,更快發展。

2.面臨DevOps,管理視圖和控件的挑戰

================================================

SOA 棧

       域層(The domain layer)作爲了一個服務層並封裝了記錄的後端系統/SoR(system of record)和記錄數據庫。SOA棧必須將服務序列串聯爲業務流程,這些業務流程本身就是宏服務(macroservices)。但是很難能保持垂直切片。

==========【微服務類型層次結構】===========

       所有業務服務在架構上幾乎相同,但是調度程序子類型專業化(這不顯示類或繼承層次結構並且顯示了專業化)。這個取決於application支持的客戶端類型以及這些客戶端需要其調度程序的妝也化程度。如下圖:

============【開發語言選擇】=============

        每個微服務都可以使用任何語言進行開發,只要它可以部署在雲上並支持REST API。Dispatchers通常用Node實現,因爲Node 擅長處理大量客戶端和大量併發I/O。對於運行JS的客戶端,服務器上的Node更容易適應。業務服務通常用Java編寫,因爲Java可以很好地處理CPU密集型任務,並且擅長連接外部系統,尤其是管理共享連接池。

==========【Backend for frontend BFF】========

       前後端開發:儘量保證dispatcher/client pair在同一個團隊裏開發即某一個模塊的前後端開人員都在同一個團隊內,爲了便於開發過程中的良好溝通、聯調成本節約等。不到萬不得已,切勿將前後端劃分給不同團隊之間的協作或不專業的團隊來完成,這樣會影響項目的開發進度。---這些類似《人月神話》,講究是“術業有專攻”。

====【Business service microservice dependencies】====

Typical/典型】

       業務服務可以依賴於其他業務服務,只需要確保每項服務都是完整的業務任務, 切勿將DB訪問層獨立分離爲單獨的服務。若服務都是一項完整的業務任務,那麼服務間(不存在相互依賴的)的協作就很好。

Death Star/~~】

       存在相互依賴的循環有向圖表示了微服務之間依賴關係。遇到類似這樣的業務服務相互連接成Death Star形狀,面臨着如何部署這樣的架構?首先部署哪一個?若必須在一個(新版本)上更改API,應該更改哪些相關聯的API?--避免讓這樣的Death Star出現在架構中!!!

===========【微服務整合/integration】===========

       微服務間通信是language-neutral(語言中立),各個微服務可以用不同的語言實現。目前的標準是REST和JSON/REST,對於異步集成(asynchronous integration)儘量遵循開放的雲標準,如Apache Kafka。異步協議包括AMQP、MQ Light、RabbitMQ等。

       儘量不要使用XML或序列化等其他方式,這樣會導致每個API提供者和消費者必須支持某種特定協議,不利用擴展K8s服務是一組pods並提供pods之間的網絡連接,而不會暴露每個pod的實際私有IP地址。同樣,可以選擇保持微服務的私密性並使用內置安全功能。

【同步/synchronous通信 VS 異步/asynchronous通信】

       對於同步,整個循環(請求者,提供者,消息)必須在調用的整個生命週期中保持工作。根據請求的性質(長時間在後臺運行)或使集成更可靠和健壯/robust,需要將一些集成點轉換爲異步。 使用異步,調用被分爲3-4個部分。 如果任何一個失敗,系統可能會重試。 並且因爲請求者是無狀態的,所以接收響應的實例甚至不需要是發送請求的實例

【異步通信使微服務更加健壯】

  • 在提供程序運行時,請求者不必阻塞
  • 不同的請求者實例可以處理響應
  • 消息傳遞系統保存動作和結果

【微服務內部通信】

       可以混合和匹配同步/synchronous和異步/asynchronous通信,通常請求/響應—request/response調用全部是同步的或者全部是異步的,但這表明單個調用可以在一個方向同步而在另一個方向異步常見的輕量級協議:REST(如JSON或HTTP)和Messaging(如Kafka)。可以通過以下方法實現完全解耦

  • Messaging wherever possible 儘可能使用消息
  • Service registry or discovery 服務註冊或發現
  • Load balancing 負載均衡
  • Circuit breaker patterns 斷路器模式

        IBM Cloud支持兩種類型的APIs: 一種簡單的HTTP REST API和一種複雜但功能很強的Kafka API。

===========【服務網格/Service Mesh】===========

 

Monolithic Architecture

Microservice Architecture

 

 

資源配置

1.明確定義的、靜態的
2.存儲在靜態文件或硬編碼;
3.託管在相同的地理位置

1.服務可以存儲在任何位置,如Data Center、公共雲提供商或某種組合中

2.託管在裸機服務器、VM、容器等

服務具有多個實例或副本, 不同負載下可擴展

當使用微服務時會遇到如下的問題以及相應的對策:

【服務註冊/Service Registry】

       每個服務網格都有一個服務註冊表,服務註冊表是一個簡單的鍵值對數據存儲,維護所有工作服務實例及其位置的當前列表。當每個服務實例啓動時,它將通過其自己的客戶端代碼或第三方註冊器功能向服務註冊表註冊自己,如K8S爲其集羣中的容器提供第三方註冊服務。服務註冊表用於跟蹤服務的位置和健康狀況,可以以可靠的方式將請求服務定向到提供者服務在服務實例向服務註冊表註冊後,服務註冊表將使用in-bound和out-bound的心跳機制來保持其實例列表的最新狀態服務註冊表需要以某種方式使其具有HA(高可用性)

 

【服務發現和服務代理/service discovery and service proxy】

       任何Service Mesh的核心是服務註冊表和服務發現功能。服務註冊表維護着所有服務實例及其位置的列表,當每個服務實例啓動時,它會check in 服務註冊表,提供其名稱和位置。在check in 之後,每個服務註冊表實現將具有某種心跳機制,以使其列表保持最新狀態,從而刪除它無法連接的任何實例。

       每個服務實例類型可以是Client/服務客戶端(從其他服務請求數據或功能),也可以是Server/服務提供者(向服務客戶端提供數據或功能)。只要服務需要其他服務,它就會使用服務發現/Service discovery功能來查找該服務的實例。

~~~~~~~~~~~兩種類型的服務發現~~~~~~~~~

1.【客戶端發現/client-side discovery】

       請求服務或服務客戶端直接與服務註冊表一起工作,以確定其所需的所有可用服務實例,並且還負責決定哪些將用於其請求的哪些服務實例中的服務實例。

       可以使用幾種可能的規則來確定要使用的實例。如Round-robin load balancing/循環負載均衡:將每個請求均勻地分佈在所有實例上,這會將每個請求發送到列表中的下一個實例。可以使用不同類型的規則,讓某些客戶端訪問某些提供程序實例,如測試新版本或其他。在任何情況下,客戶端發現將通過客戶端代碼來實現負責做出決策並決定聯繫相應的服務實例

2.【服務端發現/server-side discovery】

       此類型需要引入兩一個組件:負載均衡器/服務代理查詢服務註冊表並將請求定向到適當的服務實例的任務委託給負載均衡器。 在一些實現中,例如Istio,除了僅使用循環負載平衡之外,負載平衡器可以用特定規則來編程以管理其對服務實例的選擇。例如 nginx負載均衡器,它內置於普遍的幾個服務網格中。

        優點:只需要查詢服務註冊表並將請求定向到負載均衡器中實現一次的服務實例。缺點:負載均衡器是另一個要管理的組件。在大多數情況下,通常是由服務網格提供。

【自動化測試/Automated Testing】

       沒有什麼是可靠的!常期望組件失敗併爲application構建彈性,以便它們能夠承受/withstan這些故障。一個基本的策略是始終擁有任何給定服務的多個實例,以便application可以在給定實例的失敗後繼續運行,並在重新啓動該實例時繼續運行。

       常見的自動化測試工具可以確保應用程序的彈性,如Netflix Chaos Monkey,Netflix Simian Army以及Istio內置的功能。簡單介紹一下K8s內置的自動化測試流程:

  • 首先創建部署
  • Roll out對微服務的更改。例如希望更改初始部署中使用的鏡像。使用K8S部署微服務時,更改變換會立刻體現、應用並記錄在roll-out歷史中。
  • 使用操作和測試工具測試部署狀態
  • 查看部署的rollout歷史並確定上次部署的版本號
  • 準備就緒後,回滾到以前的版本或指定修訂版本。

【斷路器/Circuit breaker】

       斷路器模式是Istio和Netflix Hystrix附帶的編程工具。斷路器用於防止由於故障或延遲導致的給定服務依賴性的相應延遲,因爲延遲不會導致整個應用程序中更廣泛的延遲和故障。斷路器允許設置超時闕值和故障閾值來實現快速失敗Fast-fail),以滿足內置的構建替代計劃

 

       可以爲再次打開電路之前允許的恢復時間、再次嘗試呼叫服務以及測試閾值(thresholds)這些情況配置相應的值。

【隔板/Bulkhead】

        Bulkhead模式Netflix Hystrix附帶的另一個工具,它可以防止給定服務調用的響應延遲導致整個應用程序出現更廣泛的問題。通過使用單獨的線程池連接到其他系統的連接嘗試來完成此行爲,以便由給定服務的延遲或失敗調用的延遲與該服務隔離,並且在進行更過請求時不使用應用程序的所有縣城。通過爲每個從屬服務使用單獨的連接池,任何服務上的故障都與該服務隔離,並且不會在應用程序中引起更廣泛的問題。

===========【Istio 智能服務網格】===========

        Istio是一個開放平臺服務網格/Service Mesh實現,用於連接、管理和保護微服務。 通過負載平衡,服務到服務身份驗證,監控等Istio提供了一種簡單的方法來創建已部署服務的網絡,而無需對服務代碼進行任何更改。 可以通過在整個環境中部署特殊的sidecar代理來添加對服務的Istio支持,該代理攔截微服務之間的所有網絡通信,這些通信使用Istio的控制平面功能進行配置和管理。

        Istio是IBM、Google和Lyft合作發佈的,目的在於不需要更改應用程序代碼情況下,提供微服務之間的流量管理/traffic flow management、訪問策略實施/access policy enforcement、遙測數據聚合/telemetry data aggregation等功能,使得開發人員可以專注於業務邏輯並快速集成新功能

Why use Istio ???】

       背景:隨着服務網格的大小和複雜性的增加,理解和管理變得很困難。其中包括:服務發現/discovery、負載均衡/load balancing、故障恢復/failure recovery、指標和監控/metrics and monitoring以及更復雜的操作要求(如A/B testing、canary releases/canary版本、速率限制/rate limiting、訪問控制/access control、端到端身份驗證/end-to-end authentication)。Istio通過整體服務網格的行爲洞察/behavioral insight和操作控制/operational control提供了以下幾個關鍵功能:

1. 流量管理/Traffic management:控制服務之間的流量和API調用流量,使調用更加可靠,並在不利條件下使網絡更加健壯/robust

2.可觀察性/Observability:瞭解服務之間的依賴關係以及它們之間流量的性質和流量,提供快速識別問題的能力。

3.策略實施/Policy enforcement:將組織策略應用於服務之間的交互,並確保實施訪問策略,並在消費者之間公平分配資源。通過配置網格而不是通過更改應用程序代碼來進行策略更改。

4.服務標識和安全性/Service identity and security:在網格中提供具有可驗證身份的服務,並提供在不同可信度的網絡上流動時保護服務流量的能力。

5.平臺支持/Platform support:Istio可以在各種環境中運行,包括跨雲、本地、K8S、Mesos等的環境。

6.集成和定製/Integration and customization:策略實施組件可以進行擴展和自定義,以與現有的ACL、日誌記錄、監控、配額/quotas、審計/audit等解決方案集成。

How Istio  works】

     Istio服務網格在邏輯上被分成數據平面和控制平面。兩者功能如下:

  • 數據平面:由一組智能代理(Envoy)組成,這些代理被部署爲sidecars,用於調解和控制微服務之間的所有網絡通信。
  • 控制平面:負責管理和配置代理以路由流量並在運行時實施策略。

1.Sidecar Proxy/側車代理

       服務網格實現(如Istio)使用通常在pod中部署爲sidecars的代理,代理控制對另一個對象的訪問。Istio使用服務和客戶端之間的代理,使得服務網格能夠管理交互。

        K8s將容器部署到pod中,並且pod中的所有容器都託管在同一節點上,pod可以管理對pod中容器的網絡訪問。Pod通常託管單個容器,但可以將多個pod作爲一個託管單元。

        Sidecars在沒有改變的情況下向容器添加行爲。即Sidecars和服務表現爲單個增強單元。 pods作爲一個單元託管Sidecars和服務。

2.Envoy/代理:一種用C++開發的高性能代理

       用於調解服務網格中所有服務的所有inbound/ingress和outbound/egress流量Istio使用Envoy的許多內置功能,例如動態服務發現,負載平衡,TLS終止,HTTP / 2和gRPC代理,斷路器,運行狀況檢查,基於%的流量分配的分階段部署,故障注入和豐富的指標。

       Envoy作爲相關服務的sidecar部署在同一個K8s pod中,這允許Istio將關於流量行爲的大量信號作爲屬性提取,並反過來可以在混合器Mixer中用於執行策略決策並被髮送到監控系統以提供關於整個網格的行爲的信息。Sidecar代理模型還允許將Istio功能添加到現有部署,而無需重新構建或重寫代碼。

 

3.Mixer/混合器

        Mixer是一個獨立於平臺的組件,負責跨服務網格實施訪問控制和使用策略,並從Envoy代理和其他服務收集遙測數據。代理提取請求級別屬性,將其發送到Mixer進行評估。Mixer包含一個靈活的插件模型,使其能夠與各種主機環境和基礎架構後端進行交互,從而根據這些細節抽象出Envoy代理和Istio管理的服務。

 

4.Pilot/領航員—服務發現/service discovery

        Pilot爲Envoy Sidecar提供服務發現,爲智能路由提供流量管理功能(例如A/B 測試和canary 部署)以及彈性(超時/timeouts、重試/retries、斷路器/circuit breaker等)。它將控制流量行爲的高級路由規則轉換爲特定於Envoy的配置,並在運行時將它們傳播到sidecars。 Pilot將特定於平臺的服務發現機制抽象化,並將其合成爲符合Envoy數據平面API的任何邊車所消耗的標準格式。 這種鬆散耦合允許Istio在多個環境(例如,Kubernetes,Consul / Nomad)上運行,同時保持相同的運營商接口以進行流量管理。

 

5.Citadel/堡壘—服務發現/service discovery

       Citadel(以前稱爲Istio Auth)使用相互TLS提供強大的服務到服務和最終用戶身份驗證,具有內置身份和憑證管理。 它可用於升級服務網格中的未加密流量,並使運營商能夠實施基於服務標識而非網絡控制的策略。 未來版本的Istio將添加細粒度的訪問控制和審計,以控制和監控誰使用各種訪問控制機制訪問您的服務,API或資源,包括屬性和基於角色的訪問控制和授權掛鉤。

 

Istio Mesh 請求流程】

        Sidecar 可以處理服務的入口和出口流量,以類似方式,Istio網格管理和控制服務和用戶訪問其控制下的服務的能力。使用sidecars可以在服務網格中包含以下幾個屬性:

       1. 應用程序代碼中執行的常用功能可以包含在sidecars中,這些包括遙測/telemetry,分佈式跟蹤/distributed tracing和TLS終止termination/啓動initiation。

       2.一些有用的功能(如斷路器/circuit breaker、速率限制/rate limit、A/B測試、只能路由/intelligent routing、金絲雀釋放/canary releases)也可以包含在sidecars中。

Istio提供給微服務架構】

1.流量管理/Traffic Management

       使用Istio的流量管理模型實質上解耦/decouple流量和基礎設施擴展,讓運營商通過Pilot指定流量遵循的規則,而不是哪些特定的pod / VM應該接收流量 - Pilot和智能Envoy代理負責其餘部分。 因此,例如,通過Pilot指定特定服務的5%流量轉到金絲雀版本/canary version,而不管金絲雀部署的大小,或根據請求的內容將流量發送到特定版本。

2.流量分離/Traffic Splitting

3.流量轉移/Traffic Steering

       將流量從基礎設施擴展中分離,允許Istio提供存在於app代碼之外的各種流量管理功能。除了用於A / B測試、金絲雀版本、緩慢回滾的動態請求路由之外,它還通過使用超時,重試和斷路器來處理故障恢復,最後通過故障注入來測試跨服務的故障恢復策略的兼容性。 這些功能都是通過服務網格中部署的Envoy  sidecars和代理實現的。

Istio-服務發現和負載均衡】

Istio可以在服務網格中跨服務實例負載均衡流量

       服務註冊Istio假定存在服務註冊表以跟蹤應用程序中服務的pods或VMs。 它還假定服務的新實例自動註冊到服務註冊表,並自動刪除病態的實例。 Kubernetes和Mesos等平臺已經爲基於容器的應用程序提供了這樣的功能。 基於VM的應用程序存在大量解決方案。

       服務發現Pilot消費來自服務註冊表的信息,並提供與平臺無關(platform-agnostic)的服務發現接口。 網格中的Envoy實例執行服務發現並相應地動態更新其負載均衡池。

Istio-處理失敗/Handling Failures】

        Envoy提供了一套開箱即用(out-of-the-box opt-in)的選擇加入故障恢復/failure recovery功能,可以通過應用程序中的服務進行利用,並且可以通過Istio的流量管理規則在運行時動態配置。具體如下:

  • Timeouts 超時
  • 具有超時預算和重試之間的可變抖動/jitter的有界重試
  • 限制併發連接數和對上游服務的請求
  • 對負載均衡池的每個成員進行主動(定期)運行狀況檢查
  • 對負載均衡池按實例應用的細粒度斷路器(被動運行狀況檢查)

原版:

       重試之間的抖動可以最大限度地減少重試對重載上游服務的影響,而超時預算可確保調用服務在可預測的時間範圍內獲得響應

       主動和被動運行狀況檢查的組合可以最大限度地減少在負載均衡池中訪問不健康實例的可能性。 當與平臺級運行狀況檢查(例如Kubernetes或Mesos支持的運行狀況檢查)結合使用時,應用程序可以確保可以從服務網格中快速刪除不健康的pods,容器或VMs,從而最大限度地減少請求失敗和對延遲的影響這些功能共同使服務網格能夠容忍故障節點並防止本地故障與其他節點級聯/cascading不穩定

Istio-故障注入/Fault Injection】

       Istio可以將特定協議/protocol-specific的故障注入到網絡中,而不是殺死pods,這會延遲或破壞TCP層的數據包。理由是,無論網絡級故障如何,應用層觀察到的故障都是相同的,並且可以在應用層注入更有意義的故障(例如,HTTP錯誤代碼)以實現應用程序的彈性。

       可以配置要注入符合特定調價你的請求故障,並且進一步限制應該發生故障的請求概率。可以注入的兩種類型故障

  • 延遲/delays:時序故障,模仿增加的網絡延遲或過載的上游服務。
  • 中止/aborts:模擬/ mimic上游服務失敗的崩潰失敗。通常以HTTP錯誤代碼或TCP連接失敗的形式出現。

Istio-相互TLS身份驗證/Mutual TLS Authentication】

       Citadel的目標是在不需要更改服務代碼的情況下增強微服務及其通信的安全性。它提供密鑰管理系統包含自動化密鑰和證書生成,分發,輪換和撤銷。具體負責以下任務:

  • 爲每個服務提供強大身份來代表其角色,以實現跨羣集和雲的互通
  • 確保服務到服務通信和最終用戶到服務通信

      Citadel的架構圖,其中包括3個主要組件:身份/Identity、密鑰管理/Key Management、通信安全/Communication Security

 

        此圖描述了Citadel如何用於保護作爲服務帳戶前端團隊運行的服務前端與作爲服務帳戶後端團隊運行的服務後端之間的服務到服務通信。 Istio支持在Kubernetes容器和VM或裸機上運行的服務。

        Citadel使用祕密卷/secret volume裝載將密鑰/證書(keys/certs)從Istio CA傳送到Kubernetes容器。 對於在VM或裸機/bare-metal上運行的服務,使用節點代理,該代理是在每個VM或裸機上運行的進程。 它在本地生成私鑰和CSR(certificate signing request證書籤名請求),將CSR發送到Istio CA進行簽名,並將生成的證書與私鑰一起發送給Envoy。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章