1 Istio是什么?
Istio 1.0版本於8月1號凌晨准點發布,核心特性已支持上生產環境,各大微信公眾號、博客紛紛發文轉載。那么Istio到底是什么?能解決問題什么?
1、 Istio是Google繼Kubernetes之后的又一開源力作,主要參與的公司包括Google,IBM,Lyft等,它提供了完整的非侵入式的微服務治理解決方案,解決微服務的管理、網絡連接以及安全管理等應用網絡治理問題
2、 它無需修改任何代碼就能夠實現微服務的負載均衡,服務與服務之間的認證授權以及流量監控和治理。從整個基礎設施角度上看,可以將它理解為PaaS平台上的一個面向微服務管理平台的補充。

2 Istio與Kubernetes
Kubernetes提供了部署、升級和有限的運行流量管理能力;利用service的機制來做服務注冊和發現,轉發,通過kubeproxy有一定的轉發和負載均衡能力。但並不具備上層如熔斷、限流降級、調用鏈治理等能力.
Istio則很好的補齊了k8s在微服務治理上的這部分能力,同時是基於k8s構建的,但不是像SpringCloud Netflix等完全重新做一套。Istio是谷歌微服務治理上的非常關鍵的一環。

3 Istio流量管理能力介紹
Istio,用於連接、保護、控制和觀測服務。
今天,我們就來談談Istio第一主打功能——連接服務。
那么,便引出3個問題:
Istio如何實現服務之間的連接?
連接后具備哪些流量管理能力?
如何告訴Istio發揮這些能力?
3.1 Istio如何實現服務的連接?

如上圖所示的Istio架構圖,讓我們關注控制面的Pilot,它是Istio實現流量管理的核心組件。
而在數據面,每個Service,都會被注入1個Proxy。Istio通過Pilot下發配置信息給數據面每1個Service的Proxy,從而通過這些Proxy,間接地控制每1個Service之間以及和外部的連接。Proxy通常采用另一個知名的開源項目Envoy來實現。
1個Pilot和(N+N)個(Service+Proxy)組合,便形成了Service Mesh,即服務網格。有了這一套服務網格系統,對服務之間的流量進行管理,便不在話下。
3.2 連接后具備哪些流量管理能力?
從服務間的流量管理角度而言,Istio可以實現這4項功能:請求路由、服務發現和負載均衡、故障處理和故障注入。
3.2.1 請求路由

如上圖所示,Istio引入了服務版本的概念,可以通過(Current Version,Canary Version)2個版本對服務進行進一步的細分。基於這種划分,通過Pilot,你可以下發配置到Service A的Proxy,使得其95%的流量路由至Service B的Current版本,5%的流量路由至Service B的Canary版本。當然你也可以選擇雨露均沾,各分50%流量,或者霸道總裁,讓Canary版本占有100%的流量。

如上圖所示,除了按照百分比在不同版本之間分發流量,你還可以按照請求內容,將請求路由至不同的版本。例如,你可以發布一個Canary版本,只讓用着Macbook筆記本,且安裝了windows操作系統,還使用着360瀏覽器的用戶能夠訪問到。
這一切改變,都只需要你改動一個叫VirtualService的配置文件,眨個眼的功夫,Istio就已經通過Pilot幫你把新的配置下發下去了。
3.2.2 服務發現和負載均衡

