博客原文地址 (https://elfgzp.cn/2020/06/21/新一代的微服務架構 Service Mesh html
因爲最近在工做中在作 Service Mesh
的落地項目,有很是多的感觸,因此想寫一篇文章來分享這個「新一代的微服務架構 Service Mesh
」。git
筆者會從如下順序開始分享:github
首先會從 「單體應用架構」 演進到 「微服務架構」 產生的問題開始提及,到本身做爲開發人員感觸最深的痛點。web
而後簡單介紹如下今天的主角 Istio
的服務編排環境 Kubernetes
。docker
最後從 Sidecar
這種設計,說到 Service Mesh
,最後到咱們的主角 Istio
。api
到正式的主角以前的鋪墊會比較多,這是爲了讓大多數開發者都能理解。安全
本文大部份內容都整理自筆者的學習資料加上本身的一些總結和體會,你們最後能夠從文末找到他們。服務器
從「單體」到「分佈式」演進(也就是微服務化)的緣由我相信你們都很瞭解了。網絡
由於業務量愈來愈大,咱們須要多臺機器才能應對大規模的應用,因此須要垂直或者水平拆分業務系統,讓其變成一個分佈式的架構。架構
從上面的表格咱們能夠看到,分佈式系統雖然有一些優點,但也存在一些問題。
做爲業務開發人員最直觀的感覺:
總結來講,微服務架構有這些痛點和須要解決的問題:
圖片引用自 《左耳聽風 - 分佈式系統技術棧》
針對這麼多的須要去解決和處理的問題。
引出了咱們今天的主角 Istio
。
在介紹咱們今天的主角 Istio
以前,先簡單介紹一下它的服務編排環境 Kubernetes
。經過 Docker
以及其衍生出來的 Kubernetes
之類的軟件或解決方案,大大地下降了作上面不少事情的門檻。
Docker
相信你們都很是瞭解了,因此這裏我就從 Docker
過分講到 k8s
。
Docker
容器這個聽起來玄而又玄的概念,其實是在建立容器進程時,指定了這個進程所須要啓用的一組 Namespace
參數。這樣,容器就只能「看」到當前 Namespace
所限定的資源、文件、設備、狀態,或者配置。而對於宿主機以及其餘不相關的程序,它就徹底看不到了。
int pid = clone(main_function, stack_size, CLONE_NEWPID | SIGCHLD, NULL);
咱們知道,在 Linux
系統中建立線程的系統調用是 clone()
,就像這樣。而當咱們用 clone()
系統調用建立一個新進程時,就能夠在參數中指定 CLONE_NEWPID
參數。這時,新建立的這個進程將會「看到」一個全新的進程空間,在這個進程空間裏,它的 PID
是 1。之因此說「看到」,是由於這只是一個「障眼法」,在宿主機真實的進程空間裏,這個進程的 PID
仍是真實的數值,好比 100。
因此說,容器,實際上是一種特殊的進程而已。
感興趣的同窗能夠閱讀 《本身動手寫 Docker》 和嘗試一下書中的代碼。
我花了不少精力去學習 Linux
容器的原理、理解了 Docker
容器的本質,終於, Namespace
作隔離, Cgroups
作限制, rootfs
作文件系統」 這樣的「三句箴言」能夠朗朗上口了。
爲何 Kubernetes
又忽然搞出一個 Pod
來呢?
這裏提一個概念: Pod
, 是 Kubernetes
項目中最小的 API
對象。若是換一個更專業的說法,咱們能夠這樣描述: Pod
是 Kubernetes
項目的原子調度單位。
這裏經過一個實際的例子來講明:
咱們經過 pstree
查看操做系統中運行的進程,進程並非「孤苦伶仃」地獨自運行的,而是以進程組的方式,「有原則地」組織在一塊兒。
好比,這裏有一個叫做 rsyslogd
的程序,它負責的是 Linux
操做系統裏的日誌處理。能夠看到, rsyslogd
的主程序 main
, 和它要用到的內核日誌模塊 imklog
等,同屬於 1632
進程組。這些進程相互協做,共同完成 rsyslogd
程序的職責。
若是說 「Docker 容器」的其實就是一個「特殊的進程」。
那麼「K8s」就能夠理解成操做系統。
Kubernetes
所作的,其實就是將 「進程組」 的概念映射到了容器技術中,並使其成爲了這個雲計算 「操做系統」 裏的 「原子調度單位」。
不過,相信此時你可能會有第二個疑問:
對於初學者來講,通常都是先學會了用 Docker
這種單容器的工具,纔會開始接觸 Pod
。而若是 Pod 的設計只是出於調度上的考慮,那麼 Kubernetes
項目彷佛徹底沒有必要非得把 Pod
做爲「原子調度單位」吧?
首先,關於 Pod
最重要的一個事實是:它只是一個邏輯概念。
具體的說: Pod
裏的全部容器,共享的是同一個 Network Namespace
,而且能夠聲明共享同一個 Volume
。
那這麼來看的話,一個有 A
和 B
兩個容器的 Pod
,不就是等同於一個容器(容器 A
)共享另一個容器(容器 B
)的網絡和 Volume
?這好像經過 docker run --net --volumes-from
這樣的命令就能實現,就像這樣。
可是,你有沒有考慮過,若是真這樣作的話,容器 B
就必須比容器 A
先啓動,這樣一個 Pod
裏的多個容器就不是對等關係,而是拓撲關係了。
因此,在 Kubernetes
項目裏, Pod
的實現須要使用一箇中間容器,在這個 Pod
中,中間容器永遠都是第一個被建立的容器,而其餘用戶定義的容器,則經過 Join Network Namespace
的方式,與 中間容器關聯在一塊兒。
如上圖所示,這個 Pod
裏有兩個用戶容器 A
和 B
,還有一箇中間容器容器。很容易理解,在 Kubernetes
項目裏,中間容器必定要佔用極少的資源,因此它使用的是一個很是特殊的鏡像,叫做: k8s.gcr.io/pause
。這個鏡像是一個用匯編語言編寫的、永遠處於「暫停」狀態的容器,解壓後的大小也只有 100~200 KB
左右。
這裏就再也不深刻說明了,感興趣的能夠點擊圖片連接,或者在文章末尾我列出的參考資料。
其中 Pod
的一個重要的特性,它的全部容器都共享同一個 Network Namespace。這就使得不少與 Pod
網絡相關的配置和管理,也均可以交給 Sidecar
完成,而徹底無須干涉用戶容器。
這裏最典型的例子莫過於 Istio
這個微服務治理項目了。
接下來就從 Sidecar
到 Service Mesh
來一步一步介紹 Istio 的設計思想。這裏提到的 Sidecar
究竟是什麼呢, Sidecar
在國內翻譯爲邊車模式,這個翻譯真的很形象。
所謂的邊車模式,對應於咱們生活中熟知的邊三輪摩托車。
圖片引用自 《左耳聽風 - 管理設計篇「邊車模式」》
咱們能夠經過給一個摩托車加上一個邊車的方式來擴展示有的服務和功能。這樣能夠很容易地作到 "控制 " 和 "邏輯" 的分離。
也就是說,咱們不須要在服務中實現控制面上的東西,如監視、日誌記錄、限流、熔斷、服務註冊、協議適配轉換等這些屬於控制面上的東西,而只須要專一地作好和業務邏輯相關的代碼,而後,由「邊車」來實現這些與業務邏輯沒有關係的控制功能。
圖片引用自 《左耳聽風 - 管理設計篇「邊車模式」》
那最終這個 Sidecar
的效果就會像上圖所示。
那麼在 Istio
中, [Envoy](https://github.com/envoyproxy/envoy)
就是默認的 Sidecar
。它與服務容器在同一個 Pod
中,與服務容器共享同一個 Network Namespace
,接管全部通過服務容器的流量。
而後, Sidecar
集羣就成了 Service Mesh
。圖中的綠色模塊是真實的業務應用服務,藍色模塊則是 Sidecar
, 其組成了一個網格。而咱們的應用服務徹底獨立自包含,只須要和本機的 Sidecar
依賴,剩下的事全交給了 Sidecar
。
圖片引用自 《左耳聽風 - 管理設計篇之「服務網格」》
Service Mesh
這個服務網絡專一於處理服務和服務間的通信。其主要負責構造一個穩定可靠的服務通信的基礎設施,並讓整個架構更爲的先進和 Cloud Native
。在工程中, Service Mesh
基原本說是一組輕量級的服務代理和應用邏輯的服務在一塊兒,而且對於應用服務是透明的。
說白了,就是下面幾個特色。
Service Mesh
是一個基礎設施。Service Mesh
是一個輕量的服務通信的網絡代理。Service Mesh
對於應用服務來講是透明無侵入的。Service Mesh
用於解耦和分離分佈式系統架構中控制層面上的東西。咱們今天的主角 Istio
,它的偉大之處不僅是在設計自己,而是在於它是一個兼容幷包的生態。它爲整個行業提供了一種全新的開發及運維的方式。
微服務架構在網絡鏈路上還有不少待解決的點,如鏈路跟蹤、分佈式日誌、監控報警、壓測演練、故障注入等。若讓 Istio
官方來實現全部的功能,不只耗時,還會讓整個系統變得很是臃腫。
接下來就用 Istio
的官方 Demo
來說一個實際的應用場景。
這部分會用 Istio 官方的 Demo 來演示,因此本文的大部份內容均可以在官方文檔中找到。
若是有感興趣的同窗能夠跟着這個 Demo
來實踐,可是可能須要一個 K8s
集羣,這裏推薦使用 Google Cloud Platform 的免費試用服務 GCP Free Tier - Free Extended Trials and Always Free。
固然若是想本身折騰搭建 K8s
集羣的同窗能夠參考筆者的這篇文章 「K8s 學習日記」Kubeadm 部署 kubernetes 集羣。
可是筆者仍是建議使用谷歌的服務,體驗雲原生的方式。
Bookinfo
應用分爲四個單獨的微服務:
productpage
. 這個微服務會調用 details
和 reviews
兩個微服務,用來生成頁面。details
. 這個微服務中包含了書籍的信息。reviews
. 這個微服務中包含了書籍相關的評論。它還會調用 ratings
微服務。ratings
. 這個微服務中包含了由書籍評價組成的評級信息。reviews
微服務有 3 個版本:
ratings
服務。ratings
服務,並使用 1 到 5 個黑色星形圖標來顯示評分信息。ratings
服務,並使用 1 到 5 個紅色星形圖標來顯示評分信息。下圖展現了這個應用的端到端架構。
在實際的應用場景中,咱們當前發佈了兩個 Reviews
服務的 feature
版本 v2
和 v3
版本。可是若是須要對這些服務進行測試。
爲了開發人員在測試本身開發的 Review
服務不受影響,咱們可能須要部署多個完整的 Bookinfo 應用
即 Product page
、 Ratings
、 Details
的服務都須要部署,以下圖所示 。
官方的 BookInfo
中的微服務數量仍是比較少的,在實際的場景中,一個完整的系統可能會有成百上千個微服務共同支撐和運行,若是爲了開發測試方便就須要龐大的服務器資源提供給微服務進行部署,這也是目前筆者公司的一個痛點。
在官方的 demo
中,有這樣一個例子。
未來自名爲 Jason
的用戶的全部流量路由到服務 reviews:v2
。將請求頭中 end-user
值爲 jason
的全部請求指向 reviews:v2
。
正常來講,這樣的功能應該須要在具體語言的 Web
框架層進行實現,可是因爲 Istio
的 Sidecar
接管了全部的流量,這個功能就在 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 發佈!