在本教程中,我們將介紹服務網格的基礎知識,并了解它如何實現分布式系統(tǒng)架構。我們將主要關注Istio,它是服務網格的一種具體實現。在此過程中,我們將介紹Istio的核心架構。
在過去的幾十年中,我們已經看到了單體應用程序開始拆分為較小的應用程序。此外,諸如Docker之類的容器化技術和諸如Kubernetes之類的編排系統(tǒng)加速了這一變化。盡管在像Kubernetes這樣的分布式系統(tǒng)上采用微服務架構有許多優(yōu)勢,但它也具有相當的復雜性。由于分布式服務必須相互通信,因此我們必須考慮發(fā)現,路由,重試和故障轉移。還有其他一些問題,例如安全性和可觀察性,我們還必須注意以下問題:現在,在每個服務中建立這些通信功能可能非常繁瑣,尤其是當服務范圍擴大且通信變得復雜時,更是如此。這正是服務網格可以為我們提供幫助的地方?;旧希站W格消除了在分布式軟件系統(tǒng)中管理所有服務到服務通信的責任。服務網格能夠通過一組網絡代理來做到這一點。本質上,服務之間的請求是通過與服務一起運行但位于基礎結構層之外的代理路由的:這些代理基本上為服務創(chuàng)建了一個網狀網絡——因此得名為服務網格!通過這些代理,服務網格能夠控制服務到服務通信的各個方面。這樣,我們可以使用它來解決分布式計算的八個謬誤,這是一組斷言,描述了我們經常對分布式應用程序做出的錯誤假設。

現在,讓我們了解服務網格可以為我們提供的一些功能。請注意,實際功能列表取決于服務網格的實現。但是,總的來說,我們應該在所有實現中都期望其中大多數功能。我們可以將這些功能大致分為三類:流量管理,安全性和可觀察性。服務網格的基本特征之一是流量管理。這包括動態(tài)服務發(fā)現和路由。尤其影子流量和流量拆分功能,這些對于實現金絲雀發(fā)布和A/B測試非常有用。由于所有服務之間的通信都是由服務網格處理的,因此它還啟用了一些可靠性功能。例如,服務網格可以提供重試,超時,速率限制和斷路器。這些現成的故障恢復功能使通信更加可靠。服務網格通常還處理服務到服務通信的安全性方面。這包括通過雙向TLS(mTLS)強制進行流量加密,通過證書驗證提供身份驗證以及通過訪問策略確保授權。服務網格中還可能存在一些有趣的安全用例。例如,我們可以實現網絡分段,從而允許某些服務進行通信而禁止其他服務。而且,服務網格可以為審核需求提供精確的歷史信息。強大的可觀察性是處理分布式系統(tǒng)復雜性的基本要求。由于服務網格可以處理所有通信,因此正確放置了它可以提供可觀察性的功能。例如,它可以提供有關分布式追蹤的信息。服務網格可以生成許多指標,例如延遲,流量,錯誤和飽和度。此外,服務網格還可以生成訪問日志,為每個請求提供完整記錄。這些對于理解單個服務以及整個系統(tǒng)的行為非常有用。

Istio是最初由IBM,Google和Lyft開發(fā)的服務網格的開源實現。它可以透明地分層到分布式應用程序上,并提供服務網格的所有優(yōu)點,例如流量管理,安全性和可觀察性。它旨在與各種部署配合使用,例如本地部署,云托管,Kubernetes容器以及虛擬機上運行的服務程序。盡管Istio與平臺無關,但它經常與Kubernetes平臺上部署的微服務一起使用。從根本上講,Istio的工作原理是以Sidcar的形式將Envoy的擴展版本作為代理布署到每個微服務中:該代理網絡構成了Istio架構的數據平面。這些代理的配置和管理是從控制平面完成的:控制平面基本上是服務網格的大腦。它為數據平面中的Envoy代理提供發(fā)現,配置和證書管理。當然,只有在擁有大量相互通信的微服務時,我們才能體現Istio的優(yōu)勢。在這里,sidecar代理在專用的基礎架構層中形成一個復雜的服務網格:Istio在與外部庫和平臺集成方面非常靈活。例如,我們可以將Istio與外部日志記錄平臺,遙測或策略系統(tǒng)集成。

