天天看點

如何通過 Istio 實作微服務特性什麼是服務網格和 Istio?架構安裝 Istio應用概覽部署Istio 微服務特性服務發現回彈性故障重試斷路器認證認證授權可觀察性監控跟蹤結論

在微服務架構中,應用程式是由多個互相連接配接的服務組成的,這些服務協同工作以實作所需的業務功能。是以,一個典型的企業級微服務架構如下所示:

如何通過 Istio 實作微服務特性什麼是服務網格和 Istio?架構安裝 Istio應用概覽部署Istio 微服務特性服務發現回彈性故障重試斷路器認證認證授權可觀察性監控跟蹤結論

最初,我們可能認為使用微服務架構實作一個應用程式是很容易的事情。但是,要恰當地完成這一點并不容易,因為我們會面臨一些新的挑戰,而這些挑戰是單體架構所未曾遇到的。舉例來講,這樣的挑戰包括容錯、服務發現、擴充性、日志和跟蹤等。

為了應對這些挑戰,每個微服務都需要實作在 Red Hat 被稱為“微服務特性(microservicility)”的内容。這個術語指的是除了業務邏輯之外,服務必須要實作的一個橫切性關注點的清單。

這些關注點總結起來如下圖所示:

如何通過 Istio 實作微服務特性什麼是服務網格和 Istio?架構安裝 Istio應用概覽部署Istio 微服務特性服務發現回彈性故障重試斷路器認證認證授權可觀察性監控跟蹤結論

業務邏輯可以使用任何語言(Java、Go 或 JavaScript)或任何架構(Spring Boot、Quarkus)來實作,但是圍繞着業務邏輯,我們應該實作如下的關注點:

API:服務可以通過一組預先定義的 API 操作進行通路。例如,在采用 RESTful Web API 的情況下,會使用 HTTP 作為協定。此外,API 還可以使用像Swagger這樣的工具實作文檔化。

發現(Discovery):服務需要發現其他的服務。

調用(Invocation):在服務發現之後,需要使用一組參數來調用它,并且可能會傳回一個響應。

彈性(Elasticity):微服務架構很重要的特性之一就是每個服務都是有彈性的,這意味着它可以根據一些參數(比如系統的重要程度或目前的工作負載)獨立地進行擴充和伸縮。

回彈性(Resiliency):在微服務架構中,我們在開發時應該要考慮到故障,特别是與其他服務進行通信的時候。在單體架構中,應用會作為一個整體進行啟動和關閉。但是,當我們把應用拆分成微服務架構之後,應用就變成由多個服務組成的,所有的服務會通過網絡互相連接配接,這意味着應用的某些部分可能在正常運作,而其他部分可能已經出現了故障。在這種情況下,很重要的一點就是遏制故障,避免錯誤通過其他的服務進行傳播。回彈性(或稱為應用回彈性)是指一個應用/服務能夠對面臨的問題作出反應的能力,在出現問題的時候,依然能夠提供盡可能最好的結果。

管道(Pipeline):服務應該能夠獨立部署,不需要任何形式的部署編排。基于這一點,每個服務應該有自己的部署管道。

認證(Authentication):在微服務架構中,涉及到安全性時,很重要的一個方面就是如何認證/授權内部服務之間的調用。Web token(以及通用的 token)是在内部服務之間聲明安全性的首選方式。

日志(Logging):在單體應用中,日志是很簡單的事情,因為應用的所有元件都在同一個節點中運作。現在,元件以服務的形式分布在多個節點上,是以,為了全面了解日志跟蹤的情況,我們需要一個統一的日志系統/資料收集器。

監控(Monitoring):要保證基于微服務的應用正确運作,很重要的一個方面就是衡量系統的運作情況、了解應用的整體健康狀況并在出現問題的時候發出告警。監控是控制應用程式的重要方面。

跟蹤(Tracing):跟蹤是用來可視化一個程式的流程和資料進展的。當我們需要檢查使用者在整個應用中的操作時,它對開發人員或運維人員尤其有用。

