Istio介紹
一、Istio介紹
官方文檔:https://istio.io/docs/concepts/what-is-istio/
中文官方文檔:https://istio.io/zh/docs/concepts/what-is-istio/
Github地址:https://github.com/istio/istio/releases
1.1、Istio是什么
# 官當解釋:
An open platform to connect, secure, control and observe services.

1)連接(Connect):智能控制服務之間的調用流量,能夠實現灰度升級、AB 測試和藍綠部署等功能
2)安全加固(Secure):自動為服務之間的調用提供認證、授權和加密。
3)控制(Control):應用用戶定義的 policy,保證資源在消費者中公平分配。
4)觀察(Observe):查看服務運行期間的各種數據,比如日志、監控和 tracing,了解服務的運行情況。
Istio是ServiceMesh的產品化落地,可以通過在現有的服務器新增部署邊車代理(sidecar proxy),應用程序不用改代碼,或者只需要改很少的代碼,就能實現如下基礎功能:
1)幫助微服務之間建立連接,幫助研發團隊更好的管理與監控微服務,並使得系統架構更加安全;
2)幫助微服務分層解耦,解耦后的proxy層能夠更加專注於提供基礎架構能力,例如:
(1)服務發現(discovery);
(2)負載均衡(load balancing);
(3)故障恢復(failure recovery);
(4)服務度量(metrics);
(5)服務監控(monitoring);
(6)A/B測試(A/B testing);
(7)灰度發布(canary rollouts);
(8)限流限速(rate limiting);
(9)訪問控制(access control);
(10)身份認證(end-to-end authentication)。
1.1.1、服務注冊與發現

RPC:RPC(Remote Procedure Call)遠程過程調用,簡單的理解是一個節點請求另一個節點提供的服務
1.1.2、負載均衡
把前端的請求分發到后台多個服務器
1.1.3、故障恢復
出現故障具備自恢復的能力
1.1.4、服務度量
對於 HTTP,HTTP/2 和 GRPC 流量,Istio 生成以下指標:
1、請求計數(istio_requests_total):這是一個用於累加每個由 Istio 代理所處理請求的 COUNTER 指標。
2、請求持續時間(istio_request_duration_seconds):這是一個用於測量請求的持續時間的 DISTRIBUTION 指標。
3、請求大小(istio_request_bytes):這是一個用於測量 HTTP 請求 body 大小的 DISTRIBUTION 指標。
4、響應大小(istio_response_bytes):這是一個用於測量 HTTP 響應 body 大小的 DISTRIBUTION 指標。
對於 TCP 流量,Istio 生成以下指標:
1、Tcp 發送字節數(istio_tcp_sent_bytes_total):這是一個用於測量在 TCP 連接下響應期間發送的總字節數的 COUNTER 指標。
2、Tcp 接收字節數(istio_tcp_received_bytes_total):這是一個用於測量在 TCP 連接下請求期間接收的總字節數的COUNTER指標。
3、Tcp 打開連接數(istio_tcp_connections_opened_total):這是一個用於累加每個打開連接的 COUNTER 指標。
4、Tcp 關閉連接數 (istio_tcp_connections_closed_total) : 這是一個用於累加每個關閉連接的 COUNTER 指標。
1.1.5、灰度發布
灰度發布也叫金絲雀發布,起源是,礦井工人發現,金絲雀對瓦斯氣體很敏感,礦工會在下井之前,先放一只金絲雀到井中,如果金絲雀不叫了,就代表瓦斯濃度高。

1)在灰度發布開始后,先啟動一個新版本應用,但是並不直接將流量切過來,而是測試人員對新版本進行線上測試,啟動的這個新版本應用,就是我們的金絲雀。如果沒有問題,那么可以將少量的用戶流量導入到新版本上,然后再對新版本做運行狀態觀察,收集各種運行時數據,如果此時對新舊版本做各種數據對比,就是所謂的A/B測試。
2)當確認新版本運行良好后,再逐步將更多的流量導入到新版本上,在此期間,還可以不斷地調整新舊兩個版本的運行的服務器副本數量,以使得新版本能夠承受越來越大的流量壓力。直到將100%的流量都切換到新版本上,最后關閉剩下的老版本服務,完成灰度發布。
3)如果在灰度發布過程中(灰度期)發現了新版本有問題,就應該立即將流量切回老版本上,這樣,就會將負面影響控制在最小范圍內。
1.2、Istio核心特性
1.2.1、流控(traffic management)
斷路器(circuit breakers)、超時、重試、多路由規則、AB測試、灰度發布、按照百分比分配流量等。
1)斷路器

