新一代的微服務架構 Service Mesh

新一代的微服務架構 Service Mesh

博客原文地址 (https://elfgzp.cn/2020/06/21/新一代的微服務架構 Service Mesh html

因爲最近在工做中在作 Service Mesh 的落地項目,有很是多的感觸,因此想寫一篇文章來分享這個「新一代的微服務架構 Service Mesh」。git

筆者會從如下順序開始分享:github

  • Part 1 從「單體應用架構」到「微服務架構」開始提及
  • Part 2 從「Docker」到 「K8s」
  • Part 3 從「邊車模式」到「服務網格」
  • Part 4 用「Istio Demo」來說一個實際的應用場景

首先會從 「單體應用架構」 演進到 「微服務架構」 產生的問題開始提及,到本身做爲開發人員感觸最深的痛點。web

而後簡單介紹如下今天的主角 Istio 的服務編排環境 Kubernetesdocker

最後從 Sidecar 這種設計,說到 Service Mesh,最後到咱們的主角 Istioapi

到正式的主角以前的鋪墊會比較多,這是爲了讓大多數開發者都能理解。安全

本文大部份內容都整理自筆者的學習資料加上本身的一些總結和體會,你們最後能夠從文末找到他們。服務器

Part 1「單體應用架構」到「微服務架構」開始提及

1.1 單體應用架構與微服務架構對比

「單體」「分佈式」演進(也就是微服務化)的緣由我相信你們都很瞭解了。網絡

由於業務量愈來愈大,咱們須要多臺機器才能應對大規模的應用,因此須要垂直或者水平拆分業務系統,讓其變成一個分佈式的架構架構

從上面的表格咱們能夠看到,分佈式系統雖然有一些優點,但也存在一些問題。

  • 架構設計變得複雜。
  • 部署單個服務會比較快,可是若是一次部署須要多個服務,流程會變得複雜。
  • 系統的吞吐量會變大,可是響應時間會變長。
  • 運維複雜度會由於服務變多而變得很複雜。
  • 架構複雜致使學習曲線變大。
  • 測試和查錯的複雜度增大。
  • 技術多元化,公司中可能會有多個技術棧,這會帶來維護和運維的複雜度。
  • 管理分佈式系統中的服務和調度變得困難和複雜。

做爲業務開發人員最直觀的感覺

  • 接口爲何這麼慢,明明只依賴了一個服務。我須要更新個人服務,可是哪些服務依賴了個人服務,此次更新會對哪些服務形成影響。
  • 我須要在代碼框架層編寫客戶端接入監控、日誌、鏈路追蹤、告警、健康檢查等各類各樣非業務相關的代碼
  • 測試很不方便,測試一個服務須要全部依賴的服務,測試環境資源緊張。
  • ...

1.2 微服務架構的痛點和須要解決的問題

總結來講,微服務架構有這些痛點和須要解決的問題:

  • 服務多,服務之間的依賴難以管理。
  • 服務之間的版本管理,不一樣版本的服務可能會有兼容性的問題。
  • 須要對總體架構監控,快速發現問題。
  • 資源調度管理。
  • 須要作流量控制。負載均衡、服務路由、熔斷、降級、限流、灰度發佈等流量相關的控制。

圖片引用自 《左耳聽風 - 分佈式系統技術棧》

針對這麼多的須要去解決和處理的問題。

引出了咱們今天的主角 Istio

在介紹咱們今天的主角 Istio 以前,先簡單介紹一下它的服務編排環境 Kubernetes。經過 Docker 以及其衍生出來的 Kubernetes 之類的軟件或解決方案,大大地下降了作上面不少事情的門檻。

Part 2「Docker」到 「K8s」

2.1 Docker 容器的本質

Docker 相信你們都很是瞭解了,因此這裏我就從 Docker 過分講到 k8s

Docker 容器這個聽起來玄而又玄的概念,其實是在建立容器進程時,指定了這個進程所須要啓用的一組 Namespace 參數。這樣,容器就只能「看」到當前 Namespace 所限定的資源、文件、設備、狀態,或者配置。而對於宿主機以及其餘不相關的程序,它就徹底看不到了。

int pid = clone(main_function, stack_size, CLONE_NEWPID | SIGCHLD, NULL);

咱們知道,在 Linux 系統中建立線程的系統調用是 clone(),就像這樣。而當咱們用 clone() 系統調用建立一個新進程時,就能夠在參數中指定 CLONE_NEWPID 參數。這時,新建立的這個進程將會「看到」一個全新的進程空間,在這個進程空間裏,它的 PID1。之因此說「看到」,是由於這只是一個「障眼法」,在宿主機真實的進程空間裏,這個進程的 PID 仍是真實的數值,好比 100

因此說,容器,實際上是一種特殊的進程而已。

感興趣的同窗能夠閱讀 《本身動手寫 Docker》 和嘗試一下書中的代碼。

2.2 K8s 最小調度單位 Pod

我花了不少精力去學習 Linux 容器的原理、理解了 Docker 容器的本質,終於, Namespace 作隔離, Cgroups 作限制, rootfs 作文件系統」 這樣的「三句箴言」能夠朗朗上口了。

爲何 Kubernetes 又忽然搞出一個 Pod 來呢?

這裏提一個概念: Pod, 是 Kubernetes 項目中最小的 API 對象。若是換一個更專業的說法,咱們能夠這樣描述: PodKubernetes 項目的原子調度單位。

這裏經過一個實際的例子來講明:

咱們經過 pstree 查看操做系統中運行的進程,進程並非「孤苦伶仃」地獨自運行的,而是以進程組的方式,「有原則地」組織在一塊兒。

好比,這裏有一個叫做 rsyslogd 的程序,它負責的是 Linux 操做系統裏的日誌處理。能夠看到, rsyslogd 的主程序 main, 和它要用到的內核日誌模塊 imklog 等,同屬於 1632 進程組。這些進程相互協做,共同完成 rsyslogd 程序的職責。

若是說 「Docker 容器」的其實就是一個「特殊的進程」。

那麼「K8s」就能夠理解成操做系統。

Kubernetes 所作的,其實就是將 「進程組」 的概念映射到了容器技術中,並使其成爲了這個雲計算 「操做系統」 裏的 「原子調度單位」

不過,相信此時你可能會有第二個疑問:

對於初學者來講,通常都是先學會了用 Docker 這種單容器的工具,纔會開始接觸 Pod。而若是 Pod 的設計只是出於調度上的考慮,那麼 Kubernetes 項目彷佛徹底沒有必要非得把 Pod 做爲「原子調度單位」吧?

首先,關於 Pod 最重要的一個事實是:它只是一個邏輯概念

具體的說: Pod 裏的全部容器,共享的是同一個 Network Namespace,而且能夠聲明共享同一個 Volume

那這麼來看的話,一個有 AB 兩個容器的 Pod,不就是等同於一個容器(容器 A)共享另一個容器(容器 B)的網絡和 Volume ?這好像經過 docker run --net --volumes-from 這樣的命令就能實現,就像這樣。

可是,你有沒有考慮過,若是真這樣作的話,容器 B 就必須比容器 A 先啓動,這樣一個 Pod 裏的多個容器就不是對等關係,而是拓撲關係了。

因此,在 Kubernetes 項目裏, Pod 的實現須要使用一箇中間容器,在這個 Pod 中,中間容器永遠都是第一個被建立的容器,而其餘用戶定義的容器,則經過 Join Network Namespace 的方式,與 中間容器關聯在一塊兒。

圖片引用自 《Service Mesh 實戰:用 Istio 軟負載實現服務網格 3.1.3 Pause 容器》

圖片引用自 《深刻剖析Kubernetes - 爲何咱們須要 Pod》

如上圖所示,這個 Pod 裏有兩個用戶容器 AB,還有一箇中間容器容器。很容易理解,在 Kubernetes 項目裏,中間容器必定要佔用極少的資源,因此它使用的是一個很是特殊的鏡像,叫做: k8s.gcr.io/pause。這個鏡像是一個用匯編語言編寫的、永遠處於「暫停」狀態的容器,解壓後的大小也只有 100~200 KB 左右。

這裏就再也不深刻說明了,感興趣的能夠點擊圖片連接,或者在文章末尾我列出的參考資料。

其中 Pod 的一個重要的特性,它的全部容器都共享同一個 Network Namespace。這就使得不少與 Pod 網絡相關的配置和管理,也均可以交給 Sidecar 完成,而徹底無須干涉用戶容器。

這裏最典型的例子莫過於 Istio 這個微服務治理項目了。

接下來就從 SidecarService Mesh 來一步一步介紹 Istio 的設計思想。這裏提到的 Sidecar 究竟是什麼呢, Sidecar 在國內翻譯爲邊車模式,這個翻譯真的很形象。

Part 3「邊車模式」到「服務網格」

3.1 邊車模式

所謂的邊車模式,對應於咱們生活中熟知的邊三輪摩托車。

圖片引用自 《左耳聽風 - 管理設計篇「邊車模式」》

咱們能夠經過給一個摩托車加上一個邊車的方式來擴展示有的服務和功能。這樣能夠很容易地作到 "控制 ""邏輯" 的分離。

也就是說,咱們不須要在服務中實現控制面上的東西,如監視、日誌記錄、限流、熔斷、服務註冊、協議適配轉換等這些屬於控制面上的東西,而只須要專一地作好和業務邏輯相關的代碼,而後,由「邊車」來實現這些與業務邏輯沒有關係的控制功能。

圖片引用自 《左耳聽風 - 管理設計篇「邊車模式」》

那最終這個 Sidecar 的效果就會像上圖所示。

那麼在 Istio 中, [Envoy](https://github.com/envoyproxy/envoy) 就是默認的 Sidecar。它與服務容器在同一個 Pod 中,與服務容器共享同一個 Network Namespace,接管全部通過服務容器的流量。

圖片引用自 《Kubernetes Istio Canary Deployment》

3.2 服務網格

而後, Sidecar 集羣就成了 Service Mesh。圖中的綠色模塊是真實的業務應用服務藍色模塊則是 Sidecar, 其組成了一個網格。而咱們的應用服務徹底獨立自包含,只須要和本機的 Sidecar 依賴,剩下的事全交給了 Sidecar

圖片引用自 《左耳聽風 - 管理設計篇之「服務網格」》

Service Mesh 這個服務網絡專一於處理服務和服務間的通信。其主要負責構造一個穩定可靠的服務通信的基礎設施,並讓整個架構更爲的先進和 Cloud Native。在工程中, Service Mesh 基原本說是一組輕量級的服務代理和應用邏輯的服務在一塊兒,而且對於應用服務是透明的

說白了,就是下面幾個特色。

  • Service Mesh 是一個基礎設施
  • Service Mesh 是一個輕量的服務通信的網絡代理
  • Service Mesh 對於應用服務來講是透明無侵入的。
  • Service Mesh 用於解耦和分離分佈式系統架構中控制層面上的東西。

3.3 Istio 與 Service Mesh

咱們今天的主角 Istio,它的偉大之處不僅是在設計自己,而是在於它是一個兼容幷包的生態。它爲整個行業提供了一種全新的開發及運維的方式。

圖片引用自 zhaohuabing/istio-practice

微服務架構在網絡鏈路上還有不少待解決的點,如鏈路跟蹤、分佈式日誌、監控報警、壓測演練、故障注入等。若讓 Istio 官方來實現全部的功能,不只耗時,還會讓整個系統變得很是臃腫。

接下來就用 Istio 的官方 Demo 來說一個實際的應用場景。

Part 4 用「Istio Demo」來說一個實際的應用場景

這部分會用 Istio 官方的 Demo 來演示,因此本文的大部份內容均可以在官方文檔中找到。

若是有感興趣的同窗能夠跟着這個 Demo 來實踐,可是可能須要一個 K8s 集羣,這裏推薦使用 Google Cloud Platform 的免費試用服務 GCP Free Tier - Free Extended Trials and Always Free

固然若是想本身折騰搭建 K8s 集羣的同窗能夠參考筆者的這篇文章 「K8s 學習日記」Kubeadm 部署 kubernetes 集羣

可是筆者仍是建議使用谷歌的服務,體驗雲原生的方式。

4.1 Istio Demo「Bookinfo 應用」服務架構

Bookinfo 應用分爲四個單獨的微服務:

  • productpage. 這個微服務會調用 details 和 reviews 兩個微服務,用來生成頁面。
  • details. 這個微服務中包含了書籍的信息。
  • reviews. 這個微服務中包含了書籍相關的評論。它還會調用 ratings 微服務。
  • ratings. 這個微服務中包含了由書籍評價組成的評級信息。

reviews 微服務有 3 個版本:

  • v1 版本不會調用 ratings 服務。
  • v2 版本會調用 ratings 服務,並使用 1 到 5 個黑色星形圖標來顯示評分信息。
  • v3 版本會調用 ratings 服務,並使用 1 到 5 個紅色星形圖標來顯示評分信息。

下圖展現了這個應用的端到端架構。

圖片引用自 《 ISTIO 文檔示例 BOOKINFO 應用》

對 Reviews-v二、Reviews-v3 服務進行測試

在實際的應用場景中,咱們當前發佈了兩個 Reviews 服務的 feature 版本 v2v3 版本。可是若是須要對這些服務進行測試。

爲了開發人員在測試本身開發的 Review 服務不受影響,咱們可能須要部署多個完整的 Bookinfo 應用Product pageRatingsDetails 的服務都須要部署,以下圖所示 。

官方的 BookInfo 中的微服務數量仍是比較少的,在實際的場景中,一個完整的系統可能會有成百上千個微服務共同支撐和運行,若是爲了開發測試方便就須要龐大的服務器資源提供給微服務進行部署,這也是目前筆者公司的一個痛點。

利用 Istio 對流量進行控制

在官方的 demo 中,有這樣一個例子。

未來自名爲 Jason 的用戶的全部流量路由到服務 reviews:v2。將請求頭中 end-user 值爲 jason

的全部請求指向 reviews:v2

正常來講,這樣的功能應該須要在具體語言的 Web 框架層進行實現,可是因爲 IstioSidecar 接管了全部的流量,這個功能就在 Istio 中已經集成了。

對於開發人員來時也就是簡單的一個配置和一行命令:

$ kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml
$ kubectl get virtualservice reviews -o yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
  ...
spec:
  hosts:
  - reviews
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    route:
    - destination:
        host: reviews
        subset: v2
  - route:
    - destination:
        host: reviews
        subset: v1

Istio 的流量控制放到實際的應用場景中時,測試環境就只須要一套完整的服務,和一些須要測試的不一樣版本的服務了。

固然這只是其中一個應用場景,流量控制還能夠用於 A/B 測試,灰度發佈等。而且這只是 Istio 的其中一個功能。

筆者也不一一去介紹 Istio 的其餘功能了,如:服務安全、鏈路追蹤、網絡拓撲、服務註冊等等服務治理相關的功能,感興趣的同窗能夠閱讀官方文檔。

除了官方給出的 demo , 感興趣的同窗還能夠在這個網站上找到更多的例子,https://istiobyexample.dev/

結尾

以上就是筆者想分享的所有內容,在這個雲計算時代,筆者相信 Service Mesh 將會成爲微服務架構中的一個佼佼者,幫助咱們更好治理微服務架構。

參考文獻

本文由博客一文多發平臺 OpenWrite 發佈!

相關文章
相關標籤/搜索