Kubernetes 正在成為部署微服務的事實标準工具。它是一個開源的系統,用來自動化、編排、擴充和管理容器。

但是在我們提到的十個微服務特性中,通過使用 Kubernetes 隻能覆寫其中的三個。

如何通過 Istio 實作微服務特性什麼是服務網格和 Istio?架構安裝 Istio應用概覽部署Istio 微服務特性服務發現回彈性故障重試斷路器認證認證授權可觀察性監控跟蹤結論

**發現(Discovery)**是通過_Kubernetes Service_理念實作的。它提供了一種将_Kubernetes Pod_(作為一個整體)進行分組的方式,使其具有穩定的虛拟 IP 和 DNS 名。要發現一個服務隻需要發送請求的時候使用 Kubernetes 的服務名作為主機名即可。

使用 Kubernetes **調用(Invocation)**服務是非常容易的,因為平台本身提供了所需的網絡來調用任意的服務。

彈性(Elasticity)(或者說擴充性)是 Kubernetes 從一開始就考慮到的問題,例如,如果運作kubectl scale deployment myservice --replicas=5指令的話,myservice deployment 就會擴充至五個副本或執行個體。Kubernetes 平台會負責尋找合适的節點、部署服務并維持所需數量的副本一直處于運作狀态。

但是,剩餘的微服務特性該怎麼處理呢?Kubernetes 隻涵蓋了其中的三個,那麼我們該如何實作剩餘的哪些呢?

在本系列的第一篇文章中,我介紹了一種實作它們的方式,那就是使用 Java 将它們嵌入到服務内部。

在代碼内部實作橫切性關注點的服務如下圖所示:

如何通過 Istio 實作微服務特性什麼是服務網格和 Istio?架構安裝 Istio應用概覽部署Istio 微服務特性服務發現回彈性故障重試斷路器認證認證授權可觀察性監控跟蹤結論

正如在前面的文章中所闡述的那樣,這種方式能夠正常運作并且具有很多的優勢,但是它也有一些缺點。我們介紹主要的幾個問題:

服務的基礎代碼變成了業務邏輯(會給公司帶來價值)和基礎設施代碼(微服務所需)的混合體。

微服務架構中的服務可能會使用不同的語言開發,比如服務 A 使用 Java 語言,服務 B 使用 Go 語言。多語言服務所帶來的挑戰在于學習如何為每種語言實作這些微服務特性。例如,在 Java 中使用哪個庫來實作回彈性,在 Go 中使用哪個庫等等。

就 Java 來講,對于每個微服務特性來講,我們可能都會添加新的庫(及其所有的傳遞性依賴),例如,為了實作回彈性引入Resiliency4J、為了實作跟蹤引入Jaeger或者為了實作監控引入Micrometer。盡管這麼做沒有什麼問題,但是我們在類路徑下加入不同種類的庫的過程中,會增加類路徑沖突的幾率。除此之外,記憶體消耗和啟動時間也會随之增加。最後同樣重要的是,在所有的 Java 服務之間維護這些庫的版本也是一個問題,我們要讓它們保持相同的版本。

歸根到底,我們可能會想,為什麼需要實作這些微服務特性呢?

在微服務架構中,應用程式是由互相連接配接的多個服務組成的,所有的服務互相協作以生成我們所需的業務功能。這些服務都是使用網絡互相連接配接在一起的,是以實際上我們實作了一個分布式計算的模型。由于它是分布式的,可觀察性(監控、跟蹤、日志)就變得有些複雜了,因為所有的資料分散在多個服務中。因為網絡是不可靠的,或者網絡延遲不可能為零,是以服務需要在面臨故障的時候具備回彈性。

是以,我們可以假定之是以需要微服務特性,是因為在基礎設施層(我們需要使用網絡的分布式服務通信,而不是單體)所做的決定。那麼我們為什麼要在應用層面實作這些微服務特性,而不是在基礎設施層面實作呢?問題就在這裡,這個問題有一個很簡單的答案,那就是服務網格。