如上圖所示,服務網格存在3個生命周期的動態循環:服務注冊、服務發現、負載均衡。
通常kubernetes,mesos等容器管理平台已經提供了服務注冊表,以跟蹤服務的負載實例,所以Pilot能輕而易舉地獲知服務網格內的所有服務注冊信息,並將這些信息告知所有服務里的Proxy,Proxy根據這些信息執行服務發現,並相應地動態更新其負載均衡池。一個服務通常有多個負載實例,Service A請求Service B時,可以配置不同的負載均衡模式:輪詢、隨機和帶權重的最少請求。假設此時Service B的某個負載實例出現故障,因為Service A中的Proxy會定期地執行服務發現,從而能及時將故障實例從其負載均衡池里排出。
3.2.3 故障處理
Envoy 提供了一套開箱即用,可選的故障處理功能,對應用中的服務大有裨益。這些功能包括:
- 超時
- 具備超時預算,並進行有限重試,重試之間的時長可抖動
- 並發連接數和上游服務請求數限制
- 對負載均衡池中的每個成員進行主動(定期)運行健康檢查
- 細粒度熔斷器(被動健康檢查)- 適用於負載均衡池中的每個實例
以Service A請求調用Service B為例。
對於功能1。若Service B明確地知道10s以后的超時,必定會帶來失敗,那將超時時長縮短,使得Service A可以更快得知結果並作出應對,不失為一個明智之舉。
對於功能2。對超載的Service B來說,重試之間的抖動極大的降低了重試造成的影響,而超時預算確保Service A在可預測的時間范圍內獲得響應(成功/失敗)。
對於功能3。限制Service A或其他服務對Service B的連接數和請求數,可以使得Service B免於遭遇DDOS攻擊,或承受過重的流量負擔而崩潰。
對於功能4和5。主動和被動健康檢查的組合最大限度地減少了在負載平衡池中訪問不健康實例的機會。當與平台級健康檢查(例如由 Kubernetes 或 Mesos 支持的檢查)相結合時,應用程序可以確保將不健康的負載實例快速地從服務網格中去除,從而最小化請求失敗和延遲產生影響。
總之,這些功能使得服務網格能夠耐受故障節點,並防止本地故障導致的其他節點的穩定性下降。
3.2.4 故障注入
雖然Proxy為在Istio上運行的服務提供了上節所言的大量故障處理機制,但測試整個服務網格所組成應用的端到端的故障恢復能力依然是必須的。錯誤配置的故障恢復策略(例如,跨服務調用的不兼容/限制性超時)可能導致應用程序中的關鍵服務持續不可用,從而破壞用戶體驗。
Istio 能在不殺死負載實例的情況下,將協議特定的故障注入到網絡中,在 TCP 層制造數據包的延遲或損壞。我們的理由是,無論網絡級別的故障如何,應用層觀察到的故障都是一樣的,並且可以在應用層注入更有意義的故障(例如,HTTP經典的4xx和5xx錯誤代碼),以檢驗和改善應用的韌性。
運維人員可以為符合特定條件的請求配置故障,還可以進一步限制遭受故障的請求的百分比。可以注入兩種類型的故障:延遲和中斷。延遲是計時故障,模擬網絡延遲上升或上游服務超載的情況。中斷是模擬上游服務的崩潰故障。中斷通常以 HTTP 錯誤代碼或 TCP 連接失敗的形式表現。
依舊以Service A請求調用Service B為例。
若給Service B設定了10s的延時或503中斷,則Service A將至少10s后才能得到請求的響應或請求的響應為503錯誤,通過多種場景覆蓋測試,可以得到Service A面對這些場景時的綜合表現情況,從而做出針對性的改良,增加其韌性。
3.3 如何告訴Istio發揮這些能力?
Istio有4個配置文件,幫我們全方位地定制以上所有流量管理需求: VirtualService, DestinationRule, ServiceEntry和 Gateway:
- 通過配置VirtualService,可以實現請求路由的功能;
- 通過配置DestinationRule,可以實現服務發現和負載均衡、故障處理和故障注入的功能;
- 通過配置ServiceEntry,讓服務網格內的服務,可以看到外面的世界;
- 通過配置Gateway,讓服務網格的服務,可以被全世界看到;
有了以上4大法寶,我們對服務網格進行流量管理的所有需求,都可以被滿足了。
限於篇幅,讓我們舉3個簡單的栗子:
假設我們的服務網格存在1個服務explorer,只有1個v1版本;存在另1個服務helloworld,有v1,v2兩個版本。
①若要使得explorer發起的所有請求,以75%的概率走向helloworld的v1版本,以25%走向v2版本,只要配置如下兩個文件VirtualService和DestinationRule,便可實現:
apiVersion: networking.Istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld
spec:
hosts:
- helloworld
http:
- route:
- destination:
host: helloworld
subset: v1
weight: 75
- destination:
host: helloworld
subset: v2
weight: 25
---
apiVersion: networking.Istio.io/v1alpha3
kind: DestinationRule
metadata:
name: helloworld
spec:
host: helloworld
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
②如果helloworld內部需要通過訪問www.google.com來獲取一些信息,才能告訴explorer這個世界是怎么樣的,需要配置如下2個文件ServiceEntry和DestinationRule:
apiVersion: networking.Istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: googleapis
spec:
hosts:
- "*.google.com"
ports:
- number: 443
name: https
protocol: http
---
apiVersion: networking.Istio.io/v1alpha3
kind: DestinationRule
metadata:
name: googleapis
spec:
host: "*.google.com"
③如果helloworld需要被服務網格外,而不僅僅是explorer服務訪問到,則需要配置如下2個文件Gateway和VirtualService:
apiVersion: networking.Istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
Istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- 'helloworld.com'
---
apiVersion: networking.Istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo
spec:
hosts:
- 'helloworld.com'
gateways:
- helloworld-gateway
http:
- route:
- destination:
host: helloworld
port:
number: 9080
至此,我們做一個簡單的總結:Istio提供的Pilot和Proxy,將成百上千個服務組成了一個服務網格,基於此,我們可以實現請求路由、服務發現和負載均衡、故障處理以及故障注入等流量管理能力,這一切,我們只需要通過對VirtualService, DestinationRule, ServiceEntry和 Gateway這4個資源做簡單的配置,即可實現。
K8S和Istio的碰撞,又會在Cloud Native的世界里,勾出怎樣的天雷和地火呢?
拭目以待。