我們已經看到,Istio體系結構由數據平面和控制平面組成。此外,還有幾個使Istio起作用的核心組件。Istio的數據平面主要包括Envoy代理的擴展版本。Envoy是一個開源邊緣和服務代理,可幫助將網絡問題與底層應用程序分離開來。應用程序僅向localhost發(fā)送消息或從localhost接收消息,而無需了解網絡拓撲。Envoy的核心是在OSI模型的L3和L4層運行的網絡代理。它通過使用可插入網絡過濾器鏈來執(zhí)行連接處理。此外,Envoy支持用于基于HTTP的流量的附加L7層過濾器。而且,Envoy對HTTP/2和gRPC傳輸具有一流的支持。Istio作為服務網格提供的許多功能實際上是由Envoy代理的基礎內置功能啟用的:流量控制:Envoy通過HTTP,gRPC,WebSocket和TCP流量的豐富路由規(guī)則啟用細粒度的流量控制應用
網絡彈性:Envoy包括對自動重試,斷路和故障注入的開箱即用支持
安全性:Envoy還可以實施安全策略,并對基礎服務之間的通信應用訪問控制和速率限制
Envoy在Istio上表現出色的另一個原因之一是它的可擴展性。Envoy提供了基于WebAssembly的可插拔擴展模型。這在定制策略執(zhí)行和遙測生成中非常有用。此外,我們還可以使用基于Proxy-Wasm沙箱API的Istio擴展在Istio中擴展Envoy代理。如上所述,控制平面負責管理和配置數據平面中的Envoy代理。在Istio架構中,控制面核心組件是istiod,Istiod負責將高級路由規(guī)則和流量控制行為轉換為特定于Envoy的配置,并在運行時將其傳播到Sidercar。如果我們回顧一下Istio控制平面的架構,將會注意到它曾經是一組相互協作的獨立組件。它包括諸如用于服務發(fā)現的Pilot,用于配置的Galley,用于證書生成的Citadel以及用于可擴展性的Mixer之類的組件。由于復雜性,這些單獨的組件被合并為一個稱為istiod的單個組件。從根本上來說,istiod仍使用與先前各個組件相同的代碼和API。例如,Pilot負責抽象特定于平臺的服務發(fā)現機制,并將其合成為Sidecar可以使用的標準格式。因此,Istio可以支持針對多個環(huán)境(例如Kubernetes或虛擬機)的發(fā)現。此外,istiod還提供安全性,通過內置的身份和憑據管理實現強大的服務到服務和最終用戶身份驗證。此外,借助istiod,我們可以基于服務身份來實施安全策略。該過程也充當證書頒發(fā)機構(CA)并生成證書,以促進數據平面中的相互TLS(MTLS)通信。

我們已經了解了服務網格的典型特征是什么。此外,我們介紹了Istio架構及其核心組件的基礎?,F在,是時候了解Istio如何通過其架構中的核心組件提供這些功能了。我們可以使用Istio流量管理API對服務網格中的流量進行精細控制。我們可以使用這些API將自己的流量配置添加到Istio。此外,我們可以使用Kubernetes自定義資源定義(CRD)定義API資源。幫助我們控制流量路由的關鍵API資源是虛擬服務和目標規(guī)則:基本上,虛擬服務使我們可以配置如何將請求路由到Istio服務網格中的服務。因此,虛擬服務由一個或多個按順序評估的路由規(guī)則組成。評估虛擬服務的路由規(guī)則后,將應用目標規(guī)則。目標規(guī)則有助于我們控制到達目標的流量,例如,按版本對服務實例進行分組。Istio為每個服務提供身份。與每個Envoy代理一起運行的Istio代理與istiod一起使用以自動進行密鑰和證書輪換:Istio提供兩種身份驗證——對等身份驗證和請求身份驗證。對等身份驗證用于服務到服務的身份驗證,其中Istio提供雙向TLS作為全棧解決方案。請求身份驗證用于最終用戶身份驗證,其中Istio使用自定義身份驗證提供程序或OpenID Connect(OIDC)提供程序提供JSON Web令牌(JWT)驗證。Istio還允許我們通過簡單地將授權策略應用于服務來實施對服務的訪問控制。授權策略對Envoy代理中的入站流量實施訪問控制。這樣,我們就可以在各種級別上應用訪問控制:網格,命名空間和服務范圍。Istio為網格網絡內的所有服務通信生成詳細的遙測,例如度量,分布式跟蹤和訪問日志。Istio生成一組豐富的代理級指標,面向服務的指標和控制平面指標。之前,Istio遙測體系結構將Mixer作為核心組件。但是從Telemetry v2開始,混音器提供的功能已替換為Envoy代理插件:此外,Istio通過Envoy代理生成分布式跟蹤。Istio支持許多跟蹤后端,例如Zipkin,Jaeger,Lightstep和Datadog。我們還可以控制跟蹤速率的采樣率。此外,Istio還以一組可配置的格式生成服務流量的訪問日志。

