服務網格和Istio初識-續
-
- 4、為什麼服務網格選擇Istio
- 6、微服務和Istio的選擇側重
- 10、用什麼姿勢接入 Istio
本文是服務網格和Istio初識的續篇內容,主要是漫談(記錄)一些關於服務網格、 Istio
的一些理論及個人認知
為什麼還要寫這類看似枯燥的文章?我始終認為,學習和實踐應用一門新技術之前,應該做好多方調研,全域性認知,當前有什麼痛點能解決而不是有哪些功能能拿來用等等,到最後不至於僅僅是用了起來而已
1、服務治理的三種形態
服務治理的發展經過了以下三種形態的演進
sdk sidecar
2、服務網格的特點
- 基礎設施:服務網格是一種處理服務間通訊的基礎設施層
- 雲原生:服務網格尤其適用於在雲原生場景下幫助應用程式在複雜的服務拓撲間可靠地傳遞請求
- 網路代理:在實際使用中,服務網格一般是通過一組輕量級網路代理來執行治理邏輯的
- 對應用透明:輕量網路代理與應用程式部署在一起,但應用感知不到代理的存在,還是使用原來的方式工作
3、網格帶來的損耗
傳統環境下,服務 A
到服務 B
可以直接通過網路( ip
或服務名)直連
用了網格後,從 A
服務到 B
服務的一個訪問必須要經過 A
服務的 Sidecar
攔截 Outbound
流量執行治理動作;再經過 B
服務的 Sidecar
攔截 Inbound
流量,執行治理動作。 這就引入兩個問題:
- 增加了兩處延遲和可能的故障點
- 多出來的這兩跳對於訪問效能、整體可靠性及整個系統的複雜度都帶來了新的挑戰
通過保證轉發代理的輕量和高效能降低時延影響,尤其是考慮到後端實際使用的應用程式一般比代理更重,疊加代理並不會明顯影響應用的訪問效能;另外,對於這些高效能的代理,只要消耗足夠的資源總能達到期望的效能, 特別是雲原生場景下服務的彈性特點使得服務例項的彈性擴充套件變得非常方便,通過擴充套件例項數量總是能得到期望的訪問效能
因此最終需要決策的是:
是否願意花費額外的少量資源在這些基礎設施上來換取開發、運維的靈活性、業務的非侵入性和擴充套件性等便利?
4、為什麼服務網格選擇Istio
- 控制面設計
Istio
作為一種全新的設計,在功能、形態、架構和擴充套件性上提供了遠超服務網格的能力範圍。它基於 xDS
協議提供了一套標準的控制面規範,向資料面傳遞服務資訊和治理規則。 Istio
的早期版本使用 Envoy V1
版本的 API
,即 Restful
方式,其新版本使用 Envoy V2
版本的 API
,即 gRPC
協議。標準的控制面 API
解耦了控制面和資料面的繫結。 Nginx
的 nginMesh
、 F5 Networks
的 Aspen Mesh
等多種資料面代理支援 Istio
的控制面,甚至有些老牌微服務 SDK
也開始往 Istio
上整合
- 資料面設計
Istio
的標準資料面 Envoy
是由 Lyft
內部於 2016
年開發的,比 Linkerd
更早。 2016
年 9
月, Envoy
開源併發布了 1.0.0
版本; 2017
年 9
月, Envoy
加入 CNCF
,成為第 2
個 Service Mesh
專案; 2018
年 11
月, Envoy
從 CNCF
畢業,這標誌著其趨於成熟。從開發語言上看, Envoy
是使用 C++
開發的,其效能和資源佔用比用 Rust
開發的 Linkerd Proxy
要更好,更能滿足服務網格中對透明代理的輕量高效能要求;從能力上看, Envoy
提供 L3/L4
過濾器、 HTTP L7
過濾器,支援 HTTP/2
、 HTTP L7
路由及 gRPC
、 MongoDB
、 DynamoDB
等協議,有服務發現、健康檢查、高階 LB
、前端代理等能力,具有極好的 可觀察性、動態配置功能;從架構實現上看, Envoy
是一個可高度定製化的程式,通過 Filter
機制提供了 高度擴充套件性,還支援熱重啟,其程式碼基於模組化編碼,易於測試。除了在 Istio
中應用, Envoy
在其他 Service Mesh
框架中也被廣泛應用,漸漸成為 Service Mesh
的資料平面標準
- 大廠加持
Istio
由谷歌和 IBM
共同推出,從應用場景的分析規劃到本身的定位,從自身架構的設計到與周邊生態的結合,都有著比較嚴密的論證。 Istio
專案在發起時已經確認了將雲原生生態系統中的容器作為核心打包和執行時,將 Kubernetes
作為管理容器的編排系統,需要一個系統管理在容器 平臺上執行的服務之間的互動,包括控制訪問、安全、執行資料收集等,而 Istio
正是為此而生的;另外, Istio
成為架構的預設部分,就像容器和 Kubernetes
已經成為雲原生架構的預設部分一樣
另外一點,很多的公有云廠商在提供 kubernetes
容器服務時也內建了 Istio
功能或者二次開發(包裝)了 Istio
,例如阿里雲的 asm
5、Istio與kubernetes
Istio
和 Kubernetes
從設計理念、使用體驗、系統架構甚至程式碼風格等小細節來看,關係都非常緊密。更細粒度的proxy提供更多更細粒度的能力
Istio
最大化地利用了 Kubernetes
這個基礎設施,與之疊加在一起形成了一個更強大的用於進行服務執行和治理的基礎設施,並提供了更透明的使用者體驗。
- 資料面
資料面 Sidecar
執行在 Kubernetes
的 Pod
裡,作為一個 Proxy
和業務容器部署在一起。在服務網格的定義中要求應用程式在執行的時候感知不到 Sidecar
的存在。而基於 Kubernetes
的一個 Pod
多個容器的優秀設計使得部署運維對使用者透明,使用者甚至感知不到部署 Sidecar
的過程。使用者還是用原有的方式建立負載,通過 Istio
的自動注入服務,可以自動給指定的負載注入 Proxy
。如果在另一種環境下部署和使用 Proxy
,則不會有這樣的便利
- 統一服務發現
Istio
的服務發現機制非常完美地基於 Kubernetes
的域名訪問機制構建而成,省去了再搭一個類似 Eureka
的註冊中心的麻煩,更避免了在 Kubernetes
上執行時服務發現數據不一致的問題
儘管 Istio
強調自己的可擴充套件性的重要性在於適配各種不同的平臺,也可以對接其他服務發現機制,但在實際場景下,通過深入分析 Istio
幾個版本的程式碼和設計,便可以發現其重要的能力都是基於 Kubernetes
進行構建的
- 基於
Kubernetes CRD
描述規則
Istio
的所有路由規則和控制策略都是通過 Kubernetes CRD
實現的,因此各種規則策略對應的資料也被儲存在 kube-apiserver
中,不需要另外一個單獨的 APIServer
和後端的配置管理。所以,可以說 Istio
的 APIServer
就是 Kubernetes
的 APIServer
,資料也自然地被存在了對應 Kubernetes
的 etcd
中
Istio
非常巧妙地應用了 Kubernetes
這個好基座,基於 Kubernetes
的已有能力來構建自身功能。 Kubernetes
裡已經有的,絕不再自己搞一套,避免了資料不一致和使用者使用體驗的問題
Istio
不僅資料面 Envoy
跑在 Kubernetes
的 Pod
裡,其控制面也執行在 Kubernetes
叢集中,其控制面元件本身存在的形式也是 Kubernetes Deployment
和 Service
,基於 Kubernetes
擴充套件和構建