<h1 class="pgc-h-arrow-right" data-track="31">什麼是服務網格和 Istio?</h1>

服務網格是一個專用的基礎設施層,目的在于使得服務與服務之間的通信變得安全、快速和可靠。

服務網格通常以輕量級網絡代理的形式實作并且會與服務代碼部署在一起,它會攔截服務所有進站/出站的網絡流量。

Istio是一個适用于 Kubernetes 的開源服務網格實作。Istio 采用的政策是內建一個網絡流量代理到 Kubernetes Pod 中,而這個過程是借助sidecar容器實作的。sidecar 容器與服務容器運作在同一個 Pod 中。因為它們運作在系統的 Pod 之中,是以兩個容器會共享 IP、生命周期、資源、網絡和存儲。

如何通過 Istio 實作微服務特性什麼是服務網格和 Istio?架構安裝 Istio應用概覽部署Istio 微服務特性服務發現回彈性故障重試斷路器認證認證授權可觀察性監控跟蹤結論

Istio 使用Envoy Proxy作為 sidecar 容器中的網絡代理,并且會配置 Pod 通過 Envoy 代理(sidecar 容器)發送所有的入站/出站流量。

在使用 Istio 的時候,服務之間的通信并不是直接進行的,而是通過 sidecar 容器(即 Envoy)進行的,當服務 A 請求服務 B 的時候,請求會通過服務 A 的 DNS 發送到它的代理容器上。随後,服務 A 的代理容器會發送請求至服務 B 的代理容器,代理容器最終會調用真正的服務 B。響應過程則會遵循完全相反的路徑。

如何通過 Istio 實作微服務特性什麼是服務網格和 Istio?架構安裝 Istio應用概覽部署Istio 微服務特性服務發現回彈性故障重試斷路器認證認證授權可觀察性監控跟蹤結論

Envoy 代理的 sidecar 容器實作了如下的特性:

智能路由和跨服務的負載均衡。

故障注入。

回彈性:重試和斷路器。

可觀察性和遙測:名額與跟蹤。

安全性:加密和授權。

全局範圍(fleet-wide)的政策執行。

通過下圖我們可以看出,sidecar 容器實作的特性能夠非常好地比對五個微服務特性:服務發現、回彈性、認證、監控和跟蹤。

如何通過 Istio 實作微服務特性什麼是服務網格和 Istio?架構安裝 Istio應用概覽部署Istio 微服務特性服務發現回彈性故障重試斷路器認證認證授權可觀察性監控跟蹤結論

在容器中實作微服務特性的邏輯有如下幾個好處:

業務代碼與微服務特性完全隔離。

所有的服務會使用完全相同的實作,因為它們使用的是同一個容器。

它的代碼是獨立的。服務可以使用任意語言實作,但是這些橫切性的關注點始終是相同的。

所有服務的配置過程和參數是相同的。

但是,Istio 内部是如何運作的,我們為什麼需要 Istio,而不是直接使用 Envoy 代理呢?

<h1 class="pgc-h-arrow-right" data-track="51">架構</h1>

Envoy 代理是一個輕量級的網絡代理,它可以單獨使用,但是如果有十個服務要部署的話,我們就需要配置十個 Envoy 代理。這個過程會變得有一些複雜和繁瑣。Istio 簡化了這一過程。

從架構上來講,Istio 服務網格是由資料平面(data plane)和控制平面(control plane)組成的。

資料平面是由以 sidecar 形式部署的 Envoy 代理組成的。這個代理會攔截所有網絡之間的通信。它還會收集和報告所有網格流量的遙測資料。

控制平面負責管理和配置 Envoy 代理。

下圖描述了這兩個元件:

<h1 class="pgc-h-arrow-right" data-track="57">安裝 Istio</h1>

我們需要一個安裝 Istio 的 Kubernetes 叢集。就本文來講,我們會使用Minikube,但是任意其他的 Kubernetes 叢集都是可以的。

運作如下的指令來啟動叢集:

複制代碼

✨ 基于已有的 profile 并使用 virtualbox 驅動