上面我們已經講述了Istio原理和架構,接下來我們開始實戰(zhàn)部分。首先,我們將在Kubernetes集群中安裝Istio。此外,我們將使用一個簡單的基于微服務的應用程序來演示Istio在Kubernetes上的功能。有多種安裝Istio的方法,但最簡單的方法是下載并解壓縮特定操作系統(tǒng)(例如Windows)的最新版本。提取的軟件包在bin目錄中包含istioctl客戶端二進制文件。我們可以使用istioctl在目標Kubernetes集群上安裝Istio:istioctl?install?--set?profile=demo?-y
這會使用演示配置文件將Istio組件安裝在默認的Kubernetes集群上。我們還可以使用任何其他特定于供應商的配置文件來代替演示。最后,當我們在此Kubernetes集群上部署任何應用程序時,我們需要指示Istio自動注入Envoy sidecar代理:kubectl?label?namespace?default?istio-injection=enabled
我們在這里使用kubectl的前提是,我們的機器上已經有像Minikube這樣的Kubernetes集群和Kubernetes CLI kubectl。為了演示,我們將想象一個非常簡單的在線下訂單應用程序。該應用程序包含三個微服務,它們相互交互以滿足最終用戶的訂購請求:我們沒有討論這些微服務的細節(jié),但是使用Spring Boot和REST API可以很簡單地創(chuàng)建它們。最重要的是,我們?yōu)檫@些微服務創(chuàng)建了一個Docker鏡像,以便我們可以將它們部署在Kubernetes上。在像Minikube這樣的Kubernetes集群上部署容器化的工作負載非常簡單。我們將使用Deployment和Service資源類型來聲明和訪問工作負載。通常,我們在YAML文件中定義它們:apiVersion:?apps/v1beta1
kind:?Deployment
metadata:
??name:?order-service
??namespace:?default
spec:
??replicas:?1
??template:
????metadata:
??????labels:
????????app:?order-service
????????version:?v1
????spec:
??????containers:
??????-?name:?order-service
????????image:?kchandrakant/order-service:v1
????????resources:
??????????requests:
????????????cpu:?0.1
????????????memory:?200
---
apiVersion:?v1
kind:?Service
metadata:
??name:?order-service
spec:
??ports:
??-?port:?80
????targetPort:?80
????protocol:?TCP
????name:?http
??selector:
????app:?order-service
對于訂單服務的“部署和服務”,這是一個非常簡單的定義。同樣,我們可以為庫存服務和運輸服務定義YAML文件。kubectl?apply?-f?booking-service.yaml?-f?inventory-service.yaml?-f?shipping-service.yaml
由于我們已經為默認命名空間啟用了自動注入Envoy sidecar代理,因此一切都會由istiod來處理?;蛘?,我們可以使用istioctl的kube-inject命令手動注入Envoy sidecar代理。現在,Istio主要負責處理所有的網狀網絡流量。因此,默認情況下,不允許進出網格的任何流量。Istio使用網關來管理來自網格的入站和出站流量。這樣,我們可以精確地控制進入或離開網格的流量。Istio提供了一些預配置的網關代理部署:istio-ingressgateway和istio-egressgateway。我們將為我們的應用程序創(chuàng)建一個網關和一個虛擬服務來實現此目的:apiVersion:?networking.istio.io/v1alpha3
kind:?Gateway
metadata:
??name:?booking-gateway
spec:
??selector:
????istio:?ingressgateway
??servers:
??-?port:
??????number:?80
??????name:?http
??????protocol:?HTTP
????hosts:
????-?"*"
---
apiVersion:?networking.istio.io/v1alpha3
kind:?VirtualService
metadata:
??name:?booking
spec:
??hosts:
??-?"*"
??gateways:
??-?booking-gateway
??http:
??-?match:
????-?uri:
????????prefix:?/api/v1/booking
????route:
????-?destination:
????????host:?booking-service
????????port:
??????????number:?8080
在這里,我們利用了Istio提供的默認入口控制器。此外,我們已經定義了一個虛擬服務,將我們的請求路由到預訂服務。同樣,我們也可以為來自網格的出站流量定義出口網關。
現在,我們已經看到了如何使用Istio在Kubernetes上部署一個簡單的應用程序。但是,我們仍然沒有利用Istio為我們啟用的任何有趣功能。在本節(jié)中,我們將介紹服務網格的一些常見用例,并了解如何使用Istio為我們的簡單應用程序實現它們。我們可能要以特定方式處理請求路由的原因有多個。例如,我們可能會部署微服務的多個版本,例如運輸服務,并希望僅將一小部分請求路由到新版本。我們可以使用虛擬服務的路由規(guī)則來實現這一點:apiVersion:?networking.istio.io/v1alpha3
apiVersion:?networking.istio.io/v1alpha3
kind:?VirtualService
metadata:
??name:?shipping-service
spec:
??hosts:
????-?shipping-service
??http:
??-?route:
????-?destination:
????????host:?shipping-service
????????subset:?v1
??????weight:?90
????-?destination:
????????host:?shipping-service
????????subset:?v2
??????weight:?10
---
apiVersion:?networking.istio.io/v1alpha3
kind:?DestinationRule
metadata:
??name:?shipping-service
spec:
??host:?shipping-service
??subsets:
??-?name:?v1
????labels:
??????version:?v1
??-?name:?v2
????labels:
??????version:?v2
路由規(guī)則還允許我們基于諸如header參數之類的屬性來定義匹配條件。此外,目的地字段指定與條件匹配的流量的實際目的地。熔斷器基本上是一種軟件設計模式,用于檢測故障并封裝防止故障進一步級聯的邏輯。這有助于創(chuàng)建有彈性的微服務應用程序,以限制故障和延遲尖峰的影響。在Istio中,我們可以使用DestinationRule中的trafficPolicy配置在調用諸如清單服務之類的服務時應用熔斷:apiVersion:?networking.istio.io/v1alpha3
kind:?DestinationRule
metadata:
??name:?inventory-service
spec:
??host:?inventory-service
??trafficPolicy:
????connectionPool:
??????tcp:
????????maxConnections:?1
??????http:
????????http1MaxPendingRequests:?1
????????maxRequestsPerConnection:?1
????outlierDetection:
??????consecutive5xxErrors:?1
??????interval:?1s
??????baseEjectionTime:?3m
??????maxEjectionPercent:?100
在這里,我們將DestinationRule配置為maxConnections為1,httpMaxPendingRequests為1,maxRequestsPerConnection為1。這實際上意味著,如果我們將并發(fā)請求數超過1,熔斷器將開始trap一些請求。雙向身份驗證是指雙方在諸如TLS之類的身份驗證協議中同時相互進行身份驗證的情況。默認情況下,具有代理的服務之間的所有流量在Istio中都使用相互TLS。但是,沒有代理的服務仍繼續(xù)以純文本格式接收流量。雖然Istio將具有代理的服務之間的所有流量自動升級為雙向TLS,但這些服務仍可以接收純文本流量。我們可以選擇使用PeerAuthentication策略在整個網格范圍內實施雙向TLS:apiVersion:?"security.istio.io/v1beta1"
kind:?"PeerAuthentication"
metadata:
??name:?"default"
??namespace:?"istio-system"
spec:
??mtls:
????mode:?STRICT
我們還提供了對每個命名空間或服務而不是在網格范圍內強制實施雙向TLS的選項。但是,特定于服務的PeerAuthentication策略優(yōu)先于命名空間范圍的策略。JSON Web令牌(JWT)是用于創(chuàng)建數據的標準,該數據的有效載荷中包含聲明許多聲明的JSON。為了在身份提供者和服務提供者之間傳遞經過身份驗證的用戶的身份和標準或自定義聲明,這一點已被廣泛接受。我們可以在Istio中啟用授權策略,以允許訪問基于JWT的預訂服務之類的服務:apiVersion:?security.istio.io/v1beta1
kind:?AuthorizationPolicy
metadata:
??name:?require-jwt
??namespace:?default
spec:
??selector:
????matchLabels:
??????app:?booking-service
??action:?ALLOW
??rules:
??-?from:
????-?source:
???????requestPrincipals:?["[email protected]/[email protected]"]
在這里,AuthorizationPolicy強制所有請求具有有效的JWT,并將requestPrincipal設置為特定值。Istio通過組合聲明JWT的iss和sub來創(chuàng)建requestPrincipal屬性。