最後,看看微服務、容器、 Kubernetes
、 Istio
四者的關係

6、微服務和Istio的選擇側重
微服務是架構風格、方法論, Istio
是一套完整的實踐
但是,回到我在本文開頭提到的一點觀念, Istio
是用來解決問題的,並不是微服務理論的一種落地,在實際專案中拿著微服務的細節列表來硬套 Istio
的功能,比如要求 Istio
治理的服務必須實現微服務的服務註冊的一些細節,就明顯不太適當
7、Istio的侵入性
從單個應用來看, Sidecar
與應用程序的解耦帶來的應用完全無侵入、開發語言無關等特點解除了開發語言的約束,從而極大降低了應用開發者的開發成本。這種方式也經常被稱為一種應用的基礎設施層,類比 TCP/IP
網路協議棧,應用程式像使用 TCP/IP
一樣使用這個通用代理: TCP/IP
負責將位元組碼可靠地在網路節點間傳遞, Sidecar
則負責將請求可靠地在服務間進行傳遞。 TCP/IP
面向的是底層的資料流, Sidecar
則可以支援多種高階協議( HTTP
、 gRPC
、 HTTPS
等),以及對服務執行時進行高階控制,使服務變得可監控、可管理
從全域性來看,在多個服務間有複雜的互相訪問時才有服務治理的需求。即我們關注的是這些 Sidecar
組成的網格,對網格內的服務間訪問進行管理,應用還是按照本來的方式進行互相訪問,每個應用程式的 Inbound
流量和 Outbound
流量都要經過 Sidecar
代理,並在 Sidecar
上執行治理動作
Sidecar
是網格動作的執行體,全域性的管理規則和網格內的元資料維護通過一個統一的控制面實現,只有資料面的 Sidecar
和控制面有聯絡,應用感知不到 Sidecar
,更不會和控制面有任何聯絡,使用者的業務和控制面徹底解耦
8、Istio用在哪
Istio
是一個服務治理平臺,治理的是服務間的訪問,只要有訪問就可以治理,不在乎這個服務是不是 所謂的微服務,也不要求跑在其上的程式碼是微服務化的。單體應用即使不滿足微服務的若干哲學,用 Istio
治理也是完全可以的
9、Istio做了什麼
以前後端分離的服務為例
前端 服務的程式碼中通過域名訪問 後端 服務,在兩個服務中都不用包含任何服務訪問管理的邏輯。 Istio
在其中都做了什麼(可以做些什麼)
- 自動通過服務發現獲取服務例項列表,並根據負載均衡策略選擇一個服務例項
- 對服務雙方啟用雙向認證和通道加密
- 如果某個服務例項連續訪問出錯,則可以將該例項隔離一段時間,以提高訪問質量
- 設定最大連線數、最大請求數、訪問超時等對服務進行保護
- 限流
- 對請求進行重試
- 修改請求中的內容
- 將一定特徵的服務重定向
- 灰度釋出
- 自動記錄服務訪問資訊
- 記錄呼叫鏈,進行分散式追蹤
- 根據訪問資料形成完整的應用訪問拓撲
- ……
所有這些功能,都不需要使用者修改程式碼,使用者只需在 Istio
的控制面配置即可,並且動態生效
對業務程式碼完全沒有侵入性
10、用什麼姿勢接入 Istio
雖然 Istio
能解決那麼多的問題,但是引入 Istio
並不是沒有代價的。最大的問題是 Istio
的複雜性,強大的功能也意味著 Istio
的概念和元件非常多,要想理解和掌握 Istio
,併成功在生產環境中部署需要非常詳細的規劃。一般情況下,叢集管理團隊需要對 kubernetes
非常熟悉,瞭解常用的使用模式,然後採用逐步演進的方式把 Istio
的功能分批掌控下來
-
第一步,自然是在測試環境搭建一套
Istio
的叢集,理解所有的核心概念和元件。瞭解Istio
提供的介面和資源,知道它們的用處,思考如何應用到自己的場景中,然後是熟悉Istio
的原始碼,跟進社群的issues
,瞭解目前還存在的issues
和bug
,思考如何規避或者修復。這一步是基礎,需要積累到Istio
安裝部署、核心概念、功能和缺陷相關的知識,為後面做好準備 -
第二步,可以考慮接入
Istio
的觀察性功能,包括logging
、tracing
、metrics
資料。應用部署到叢集中,選擇性地(一般是流量比較小,影響範圍不大的應用)為一些應用開啟Istio
自動注入功能,接管應用的流量,並安裝prometheus
和zipkin
等監控元件,收集系統所有的監控資料。這一步可以試探性地瞭解Istio
對應用的效能影響,同時建立服務的效能測試基準,發現服務的效能瓶頸,幫助快速定位應用可能出現的問題。此時,這些功能可以是對應用開發者透明的,只需要叢集管理員感知,這樣可以減少可能帶來的風險 -
第三步,為應用配置
timeout
超時引數、自動重試、熔斷和降級等功能,增加服務的容錯性。這樣可以避免某些應用錯誤進行這些配置導致問題的出現,這一步完成後需要通知所有的應用開發者刪除掉在應用程式碼中對應的處理邏輯。這一步需要開發者和叢集管理員同時參與 -
第四步,和
ingress
、helm
、應用上架等相關元件和流程對接,使用Istio
接管應用的升級釋出流程。讓開發者可以配置應用灰度釋出升級的策略,支援應用的藍綠髮布、金絲雀釋出以及AB
測試 -
第五步,接入安全功能。配置應用的
TLS
互信,新增RBAC
授權,設定應用的流量限制,提升整個叢集的安全性。因為安全的問題配置比較繁瑣,而且優先順序一般會比功能性相關的特性要低,所以這裡放在了最後
當然這個步驟只是一個參考,需要根據自己的情況、人力、時間和節奏來調整,找到適合的方案
11、Istio不是銀彈
Istio
的架構在資料中心和叢集管理中非常常見,每個 agent
分佈在各個節點上(可以是伺服器、虛擬機器、pod、容器)負責接收指令並執行,以及彙報資訊;控制中心負責匯聚整個叢集的資訊,並提供 API
讓使用者對叢集進行管理。 kubernetes
也是類似的架構, SDN(Software Defined Network)
也是如此。相信以後會有更多類似架構的出現,這是因為資料中心要管理的節點越來越多,我們需要把任務執行分佈到各節點( agent
負責的功能),同時也需要對整個叢集進行管理和控制( control plane
的功能),完全去中心化的架構是無法滿足後面這個要求的
Istio
的出現為負責的微服務架構減輕了很多的負擔,開發者不用關心服務呼叫的超時、重試、 rate limit
的實現,服務之間的安全、授權也自動得到了保證;叢集管理員也能夠很方便地釋出應用(AB 測試和灰度釋出),並且能清楚看到整個叢集的執行情況
但是這並不表明有了 Istio
就可以高枕無憂了, Istio
只是把原來分散在應用內部的複雜性統一抽象出來放到了統一的地方,並沒有讓原來的複雜消失不見。因此我們需要維護 Istio
整個叢集,而 Istio
的架構比較複雜,尤其是它一般還需要架在 kubernetes
之上,這兩個系統都比較複雜,而且它們的穩定性和效能會影響到整個叢集。因此再採用 Isito
之前,必須做好清楚的規劃,權衡它帶來的好處是否遠大於額外維護它的花費,需要有相關的人才對整個網路、 kubernetes
和 Istio
都比較瞭解才行
- Gradle打包工具入門
- 服務網格和Istio初識-續
- 服務網格和Istio初識
- Golang與非對稱加密
- ack叢集Terway網路場景下的vSwitch擴容
- Golang與對稱加密
- 基於ack k8s叢集排程的方案設計
- 基於Dockerfile構建容器映象的最佳實踐
- Golang反射-下篇
- Golang反射-上篇
- Azure DevOps的使用入門
- Golang介面型別-下篇
- Golang介面型別-上篇
- 基於Python實現原生的登入驗證碼
- Golang開發命令列工具之flag包的使用
- Golang檔案操作-下篇
- k8s環境下處理容器時間問題的多種姿勢
- Golang基準測試
- 淺談Prometheus的資料儲存
- Golang單元測試