❗ 對于既有的 minikube 叢集,我們無法改變它的記憶體大小。如果需要的話,請先将該叢集删除掉。

Kubernetes 叢集運作起來之後,我們就可以下載下傳istioctl CLI 工具來安裝 Istio 到叢集中了。在本例中,我們會從版本釋出頁面下載下傳 Istio 1.9.4。

istioctl工具安裝完成之後,我們就可以将 Istio 部署到叢集之中了。Istio 自帶了不同的profiles,但是就開始學習 Istio 而言,demo profile 是最合适的。

istioctl install --set profile=demo -y

Detected that your cluster does not support third party JWT authentication. Falling back to less secure first party JWT. See https://istio.io/docs/ops/best-practices/security/#configure-third-party-service-account-tokens for details.

&lt;small&gt;✔ Istio core installed&lt;/small&gt;

&lt;small&gt;✔ Istiod installed&lt;/small&gt;

&lt;small&gt;✔ Egress gateways installed&lt;/small&gt;

&lt;small&gt;✔ Ingress gateways installed&lt;/small&gt;

&lt;small&gt;✔ Addons installed&lt;/small&gt;

&lt;small&gt;✔ Installation complete&lt;/small&gt;

我們要一直等到istio-system命名空間中的所有 Pod 均處于 running 狀态。

為了發揮 Istio 的所有功能,網格中的 Pod 必須運作一個 Istio sidecar 代理。

我們有兩種方式将 Istio sidecar 注入到 Pod 中:使用istioctl指令手動注入或者在将 Pod 部署到配置好的命名空間時自動注入。

為了簡單起見,我們通過執行如下指令,為default命名空間配置預設的自動化 sidecar 注入:

kubectl label namespace default istio-injection=enabled

namespace/default labeled

現在,Istio 已經安裝到了 Kubernetes 叢集中,并且為在default命名空間使用做好了準備。

在下面的章節中,我們将會看到如何“Istio 化”應用并部署一個這樣的應用。

<h1 class="pgc-h-arrow-right" data-track="86">應用概覽</h1>

應用是由兩個服務組成的,分别是 book service 和 rating service。Book service 傳回一本圖書的資訊及其評分。Rating service 傳回給定圖書的評分。我們有 rating service 的兩個版本:v1 會為所有的圖書傳回一個固定的評分(也就是 1),而 v2 會傳回一個随機的評分值。

<h1 class="pgc-h-arrow-right" data-track="88">部署</h1>

因為已經啟用了 sidecar 注入,我們不需要對 Kubernetes 部署檔案做任何變更。接下來,我們将這三個服務部署到“Istio 化”的命名空間中。

舉例來說,_book service_的部署檔案如下所示:

我們可以看到,在檔案中既沒有 Istio 相關的内容,也沒有 sidecar 容器的配置。Istio 功能的注入預設會自動進行。

我們把應用部署到 Kubernetes 叢集中:

幾秒鐘之後,應用就會啟動起來了。為了進行校驗,我們運作如下的指令并觀察 Pod 所擁有的容器數量:

注意,每個 Pod 都包含了兩個正在運作的容器,其中一個是服務本身,另外一個是 Istio 代理。

如果描述這個 Pod 的話,我們會發現:

因為我們使用了 Minikube 并且 Kubernetes 服務是 LoadBalancer 類型,是以要通路應用需要 Minikube 的 IP 和服務端口。為了找到這些值,可以執行如下指令:

接下來,我們可以對服務執行 curl 指令:

從輸出我們可以看到評分值的變化,也就是對于同一個圖書的 id,評分值會在 1 和 3 之間變化。預設情況下,Istio 會使用 round-robin 方式平衡對服務的調用。在本例中,請求會在rating:v1(傳回固定的評分值 1)和rating:v2(在啟動的時候進行随機的評分計算,在本例中,會對 ID 為 1 的圖書傳回 3)之間進行平衡。

應用現在已經部署好了,并且實作了“Istio 化”,但是到目前為止還沒有啟用任何的微服務特性。我們首先來建立一些 Istio 資源,以便于在 Istio 代理容器上啟用和配置微服務特性。