斷路器也稱為服務熔斷,在多個服務調用的時候,服務A依賴服務B,服務B依賴服務C,如果服務C響應時間過長或者不可用,則會讓服務B占用太多系統資源,而服務A也依賴服B,同時也在占用大量的系統資源,造成系統雪崩的情況出現。 Istio 斷路器通過網格中的邊車對流量進行攔截判斷處理,避免了在代碼中侵入控制邏輯,非常方便的就實服務熔斷的能力。
在微服務架構中,在高並發情況下,如果請求數量達到一定極限(可以自己設置閾值),超出了設置的閾值,斷路器會自動開啟服務保護功能,然后通過服務降級的方式返回一個友好的提示給客戶端。假設當10個請求中,有10%失敗時,熔斷器就會打開,此時再調用此服務,將會直接返回失敗,不再調遠程服務。直到10s鍾之后,重新檢測該觸發條件,判斷是否把熔斷器關閉,或者繼續打開。
服務降級(提高用戶體驗效果):比如電商平台,在針對618、雙11的時候會有一些秒殺場景,秒殺的時候請求量大,可能會返回報錯標志“當前請求人數多,請稍后重試”等,如果使用服務降級,無法提供服務的時候,消費者會調用降級的操作,返回服務不可用等信息,或者返回提前准備好的靜態頁面寫好的信息。
2)超時
在生產環境中經常會碰到由於調用方等待下游的響應過長,堆積大量的請求阻塞了自身服務,造成雪崩的情況,通過超時處理來避免由於無限期等待造成的故障,進而增強服務的可用性。

nginx 服務設置了超時時間為3秒,如果超出這個時間就不在等待,返回超時錯誤
httpd 服務設置了響應時間延遲5秒,任何請求都需要等待5秒后才能返回
client 通過訪問 nginx 服務去反向代理 httpd 服務,由於 httpd 服務需要5秒后才能返回,但nginx 服務只等待3秒,所以客戶端會提示超時錯誤。
3)重試
istio 重試機制就是如果調用服務失敗,Envoy 代理嘗試連接服務的最大次數。而默認情況下,Envoy 代理在失敗后並不會嘗試重新連接服務。

客戶端調用 nginx,nginx 將請求轉發給 tomcat。tomcat 通過故障注入而中止對外服務,nginx 設置如果訪問 tomcat 失敗則會重試 3 次。
4)多路由規則
1、HTTP重定向(HTTPRedirect)
2、HTTP重寫(HTTPRewrite)
3、HTTP重試(HTTPRetry)
4、HTTP故障注入(HTTPFaultInjection)
5、HTTP跨域資源共享(CorsPolicy)
1.2.2、安全(security)
加密、身份認證、服務到服務的權限控制、K8S里容器到容器的權限控制等。
1.2.3、可觀察(observability)
追蹤、監控、數據收集,通過控制后台全面了解上行下行流量,服務鏈路情況,服務運行情況,系統性能情況,國內微服務架構體系,這一塊做得比較缺乏。
1.2.4、平台無關系(platform support)
K8s,物理機,自己的虛機都沒問題。
1.2.5、集成與定制(integration and customization)
可定制化擴展功能。
二、Istio架構
2.1、架構圖
istio服務網格從邏輯上分為數據平面和控制平面。