因此,到目前為止,我們已經看到像Istio這樣的服務網格如何使我們更輕松地處理諸如微服務之類的分布式架構中的許多常見問題。但是盡管如此,Istio還是一個復雜的系統(tǒng),會增加最終部署的復雜性。與其他所有技術一樣,Istio并非靈丹妙藥,必須謹慎使用。盡管我們已經看到了使用服務網格的足夠理由,但下面列舉了一些可能促使我們不使用它的原因:服務網格處理所有服務到服務的通信,而部署和操作服務網格則需要支付額外的費用。對于較簡單的應用程序,這可能是不合理的
由于我們已經習慣于處理一些此類問題,例如應用程序代碼中的熔斷,因此可能導致服務網格中的重復處理
越來越依賴于諸如服務網格之類的外部系統(tǒng)可能會損害應用程序的可移植性,尤其是因為沒有針對服務網格的行業(yè)標準
由于服務網格通常通過攔截通過代理的網格流量來工作,因此它可能會給請求增加不希望的延遲
服務網格增加了許多其他組件和配置,需要精確處理。這需要專業(yè)知識,并增加了學習曲線
最后,我們可能最終將操作邏輯(應在服務網格中存在)與業(yè)務邏輯(不應在服務網格中)混合在一起
因此,正如我們所看到的,服務網格的故事不僅僅涉及好處,但這并不意味著它們不是真的。對我們來說,重要的是要仔細評估我們的需求和應用程序的復雜性,然后權衡服務網格的好處和它們所增加的復雜性。盡管Istio非常受歡迎,并得到了業(yè)內一些領導者的支持,但它當然不是唯一的選擇。盡管我們在這里無法進行全面的比較,但讓我們看一下Linkerd和Consul這兩個選項。Linkerd是已為Kubernetes平臺創(chuàng)建的開源服務網格。它也很受歡迎,目前在CNCF中具有孵化項目的地位。它的工作原理類似于Istio等任何其他服務網格。它還利用TCP代理來處理網格流量。Linkerd使用用Rust編寫的微型代理,稱為Linkerd代理。總體而言,Linkerd并不比Istio復雜,因為它僅支持Kubernetes。但是,除此之外,Linkerd中可用的功能列表與Istio中可用的功能非常相似。Linkerd的核心架構也非常類似于Istio?;旧?,Linkerd包含三個主要組件:用戶界面,數據平面和控制平面。Consul是HashiCorp的服務網格的開源實現。它的好處是可以與HashiCorp的其他基礎架構管理產品套件很好地集成,以提供更廣泛的功能。Consul中的數據平面可以靈活地支持代理以及本機集成模型。它帶有內置代理,但也可以與Envoy一起使用。除了Kubernetes,Consul還可以與Nomad等其他平臺一起使用。Consul通過在每個節(jié)點上運行Consul代理以執(zhí)行運行狀況檢查來工作。這些代理與一臺或多臺存儲和復制數據的Consul服務器通信。盡管它提供了服務網格(如Istio)的所有標準功能,但它是部署和管理的更復雜的系統(tǒng)。

總而言之,在本教程中,我們介紹了服務網格模式的基本概念以及它提供給我們的功能。特別是,我們詳細介紹了Istio。這涵蓋了Istio的核心架構及其基本組件。此外,我們詳細介紹了一些常見用例的安裝和使用Istio的細節(jié)。來源:https://zhuanlan.zhihu.com/p/369068128
譯者:iyacontrol
版權申明:內容來源網絡,版權歸原創(chuàng)者所有。除非無法確認,我們都會標明作者及出處,如有侵權煩請告知,我們會立即刪除并表示歉意。謝謝!
順便給大家推薦一個GitHub項目,這個 GitHub 整理了上千本常用技術PDF,絕大部分核心的技術書籍都可以在這里找到,
GitHub地址:https://github.com/javadevbooks/books
電子書已經更新好了,你們需要的可以自行下載了,記得點一個star,持續(xù)更新中..