<h1 class="pgc-h-arrow-right" data-track="112">Istio 微服務特性</h1>

<h1 class="pgc-h-arrow-right" data-track="113">服務發現</h1>

Kubernetes Service_實作了服務發現的理念。它提供了一種方式将一組_Kubernetes Pod(作為一個整體)賦予一個穩定的虛拟 IP 和 DNS 名。Pod 在通路其他 Pod 的時候,可以使用_Kubernetes Service_名作為主機名。這隻能允許我們實作基本的服務發現政策,但是我們可能會需要更進階的發現/部署政策,比如金絲雀釋出、灰階釋出或者鏡像流量(shadowing traffic),此時 Kubernetes Service 就愛莫能助了。

Istio 能夠讓我們很容易地控制服務之間的網絡流量,這是通過兩個概念來實作的,即DestinationRule和VirtualService。

DestinationRule定義了在路由發生之後如何為網絡流量提供服務的政策。在 destination rule 中我們可以配置的内容如下所示:

網絡流量政策

負載均衡政策

連接配接池設定

mTLS

回彈性

使用标簽(label)指定服務的子集(subset),這些子集會在VirtualService中用到。

我們建立一個名為destination-rule-v1-v2.yml的檔案來注冊兩個子集,其中一個用于_rating service v1_,另外一個用于_rating service v2_:

在這裡,我們将host字段設定為 rating,因為這是在_Kubernetes Service_中定義的 DNS 名。随後,在subsets部分,我們以labels集的形式定義了多個子集,并将它們分組到一個“虛拟的”name。例如,在前面的例子中,我們定義了兩個組,其中一個組用于 rating service 的 version 1,另外一個組用于 version 2。

VirtualService能夠讓我們配置請求該如何路由至 Istio 服務網格的服務中。借助 virtual service,實作像 A/B 測試、藍/綠部署、金絲雀釋出或灰階釋出這樣的政策就會變得非常簡單。

我們建立一個名為virtual-service-v1.yml的檔案以發送所有的流量到 v1:

在前面的檔案中,我們配置所有到達 rating 主機的請求都會被發送到 version-v1 子集所屬的 Pod 中。我們需要記住,子集是在DestinationRule檔案中建立的。

現在,我們可以再次向服務執行一些curl指令,但是在輸出方面最大的差異在于所有的請求都發送到了_rating v1_中。

顯然,我們可以建立另外一個 virtual service 檔案,使其指向 rating v2:

這樣,所有的流量會發送至_rating_ v2:

現在,rating字段沒有被設定為 1,這是因為所有的請求都被 version 2 處理了。

通過修改 virtual service 的weight字段,我們就能實作金絲雀釋出。

現在,我們對應用執行一些curl指令:

rating v1 的通路次數要比 rating v2 更多,這遵循了在weight字段中設定的占比。

現在,我們移除 virtual service 資源,使其回到預設的行為(也就是 round-robin 政策):

<h1 class="pgc-h-arrow-right" data-track="160">回彈性</h1>

在微服務架構中,我們在開發時要始終考慮到可能出現的故障,在與其他的服務進行通信時更是如此。在單體應用中,我們的應用會作為一個整體,要麼全部處于可用狀态,要麼全部處于當機狀态,但是在微服務架構中,情況卻并非如此,因為有些服務是可用的,而另外一些則可能已經當機了。回彈性(或稱為應用回彈性)是指一個應用/服務能夠對面臨的問題作出反應的能力,在出現問題的時候,依然能夠提供盡可能最好的結果。

接下來我們看一下 Istio 如何幫助我們實作回彈性政策,以及如何配置它們。

<h1 class="pgc-h-arrow-right" data-track="163">故障</h1>

rating service 實作了一個特殊的端點,當它被通路後會導緻服務開始傳回 503 HTTP 錯誤碼。

執行如下的指令(将 Pod 名替換為你自己的),使服務 rating v2 在通路的時候開始出現故障::