1)數據平面由一組以Sidecar方式部署的智能代理(Envoy+Polit-agent)組成。這些代理承載並控制微服務之間的所有網絡通信,管理入口和出口流量,類似於一線員工。 Sidecar 一般和業務容器綁定在一起(在Kubernets中以自動注入的方式注入到到業務pod中),來劫持業務應用容器的流量,並接受控制面組件的控制,同時會向控制面輸出日志、跟蹤及監控數據。Envoy 和 pilot-agent 打在同一個鏡像中,即sidecar Proxy。
2)控制平面負責管理和配置代理來路由流量。istio1.5+中使用了一個全新的部署模式,重建了控制平面,將原有的多個組件整合為一個單體結構istiod,這個組件是控制平面的核心,管理Istio的所有功能,主要包括Pilot、Mixer、Citadel等服務組件。
istiod是新版本中最大的變化,以一個單體組件替代了原有的架構,降低了復雜度和維護難度,但原有的多組件並不是被完全移除,而是在重構后以模塊的形式整合在一起組成了istiod。
結合下圖我們來理解Istio的各組件的功能及相互之間的協作方式。

1)自動注入:在創建應用程序時自動注入 Sidecar代理Envoy程序。在 Kubernetes中創建 Pod時,Kube-apiserver調用控制面組件的 Sidecar-Injector服務,自動修改應用程序的描述信息並注入Sidecar。在真正創建Pod時,在創建業務容器的Pod中同時創建Sidecar容器。
2)流量攔截:在Pod初始化時設置iptables 規則,基於配置的iptables規則攔截業務容器的Inbound流量和Outbound流量到Sidecar上。而應用程序感知不到Sidecar的存在,還以原本的方式 進行互相訪問。上圖中,流出frontend服務的流量會被 frontend服務側的 Envoy攔截,而當流量到達forecast容器時,Inbound流量被forecast 服務側的Envoy攔截。
3)服務發現:服務發起方的 Envoy 調用控制面組件 Pilot 的服務發現接口獲取目標服務的實例列表。上圖中,frontend 服務側的 Envoy 通過 Pilot 的服務發現接口得到forecast服務各個實例的地址。
4)負載均衡:服務發起方的Envoy根據配置的負載均衡策略選擇服務實例,並連接對應的實例地址。上圖中,數據面的各個Envoy從Pilot中獲取forecast服務的負載均衡配置,並執行負載均衡動作。
5)流量治理:Envoy 從 Pilot 中獲取配置的流量規則,在攔截到 Inbound 流量和Outbound 流量時執行治理邏輯。上圖中, frontend 服務側的 Envoy 從 Pilot 中獲取流量治理規則,並根據該流量治理規則將不同特征的流量分發到forecast服務的v1或v2版本。
6)訪問安全:在服務間訪問時通過雙方的Envoy進行雙向認證和通道加密,並基於服務的身份進行授權管理。上圖中,Pilot下發安全相關配置,在frontend服務和forecast服務的Envoy上自動加載證書和密鑰來實現雙向認證,其中的證書和密鑰由另一個管理面組件 Citadel維護。
7)服務監測:在服務間通信時,通信雙方的Envoy都會連接管理面組件Mixer上報訪問數據,並通過Mixer將數據轉發給對應的監控后端。上圖中,frontend服務對forecast服務的訪問監控指標、日志和調用鏈都可以通過這種方式收集到對應的監控后端。
8)策略執行:在進行服務訪問時,通過Mixer連接后端服務來控制服務間的訪問,判斷對訪問是放行還是拒絕。上圖中,Mixer 后端可以對接一個限流服務對從frontend服務到forecast服務的訪問進行速率控制等操作。
9)外部訪問:在網格的入口處有一個Envoy扮演入口網關的角 色。上圖中,外部服務通過Gateway訪問入口服務 frontend,對 frontend服務的負載均衡和一些流量治理策略都在這個Gateway上執行。
2.2、控制平面組件--Pilot
Pilot 是 Istio 的主要控制組件,下發指令控制客戶端。在整個系統中,Pilot 完成以下任務:
1)從 Kubernetes 或者其他平台的注冊中心獲取服務信息,完成服務發現過程。
2)讀取 Istio 的各項控制配置,在進行轉換之后,將其發給數據面進行實施。

