出處:https://www.cnblogs.com/ljhoracle/p/12545994.html
一、什麼是Service Mesh?下面是 Willian Morgan 對 Service Mesh 的解釋:
A Service Mesh is a dedicated infrastructure layer for handling service-to-service communication. It’s responsible for the reliable delivery of requests through the complex topology of services that comprise a modern, cloud native application. In practice, the Service Mesh is typically implemented as an array of lightweight network proxies that are deployed alongside application code, without the application needing to be aware.
簡單概況來說:服務網格(Service Mesh)是一個基礎設施層,用來實現服務間請求的可靠傳遞,對應用和開發者是透明的
個人理解:Service Mesh和RPC框架一樣是個概念,並不是具體的一個產品,不同的廠商有不同的實現,所以Istio對於Service Mesh就如同Thrift對於RPC框架一樣。
二、Service Mesh的出現過程當電腦第一次聯網由於人們首先想到的是讓兩臺或多臺電腦相互通訊,因此,他們構思出了這樣的東西:
上述這個修改過的模型自20世紀50年代以來一直使用至今。一開始,計算機很稀少,也很昂貴,所以兩個節點之間的每個環節都被精心製作和維護。隨著計算機變得越來越便宜,連線的數量和資料量大幅增加。隨著人們越來越依賴網路系統,工程師們需要保證他們構建的軟體能夠達到使用者所要求的服務質量。
當然,還有許多問題急需解決以達到使用者要求的服務質量水平。人們需要找到解決方案讓機器互相發現、透過同一條線路同時處理多個連線、允許機器在非直連的情況下互相通訊、透過網路對資料包進行路由、加密流量等等。
在這其中,有一種叫做 流量控制 的東西,下面我們以此為例。流量控制是一種防止一臺伺服器傳送的資料包超過下游伺服器可以承受上限的機制。這是必要的,因為在一個聯網的系統中,你至少有兩個不同的、獨立的計算機,彼此之間互不瞭解。 計算機A 以給定的速率向 計算機B 傳送位元組,但不能保證 B 可以連續地以足夠快的速度來處理接收到的位元組。例如, B 可能正在忙於並行執行其他任務,或者資料包可能無序到達,並且 B 可能被阻塞以等待本應該第一個到達的資料包。這意味著 A 不僅不知道 B 的預期效能,而且還可能讓事情變得更糟,因為這可能會讓 B 過載, B 現在必須對所有這些傳入的資料包進行排隊處理。
一段時間以來,大家寄希望於建立網路服務和應用程式的開發者能夠透過編寫程式碼來解決上面提出的挑戰。在我們的這個流程控制示例中,應用程式本身必須包含某種邏輯來確保服務不會因為資料包而過載。這種重聯網的邏輯與業務邏輯一樣重要。在我們的抽象示意圖中,它是這樣的:
幸運的是,技術的發展日新月異,隨著像TCP/IP這樣的標準的橫空出世,流量控制和許多其他問題的解決方案被融入進了網路協議棧本身。這意味著這些流量控制程式碼仍然存在,但已經從應用程式轉移到了作業系統提供的底層網路層中:
這個模型相當地成功。幾乎任何一個組織都能夠使用商業作業系統附帶的TCP/IP協議棧來驅動他們的業務,即使有高效能和高可靠性的要求。
當第一次使用微服務多年以來,計算機變得越來越便宜,並且到處可見,而上面提到的網路協議棧已被證明是用於可靠連線系統的事實上的工具集。隨著節點和穩定連線的數量越來越多,行業中出現了各種各樣的網路系統,從細粒度的分散式代理和物件到由較大但重分散式元件組成的面向服務的架構。
在90年代,Peter Deutsch和他在Sun公司的同事工程師們撰寫了“分散式計算的八大錯誤”一文,其中列出了人們在使用分散式系統時通常會做出的一些假設。Peter認為,這些假設在更原始的網路架構或理論模型中可能是真實的,但在現代世界中是不成立的:
網路是可靠的延遲為零頻寬是無限的網路是安全的拓撲是不變的有一個管理員傳輸成本為零網路是同構的大家把上面這個列表斥為“謬論”,因此,工程師們不能忽視這些問題,必須明確地處理這些問題。
計算資源的快速提供基本的監控快速部署易於擴充套件的儲存可輕鬆訪問邊緣認證與授權標準化的RPC因此,儘管數十年前開發的TCP/IP協議棧和通用網路模型仍然是計算機之間相互通訊的有力工具,但更復雜的架構引入了另一個層面的要求,這再次需要由在這方面工作的工程師來實現。
例如,對於 服務發現 和 斷路器 ,這兩種技術已用於解決上面列出的幾個彈性和分散式問題。
歷史往往會重演,第一批基於微服務構建的系統遵循了與前幾代聯網計算機類似的策略。這意味著落實上述需求的責任落在了編寫服務的工程師身上。
服務發現是在滿足給定查詢條件的情況下自動查詢服務例項的過程,例如,一個名叫Teams的服務需要找到一個名為Players的服務例項,其中該例項的environment屬性設定為production。你將呼叫一些服務發現程序,它們會返回一個滿足條件的服務列表。對於更集中的架構而言,這是一個非常簡單的任務,可以通常使用DNS、負載均衡器和一些埠號的約定(例如,所有服務將HTTP伺服器繫結到8080埠)來實現。而在更分散的環境中,任務開始變得越來越複雜,以前可以透過盲目信任DNS來查詢依賴關係的服務現在必須要處理諸如客戶端負載均衡、多種不同環境、地理位置上分散的伺服器等問題。如果之前只需要一行程式碼來解析主機名,那麼現在你的服務則需要很多行程式碼來處理由分散式引入的各種問題。
斷路器是由Michael Nygard在其編寫的“Release It”一書中引入的模式。我非常喜歡Martin Fowler對該模式的一些總結:
斷路器背後的基本思路非常簡單。將一個受保護的函式呼叫包含在用於監視故障的斷路器物件中。一旦故障達到一定閾值,則斷路器跳閘,並且對斷路器的所有後續呼叫都將返回錯誤,並完全不接受對受保護函式的呼叫。通常,如果斷路器發生跳閘,你還需要某種監控警報。
這些都是非常簡單的裝置,它們能為服務之間的互動提供更多的可靠性。然而,跟其他的東西一樣,隨著分散式水平的提高,它們也會變得越來越複雜。系統發生錯誤的機率隨著分散式水平的提高呈指數級增長,因此即使簡單的事情,如“如果斷路器跳閘,則監控警報”,也就不那麼簡單了。一個元件中的一個故障可能會在許多客戶端和客戶端的客戶端上產生連鎖反應,從而觸發數千個電路同時跳閘。而且,以前可能只需幾行程式碼就能處理某個問題,而現在需要編寫大量的程式碼才能處理這些只存在於這個新世界的問題。
大多數採用微服務架構的組織都遵循了上面提到的那個模型,如Netflix、Twitter和SoundCloud。隨著系統中服務數量的增加,他們發現了這種方法存在著各種弊端。
即使是使用像Finagle這樣的庫,專案團隊仍然需要投入大量的時間來將這個庫與系統的其他部分結合起來,這是一個代價非常高的難題。根據我在SoundCloud和DigitalOcean的經驗,我估計在100-250人規模的工程師組織中,需要有1/10的人員來構建模型。有時,這種代價很容易看到,因為工程師被分配到了專門構建工具的團隊中,但是更多的時候,這種代價是看不見的,因為它表現為在產品研發上需要花費更多的時間。
第二個問題是,上面的設定限制了可用於微服務的工具、執行時和語言。用於微服務的庫通常是為特定平臺編寫的,無論是程式語言還是像JVM這樣的執行時。如果開發團隊使用了庫不支援的平臺,那麼通常需要將程式碼移植到新的平臺。這浪費了本來就很短的工程時間。工程師沒辦法再把重點放在核心業務和產品上,而是不得不花時間來構建工具和基礎架構。那就是為什麼一些像SoundCloud和DigitalOcean這樣的中型企業認為其內部服務只需支援一個平臺,分別是Scala或者Go。
下一個邏輯類似於我們在網路協議棧中看到的那樣,大規模分散式服務所需的功能應該放到底層的 平臺 中。
人們使用高階協議(如HTTP)編寫非常複雜的應用程式和服務,甚至無需考慮TCP是如何控制網路上的資料包的。這種情況就是微服務所需要的,那些從事服務開發工作的工程師可以專注於業務邏輯的開發,從而避免浪費時間去編寫自己的服務基礎設施程式碼或管理整個系統的庫和框架。
將這個想法結合到我們的圖表中,我們可以得到如下所示的內容:
不幸的是,透過改變網路協議棧來新增這個層並不是一個可行的任務。許多人的解決方案是透過一組 代理 來實現。這個的想法是,服務不會直接連線到它的下游,而是讓所有的流量都將透過一個小小的軟體來透明地新增所需功能。
在這個領域第一個有記載的進步使用了 邊三輪(sidecars) 這個概念。“邊三輪”是一個輔助程序,它與主應用程式一起執行,併為其提供額外的功能。在2013年,Airbnb寫了一篇有關Synapse和Nerve的文章,這是“邊三輪”的一個開源實現。一年後,Netflix推出了Prana,專門用於讓非JVM應用程式從他們的NetflixOSS生態系統中受益。在SoundCloud,我們構建了可以讓遺留的Ruby程式使用我們為JVM微服務構建的基礎設施的“邊三輪”。
雖然有這麼幾個開源的代理實現,但它們往往被設計為需要與特定的基礎架構元件配合使用。例如,在服務發現方面,Airbnb的Nerve和Synapse假設了服務是在Zookeeper中註冊,而對於Prana,則應該使用Netflix自己的Eureka服務登錄檔 。
隨著微服務架構的日益普及,我們最近看到了一波新的代理浪潮,它們足以靈活地適應不同的基礎設施元件和偏好。 這個領域中第一個廣為人知的系統是Linkerd,它由Buoyant創建出來,源於他們的工程師先前在Twitter微服務平臺上的工作。很快,Lyft的工程團隊宣佈了Envoy的釋出,它遵循了類似的原則。
Service Mesh在這種模式中,每個服務都配備了一個代理“邊三輪”。由於這些服務只能透過代理“邊三輪”進行通訊,我們最終會得到類似於下圖的部署方案:
Buoyant的執行長威廉·摩根表示,代理之間的互連形成了 服務網格 。 2017年初,威廉寫下了這個平臺的定義,並稱它為 服務網格 :
服務網格是用於處理服務到服務通訊的專用基礎設施層。它負責透過複雜的服務拓撲來可靠地傳遞請求。實際上,服務網格通常被實現為與應用程式程式碼一起部署的輕量級網路代理矩陣,並且它不會被應用程式所感知。
這個定義最強大的地方可能就在於它不再把代理看作是孤立的元件,並承認它們本身就是一個有價值的網路。
隨著微服務部署被遷移到更為複雜的執行時中去,如Kubernetes和Mesos,人們開始使用一些平臺上的工具來實現網格網路這一想法。他們實現的網路正從互相之間隔離的獨立代理,轉移到一個合適的並且有點集中的控制面上來。
來看看這個鳥瞰圖,實際的服務流量仍然直接從代理流向代理,但是控制面知道每個代理例項。控制面使得代理能夠實現諸如訪問控制和度量收集這樣的功能,但這需要它們之間進行合作:
三、Service Mesh能解決什麼問題一個應用被拆分成了多個微服務,每個微服務又進行分散式部署,人工手動部署的話肯定是沒人願意的。因此Docker和Kubernetes等工具就出現了,實現了方便快捷將一個微服務應用成功部署。這些工具實現了整個部署過程的標準化。
一個服務產生價值的過程是在其執行期間與其他服務配合完成的,那麼這個配合過程是否也能標準化呢?正如前文所述,執行期間,服務的狀態與能力都是會變化的,為了能讓應用穩定執行,這就需要每個服務都具備負載均衡、檢測、通訊可靠、安全、日誌等能力。顯然這些功能可以被抽成庫,實現複用,比如谷歌的Stubby、Netflix的HYstrix、Twitter的Finagle等,提供了在執行期間服務之間的統一操作。其實這些庫就是service mesh。
庫方式的service mesh存在許多缺點,如以下幾點:
與服務耦合,主要會有程式碼入侵和升級難的問題。 首先,程式碼入侵。開發者需要了解如何使用這些SDK並完成相應的非業務程式碼。 其次,升級難。庫的更新會要求服務也更新,但出於對應用穩定性的考慮,或重新部署比較麻煩,開發者更新都比較謹慎,庫的相容性問題就出現了。依賴衝突。比如兩個庫都用到了fastjson,但由於依賴版本的不同,maven最近原則選擇了其中一個版本,那就可能導致另一個庫在執行時出現NoSuchMethod等錯誤,就需要手動解決衝突。無法跨語言。如果多語言支援代價很大,甚至可能需要重新開發一套。應用開發和服務運維界線不清。故障時,應用開發者往往需要自行定位問題,無法由庫的開發者統一對庫進行監控與運維,等等。另外一個辦法就是代理,用另一個標準化服務代理當前服務就完美的解決了上述問題。這個代理服務分散式部署在每個服務所在的機子上,對原來形態各樣服務的監控和負載均衡等操作,現在全部可透過對統一的代理服務的特定介面進行操作。由上,service mesh實現了服務之間操作的標準化,實現了執行期的服務治理,讓服務開發者迴歸業務開發與維護。
四、Service Mesh的代表產品Service Mesh的代表產品主要有 Linkerd 、 Envoy 、 Istio 和 Conduit 。
Buoyant公司給出了service mesh的定義,併發布第一個產品化的Service Mesh Linkerd。2016年9月Lyft釋出service mesh產品Envoy。2017年5月,Google和 IBM等大佬公司們聯合開發了Istio0.1版本release。Istio將Lyft開發的Envoy作為其資料面板部分。三大巨頭合作後,相比Linkerd新增了服務控制相關的控制面板,功能強大。Isotio發展迅速。而Linkerd卻發展趨勢急劇下降。2017年11月Linkerd就提出了和Istio整合,作為資料面板替換掉Envoy。不過Envoy穩定發展,並沒有受影響。2017年12月,Buoyant提出了最新產品Conduit,對標Istio。但目前看來,好像還是Istio發展更好
五、Istio架構介紹Service mesh的主要目的是實現服務執行時的標準化治理。Istio將服務的管理分為了兩大部分:資料面板和控制面板。
資料面板:就是上文中的sidecar部分,代理了服務的所有通訊。 控制面板:執行期間的服務控制,如流量控制和配置管理等。
Istio中,資料面板由Envoy實現。控制面板包括Pilot,Mixer,Istio-Auth三部分。 Envoy的功能包括:HTTP/1.1、HTTP/2、gRPC和TCP通訊;請求過濾;服務健康檢查;加密與認證;日誌服務;Distribution Trace等。 Pilot:服務發現;路由;負載均衡;故障處理;規則配置。官方描述為收集與驗證配置,並傳遞給Istio的其他元件。 Mixer:為了減少envoy與服務的耦合而存在,讓服務開發者僅關係業務本身,而驗證規則、服務監控規則等則分離出來放到Mixer中,由運維人員負責。Mixer的功能包括:前提條件檢查,比如請求的合法性驗證;配額管理,如限速;監測報告,上傳服務日誌等。 Istio-Auth:用於保證服務與服務之間的通訊安全。包括:身份認證,金鑰管理,請求稽核等。
六、Istio安裝參考: https://mp.weixin.qq.com/s?__biz=MzU0MTMyMDg1NQ==&mid=2247483756&idx=1&sn=ee475f20b9900aec7e56ae03313bf149&chksm=fb2af294cc5d7b82509ef23d7268370588b997d1b169970bbbce08810488f098024a5a84cb78&scene=21#wechat_redirect
安裝過程中出現的問題需要參考下面的連線去解決:
1、示例服務的dockerfile: https://github.com/bigwhite/experiments/tree/master/istio-demo
2、拉取映象失敗: https://hub.docker.com/u/bigwhite
3、本地curl請求不到service_a服務: https://www.jianshu.com/p/a45dca185afb ,
其中可以由 kubectl port-forward pod/nginx-6f754dd4b9-74jdn 8080:80 聯想到 kubectl port-forward svc/svca-6f754dd4b9-74jdn 8080:80
4、本地瀏覽器訪問不到Prometheus: https://blog.csdn.net/blanchedingding/article/details/84109400
5、本地Kubenertes-Dashbord啟動埠8001被佔用,可以使用:kill -9 `lsof -ti:8001` 殺死,然後使用kubectl proxy命令再啟動:
6、關於Istio的介紹: https://mp.weixin.qq.com/s?__biz=MzU0MTMyMDg1NQ==&mid=2247483653&idx=1&sn=4cd7b210b04fd32be48ab305da30bbf3&chksm=fb2af2fdcc5d7beb670099148882ebb1ced7995afe114b72e32434f39000b3d95f874ecd5cc6&scene=21#wechat_redirect
7、Istio及Bookinfo示例程式安裝: https://zhaohuabing.com/2017/11/04/istio-install_and_example/#heading
9、kubenertes進一步學習: https://github.com/cnych/kubernetes-learning/