<h1 class="pgc-h-arrow-right" data-track="168">重試</h1>

目前,Istio 配置為沒有 virtual service,這意味着它會在兩個版本之間平衡請求。

我們發送一些請求并校驗 rating v2 會失敗:

其中有個請求沒有産生響應,這是因為_rating v2_沒有傳回合法的響應,而是産生了錯誤。

Istio 支援重試,這是通過在VirtualService資源中進行配置實作的。建立名為virutal-service-retry.yml的檔案,其内容如下所示:

按照配置,如果 rating service(不管哪個版本)傳回5XX HTTP 錯誤碼的話,會自動進行兩次重試。

接下來,我們發送一些請求并檢查輸出:

現在,我們可以看到,所有的請求都是由 rating v1 響應的。原因很簡單,當對 rating service 的請求發送至 v1,會得到一個合法的響應。但是,如果請求被發送到 v2 的時候,會出現錯誤并且會自動執行重試。

因為調用是在兩個服務之間進行負載均衡的,是以重試請求會被發送到 v1,進而産生一個合法的響應。

基于這樣的原因,上述的所有請求都會傳回來自 v1 的響應。

<h1 class="pgc-h-arrow-right" data-track="186">斷路器</h1>

對于處理網絡故障或偶爾出現的錯誤來說,自動重試是一個很好的方式,但是如果多個并發使用者向一個具有自動重試功能的故障系統發送請求時,會發生什麼呢?

我們通過使用Siege(一個 HTTP 負載測試工具)模拟這個場景,但首先,我們使用 kubectl 指令來探查一下 rating v2 的日志:

這些日志行展示了該服務所處理的請求數。目前,該服務處理了 34 個請求。

為了模拟四個并發使用者,并且每個使用者發送十個請求到應用上,我們可以執行如下的 siege 指令:

當然,這裡沒有錯誤發送給調用者,這是因為有自動重試機制,但是我們再次探測一下 rating v2 的日志:

盡管 rating v2 不能産生一個合法的響應,但是服務依然被通路了 25 次,這會對應用産生很大的影響,因為:

如果服務已經處于過載狀态的話,發送更多的請求對它的恢複來講并不是一個好主意。也許,最好的方式是将執行個體放到一個隔離區中。

如果服務此時恰好因為某個缺陷出現了故障,那麼重試并不會改善這種情況。

對于每次重試,都會建立一個 socket、配置設定一些檔案描述符(file descriptor),還要通過網絡發送一些資料包,但最終得到的卻是故障。這個過程會影響在同一個節點中其他服務(CPU、記憶體、檔案描述符等)或者網絡(增加無用的流量、延遲等)。

為了解決這個問題,我們需要有一種方式能夠在出現重複執行失敗的時候,讓調用能夠自動地快速失敗。斷路器(circuit breaker)設計模式和艙壁(bulkhead)模式是這個問題的解決方案。前者提供了在遇到并發錯誤的時候,快速失敗的政策,而後者則能限制并發執行的數量。

現在,建立一個名為destination-rule-circuit-breaker.yml的檔案,内容如下所示:

我們要注意的第一件事情就是DestinationRule配置了斷路器。除了配置斷路器之外,子集也需要指定。對并發連接配接的限制是在connectionPool字段中實作的。

要配置斷路器,我們需要使用outlierDetection。就本例而言,如果在一秒鐘的時間視窗中發生了一次錯誤,斷路器将會打開,使服務暫時跳閘(trip)三分鐘。在這個時間之後,斷路器會處于半開狀态,這意味着會執行真實的邏輯。如果再次失敗的話,斷路器會保持打開的狀态,否則的話,它将會關閉。

我們已經在 Istio 中配置完了斷路器模式,接下來,我們再次執行siege指令并探查_rating v2_ v2 的日志。

再次探查日志。注意,在前面的運作中,我們已經到了 Request 59。

_Rating v2 _隻接收到了一個請求,因為在第一次處理請求的時候傳回了錯誤,斷路器就會打開,是以不會有更多的請求發送到 rating v2 上。