Pilot 將配置內容下發給數據面的 Envoy,Envoy 根據 Pilot 指令,將路由、服務、監聽、集群等定義信息轉換為本地配置,完成控制行為的落地。
1)Pilot為Envoy提供服務發現
2)提供流量管理功能(例如,A/B 測試、金絲雀發布等)以及彈性功能(超時、重試、熔斷器等);
3)生成envoy配置
4)啟動envoy
5)監控並管理envoy的運行狀況,比如envoy出錯時pilot-agent負責重啟envoy,或者envoy配置變更后reload envoy
2.3、控制平面組件--Citadel
1)負責處理系統上不同服務之間的TLS通信。 Citadel充當證書頒發機構(CA),並生成證書以允許在數據平面中進行安全的mTLS通信。
2)Citadel是 Istio的核心安全組件,提供了自動生 成、分發、輪換與撤銷密鑰和證書功能。Citadel一直監聽 Kube- apiserver,以 Secret的形式為每個服務都生成證書密鑰,並在Pod創建時掛載到Pod上,代理容器使用這些文件來做服務身份認證,進而代 理兩端服務實現雙向TLS認證、通道加密、訪問授權等安全功能。如圖 所示,frontend 服 務對 forecast 服務的訪問用到了HTTP方式,通過配置即可對服務增加認證功能,雙方的Envoy會建立雙向認證的TLS通道,從而在服務間啟用雙向認證的HTTPS。

2.4、控制平面組件--Galley
1)Galley是istio的配置驗證、提取、處理和分發的組件。Galley是提供配置管理的服務。實現原理是通過k8s提供的ValidatingWebhook對配置進行驗證。
2)Galley使Istio可以與Kubernetes之外的其他環境一起工作,因為它可以將不同的配置數據轉換為Istio可以理解的通用格式。
2.5、數據平面組件--Envoy
Envoy是用 C++ 開發的高性能代理,用於協調服務網格中所有服務的入站和出站流量。Envoy有許多強大的功能,例如:
動態服務發現
負載均衡
TLS終端
HTTP/2與gRPC代理
斷路器
健康檢查
流量拆分
灰度發布
故障注入

Envoy和Service A同屬於一個Pod,共享網絡和命名空間,Envoy代理進出Pod A的流量,並將流量按照外部請求的規則作用於Service A中。
Pilot-agent是什么?
Envoy不直接跟k8s交互,通過 pilot-agent管理的Pilot-agent進程根據K8S APIserver中的配置信息生成Envoy的配置文件,並負責啟動Envoy進程。
Envoy由Pilot-agent進程啟動,啟動后,Envoy讀取Pilot-agent為它生成的配置文件,然后根據該文件的配置獲取到Pilot的地址,通過數據面從pilot拉取動態配置信息,包括路由(route),監聽器(listener),服務集群(cluster)和服務端點(endpoint)。
2.6、控制平面組件--Ingressgateway
Ingressgateway 就是入口處的 Gateway,從網格外訪問網格內的服務就是通過這個Gateway進行的。istio-ingressgateway是一個Loadbalancer類型的Service,不同於其他服務組件只有一兩個端 口,istio-ingressgateway 開放了一組端口,這些就是網格內服務的外部訪問端口。如下圖所示,網格入口網關istio-ingressgateway的負載和網格內的Sidecar是同樣的執行流程,也和網格內的其他 Sidecar一樣從 Pilot處接收流量規則並執行。

2.7、控制平面--Sidecar-injector
Sidecar-injector是負責自動注入的組件,只要開啟了自動注 入,在Pod創建時就會自動調用istio-sidecar-injector向Pod中注入Sidecar 容器。
在 Kubernetes環境下,根據自動注入配置,Kube-apiserver在攔截到 Pod創建的請求時,會調用自動注入服務 istio-sidecar-injector 生成 Sidecar 容器的描述並將其插入原 Pod的定義中,這樣,在創建的 Pod 內除了包括業務容器,還包括 Sidecar容器,這個注入過程對用戶透明。
2.8、其他組件
除了以“istio”為前綴的Istio自有組件,在集群中一般還安裝Jaeger-agent、Jaeger-collector、Jaeger-query、Kiali、Prometheus、Grafana、 Tracing、Zipkin等組件,這些組件提供了Istio的調用鏈、監控等功能,可以選擇安裝來完成完整的服務監控管理功能。