現在,我們已經看到了如何使用 Istio 實作回彈性。在這裡,我們并沒有在服務中實作相關的邏輯,将其與業務邏輯混在一起,而是讓 sidecar 容器實作了這些邏輯。

最後,執行如下的指令,讓 rating v2 服務回到之前的狀态。

<h1 class="pgc-h-arrow-right" data-track="221">認證</h1>

在實作微服務架構的時候,我們可能會發現的一個問題就是如何保護内部服務之間的通信。我們是不是要使用 mTLS?是不是要對請求進行認證?是否要對請求進行鑒權?所有這些問題的答案都是肯定的!接下來,我們将會一步一步地看一下 Istio 是如何幫助我們實作這些功能的。

<h1 class="pgc-h-arrow-right" data-track="223">認證</h1>

Istio 會自動将代理和工作負載之間的所有網絡流量更新為 mTLS,這個過程不需要修改任何的服務代碼。與此同時,作為開發人員,我們會使用 HTTP 協定實作服務。當服務被“Istio 化”的時候,服務之間的通信會采用 HTTPS。Istio 會負責管理證書,擔任證書頒發機構并撤銷/更新證書。

要校驗 mTLS 是否已啟用,我們可以使用 istioctl 工具執行如下的指令:

book-service 托管在了 8080 端口,并且以 permissive 政策配置了 mTLS。

<h1 class="pgc-h-arrow-right" data-track="229">授權</h1>

接下來,我們看一下如何使用 JSON Web Token(JWT)格式啟用 Istio 的終端使用者認證。

我們要做的第一件事情是應用一個RequestAuthentication資源。這個政策能夠確定如果Authorization頭資訊包含 JWT token 的話,它必須是合法的、沒有過期的、由正确的使用者頒發的并且沒有被篡改。

其中的關鍵字段包括:

issuer:token 的合法頒發者。如果所提供的 token 沒有在iss JWT 字段指定該頒發者,那麼這個 token 就是非法的。

jwksUri:jwks檔案的 URL,它指定了公鑰注冊的位址,用來校驗 token 的簽名。

我們現在使用一個非法的 token 來運作curl指令:

因為 token 是非法的,是以請求會被拒絕,并傳回 HTTP/1.1 401 Unauthorized 狀态碼。

使用合法的 token 重複前面的請求:

現在,我們可以看到一個合法的響應了,因為此時 token 是正确的。

到目前為止,我們隻是認證了請求(隻需要一個合法的 token),其實 Istio 還支援基于角色通路控制(role-based access control,RBAC)模型的授權。我們接下來建立一個AuthorizationPolicy政策,隻允許具有合法 JSON Web Token 并且 claim role 設定為 customer 的請求。建立名為authorization-policy-jwt.yml的檔案:

然後執行和上面一樣的 curl 指令:

這一次的響應顯然不一樣了。盡管 token 是合法的,但是通路被拒絕了,這是因為 token 中并沒有值為 customer 的 claim role。

然後,我們使用如下的 token:

curl 192.168.99.116:31304/book/1 -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IkRIRmJwb0lVcXJZOHQyenBBMnFYZkNtcjVWTzVaRXI0UnpIVV8tZW52dlEiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjI1NDkwNTY4ODgsImlhdCI6MTU0OTA1Njg4OSwiaXNzIjoidGVzdGluZ0BzZWN1cmUuaXN0aW8uaW8iLCJyb2xlIjoiY3VzdG9tZXIiLCJzdWIiOiJ0ZXN0aW5nQHNlY3VyZS5pc3Rpby5pbyJ9.VM9VOHD2NwDjQ6k7tszB3helfAn5wcldxe950BveiFVg43pp7x5MWTjMtWQRmQc7iYul19PXsmGnSSOiQQobxdn2UnhHJeKeccCdX5YVgX68tR0R9xv_wxeYQWquH3roxHh2Xr2SU3gdt6s7gxKHrW7Zc4Z9bT-fnz3ijRUiyrs-HQN7DBc356eiZy2wS7O539lx3mr-pjM9PQtcDCDOGsnmwq1YdKw9o2VgbesfiHDDjJQlNv40wnsfpq2q4BgSmdsofAGwSNKWtqUE6kU7K2hvV2FvgwjzcB19bbRYMWxRG0gHyqgFy-uM5tsC6Cib-gPAIWxCdXDmLEiqIdjM3w"

{"bookId":1,"name":"Book 1","rating":3}

現在,我們看到了一個合法的響應,因為此時 token 是正确的并且包含了一個合法的 role 值。

<h1 class="pgc-h-arrow-right" data-track="260">可觀察性</h1>

Istio 自帶了四個元件以适應可觀察性的需求:

Prometheus:用于監控。

Grafana:用于可視化。

Jaeger + Zipkin:用于跟蹤。

Kiali:用于為應用提供一個全局的概覽。

我們可以在istio-system命名空間中看到所有的 Pod:

<h1 class="pgc-h-arrow-right" data-track="269">監控</h1>

Istio 內建了Prometheus,用于發送與網絡流量和服務相關的各種資訊。除此之外,它還提供了一個Grafana執行個體來可視化所有收集到的資料。

要通路 Grafana,我們可以使用 port-forward 指令來将 Pod 暴露出來:

打開浏覽器并導航至locahost:3000以通路 Grafana 的儀表盤。

Kiali是另外一個在 Istio 中運作的工具,它能夠管理 Istio 并觀察服務網格參數,比如服務是如何連接配接的、它們是如何執行的以及 Istio 資源是如何注冊的。

要通路 Kiali,我們可以使用 port-forward 指令來将 Pod 暴露出來:

打開浏覽器,通路 Istio 儀表盤,然後導航至 locahost:20001。

如何通過 Istio 實作微服務特性什麼是服務網格和 Istio?架構安裝 Istio應用概覽部署Istio 微服務特性服務發現回彈性故障重試斷路器認證認證授權可觀察性監控跟蹤結論

<h1 class="pgc-h-arrow-right" data-track="280">跟蹤</h1>

跟蹤用來可視化一個程式的流程和資料進展。Istio 會攔截所有的請求/響應,并将它們發送至Jaeger。

在這裡,我們可以不用 port-forward 指令,而是使用istioctl來暴露端口并自動打開頁面。

istioctl dashboard jaeger

如何通過 Istio 實作微服務特性什麼是服務網格和 Istio?架構安裝 Istio應用概覽部署Istio 微服務特性服務發現回彈性故障重試斷路器認證認證授權可觀察性監控跟蹤結論

<h1 class="pgc-h-arrow-right" data-track="284">結論</h1>

開發和實作微服務架構要比開發單體應用更具挑戰性。我們相信,微服務特性能夠促使你在應用基礎設施方面正确地開發服務。

Istio 在一個 sidecar 容器中實作了一些微服務特性,使得它們能夠跨所有的服務進行重用,獨立于應用所使用的程式設計語言。

除此之外,Istio 方式能夠讓我們在不重新部署服務的前提下改變服務的行為。

如果你計劃開發微服務并将它們部署到 Kubernetes 中,那麼 Istio 是一個切實可行的方案,因為它能夠與 Kubernetes 無縫內建。

本文中所用到的源碼可以在 GitHub 的倉庫中找到,本系列第一篇文章的源碼也可以在 GitHub 的倉庫中找到。

作者簡介:

Alex Soto 是紅帽公司的開發者體驗總監。他對 Java 領域、軟體自動化充滿熱情,他相信開源軟體模式。Soto 是Manning的《Testing Java Microservices》和O’Reilly的《Quarkus Cookbook》兩本書的共同作者,他還是多個開源項目的貢獻者。自 2017 年以來,他一直是 Java Champion,是國際演講者和 Salle URL 大學的教師。你可以在 Twitter 上關注他(Alex Soto ⚛️),随時了解 Kubernetes 和 Java 領域的動态。

原文連結:

Implementing Microservicilites with Istio