Service Mesh實踐之Istio初體驗
- 2019 年 12 月 11 日
- 筆記
微服務中國發展背景
2014年,Martin Fowler撰寫的《Microservices》[1]使得許多中國的先行者接觸到微服務這個概念並將其引入中國,2015年越來越多的人通過各種渠道了解到微服務的概念並有人開始在生產環境中落地,2016-2017年,微服務的概念被越來越多的人認可,帶動了一大批公司以微服務和容器為核心開始技術架構的全面革新。
至今微服務已經歷了兩代發展,第一代以Spring Cloud為代表的微服務開發框架,該框架在微服務發展的前幾年一度獨領風騷,甚至在部分人群中成為微服務的代名詞,但事實上該微服務框架並不是唯一實現微服務的方式;第二代微服務技術為服務網格(Service Mesh),它的出現解決了大部分開發人員在使用Spring Cloud中遇到的不足和痛點。
Service Mesh是如何解決這些問題的,又是何以贏得眾多開發者的支援呢?筆者就這些問題給大家分享一篇以Istio為代表的第二代微服務實踐。
此篇文章分為兩個部分,第一部分為微服務相關概念介紹,第二部分為Istio具體實踐。
一、微服務和Istio
1Service Mesh基本概念
服務網格是一個基礎設施層,主要用於處理服務間的通訊。雲原生應用有著複雜的服務拓撲,服務網格負責在這些拓撲中實現請求的可靠傳遞。在實踐中,服務網格通常實現為一組輕量級網路代理,它們與應用程式部署在一起,而對應用程式透明。
圖1展示了服務網格的拓撲,當微服務數量增多達到幾十上百時,服務網格就會呈現服務網格狀,其中綠色為微服務,藍色為服務網格,服務網格以典型的sidecar方式部署在微服務旁。
sidecar: 一種單節點、多容器的應用設計形式。sidecar主張以額外的容器來擴展或增強主容器,而這個額外的容器被稱為sidecar容器。

圖1 Service Mesh
2Istio基本概念
Istio是由Google、IBM、Lyft聯合開發的開源項目,2017年5月發布第一個release 0.1.0, 它是一個完全開源的服務網格,可以透明的分層到現有的分散式應用中,它也是一個平台,包括允許它集成到任何日誌記錄平台,遙測或策略系統的API。Istio 多樣化功能集能夠高效的運行在分散式微服務架構中,並同時提供保護、連接和監控微服務等方法。
3Istio基本架構

圖2 Istio架構[2]
由圖2可知,Istio架構在網格邏輯上主要分為控制平面(Control Plane API)和數據平面(Data Plane)
控制平面:負責管理和配置代理來路由流量。主要分為三個組件Pilot、Mixer、Citadel,由於篇幅有限,此處對概念進行簡單介紹:
「
(1)Pilot
為Envoy sidecar提供服務發現功能,為智慧路由和彈性提供管理功能,它將控制流量行為的高級路由轉化為特定於Envoy的配置,並在運行時將它們傳播到sidecar。
(2)Mixer
獨立於平台,負責在Service Mesh上執行訪問控制和使用策略,並從Envoy代理和其它服務中收集遙測數據。
(3)Citadel
通過內置身份和憑證管理以提供服務與服務間的身份驗證並且可以升級Service Mesh中未加密的流量。
數據平面:由一組以sidecar方式部署的智慧代理組成,這些代理可以調節和控制微服務及Mixer之間所有的網路通訊。Istio默認使用Envoy做智慧代理,當然也支援其它代理,例如Linkerd、Nginmesh等。
(1)Envoy: C++開發的高性能代理,用於調解Service Mesh中所有的入站和出站流量。Envoy含有許多的內置功能:動態服務發現、負載均衡、熔斷器、健康檢查、HTTP/2和gRPC代理等。Envoy在Istio中被部署為sidecar,和對應的微服務在同一個Kubernetes Pod中,Istio將其功能添加到sidecar中來對微服務進行管理而無需更改微服務應用程式碼,起到一個無侵入式的作用。
二、為什麼要使用Istio?
隨著微服務規模的增長,其複雜性也越來越高,其中面臨許多需求,例如服務發現、故障恢復、監控、負載均衡、限流、訪問控制等,Istio提供了一體化的方案,通過為整個Service Mesh提供管理來滿足微服務應用中複雜變換的需求,其中提供了許多非常關鍵的需求[3]:
(1)流量管理:控制服務之間流量和API調用,使得調用更可靠。
(2)可觀察性:了解服務之間依賴關係,以及它們之間流量的本質和流向
(3)策略執行:策略應用於微服務之間互動,確保訪問策略得以執行(執行是通過配置網格而不是修改程式程式碼)
(4)服務身份安全:為網格中的服務提供可靠身份驗證,並提供保護流量的能力。
三、試用Istio
Istio實踐主要分為三步,第一步下載並部署Istio;第二步部署Bookinfo微服務;第三步通過指定yaml文件測試Istio的功能特性。
主要配置環境如下:
作業系統:Ubuntu 16.04
Kubernetes(簡稱k8s)對應版本:

圖3 k8s工具版本
k8s集群為:

圖4 k8s節點資訊
1第一步:安裝Istio
在終端首先獲取最新的Istio安裝包
curl -L https://git.io/getLatestIstio | sh -
進入安裝包目錄後進入install/kubernetes/目錄安裝k8s所需yaml文件,如圖5所示:

圖5 Istio安裝包
使用kubectl運行istio-demo.yaml文件(有四種方式安裝,對應有不同的yaml文件,此處選擇默認不啟用TLS身份驗證的安裝方式,啟用TLS安裝方式的yaml文件為istio-demo-auth.yaml),安裝過程如圖6所示:
kubectl create –f istio-demo.yaml

圖6 Istio安裝過程
顯示已安裝成功(由於安裝內容較多,只截圖了其中一部分),之後查看已部署的Istio Pod運行狀況:
kubectl get po -o wide --all-namespaces

圖7 Istio中運行的Pod
由圖7可以看出k8s中命名空間為istio-system的Pod,其中包含許多組件,如用於監控的grafana、prometheus,用於服務查看的servicegraph,以及Istio組件citadel、mixer、pilot等。
可以再查看Istio安裝包中安裝的service,其中PORTS欄可以查看服務對外暴露的埠號,以便在外部訪問,如圖8所示:
kubectl get svc -n istio-system

圖8 Istio中運行的service
為了使用Istio的命令行工具istioctl,需要指定環境變數以便後期使用:
export PATH=/home/xxxx/istio-1.0.0/bin:$PATH
下面可以簡單看看istioctl的命令使用,如圖8所示:

圖9 istioctl基本命令
2第二步:部署bookinfo微服務
Bookinfo是Istio提供的一個樣例應用,它由四個單獨的微服務構成,用來演示多種 Istio 特性:
(1)productpage: productpage微服務會調用details和reviews兩個微服務,用來生成頁面。
(2)details:此微服務包含書籍的資訊。
(3)reviews:此微服務包含書籍的相關評論,它會調用ratings微服務。
(4)ratings: 此微服務包含書籍評價的評級資訊。
其中reviews微服務包含三個版本:
(1)v1版本不會調用ratings微服務。
(2)v2版本調用ratings並使用5個黑色星型圖標顯示評分資訊。
(3)v3版本調用ratings並使用5個紅色星型圖標顯示評分資訊。
圖10為bookinfo架構:

圖10 bookinfo架構圖
其中所有的微服務都和Envoy sidecar集成在一起,所有服務的出入流量都被Envoy劫持,這樣Istio的控制平面就可以為應用提供服務路由、遙測數據收集以及策略實施等內容。
由於之前已經下載了bookinfo相關yaml文件,所以直接執行就好了,如圖11,12所示:
kubectl create –f bookinfo.yaml
kubectl create –f bookinfo-gateway.yaml

圖11運行bookinfo

圖12 運行bookinfo-gateway
查看k8s中bookinfo應用運行狀況,如圖13所示:
kubectl get po

圖13 bookinfo運行的Pod
查看bookinfo中service部署情況,如圖14所示:
kubectl get svc

圖14 bookinfo運行的service
至此bookinfo應用已部署完畢,那麼如何訪問bookinfo中的微服務呢?通過前面所講可知bookinfo有對應的web微服務productpage,可以通過以下方式訪問:
(1)首先確定Ingress的IP和埠:
port:
export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
secure port:
export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].nodePort}')
host:
export INGRESS_HOST=$(kubectl get po -l istio=ingressgateway -n istio-system -o 'jsonpath={.items[0].status.hostIP}')
GATEWAY_URL:
export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT
具體操作如圖15所示,可知網關入口為20.0.0.13:31380

圖15 配置Ingress地址
測試Bookinfo應用的運行情況,返回200為正常,如圖16所示:
curl -o /dev/null -s -w "%{http_code}n" http://${GATEWAY_URL}/productpage

圖16 測試Bookinfo運行情況
在Chrome瀏覽器中輸入,如圖17所示:
http://192.168.19.13:31380/productpage

圖17 Bookinfo應用Web介面
上圖可以看出Bookinfo應用由4個微服務組成,即web微服務頁面productpage、頁面左邊部分為Book Details服務,右邊部分為Book Reviews服務, reviews服務目前為v1狀態即無星級評分。由於未設置請求路由,多刷新頁面幾次,請求路由流量會隨機的在reviews服務v1,v2,v3中切換。
3第三步:驗證Istio功能
(1)請求路由
此樣例會把Bookinfo應用的進入流量導向reviews服務的v1版本,配置yaml文件如圖18所示:

圖18 route-rule-all-v1.yaml文件部分內容
終端執行以下命令,如圖19所示:
kubectl apply -f route-rule-all-v1.yaml

圖19 route-rule-all-v1.yaml文件執行過程
此時多次刷新頁面就會發現每次刷新reviews服務始終為v1版本。
如果想看具體的virtualservices和destinationrules可以通過命令查看:
kubectl get virtualservices -o yaml
kubectl get destinationrules -o yaml
請求也可以基於用戶身份去路由,比如「xx」登錄就是reviews服務的v1版本,其它用戶登錄則為v2版本。
(2)故障注入
此樣例會使用Istio測試Bookinfo應用的彈性,具體方式為當用戶jason登錄時在reviews:v2和ratings之間進行延遲注入。此樣例對應yaml文件如圖20所示:

圖20 route-rule-ratings-test-delay.yaml文件內容
終端執行以下命令,如圖21所示:
kubectl replace -f route-rule-ratings-test-delay.yaml

圖21 route-rule-ratings-test-delay.yaml文件執行過程
此時用jason帳號登錄就會發現每次請求路由到reviews微服務都要6秒左右,可以打開chrome瀏覽器開發者工具查看,並且reviews部分顯示錯誤消息,如圖22所示:

圖22 故障注入頁面展示
(3)流量遷移
此樣例會使用Istio將所有用戶的流量按照權重進行轉移,此樣例對應的yaml文件如圖23所示:

圖23 route-rule-reviews-50-v3.yaml文件內容
由上圖可知當有流量進入時,百分之五十流量遷移到reviews v1,另外百分之五十流量遷移到reviews v3,終端執行以下命令,如圖21所示:
kubectl replace -f route-rule-reviews-50-v3.yaml
此時刷新頁面就會看到有一半的概率是reviews v3(紅色星),一半概率是reviews v1(無評星)。
(4)設定請求超時
此樣例首先將流量全部導入reviews v2服務,再給ratings服務增加2秒延遲,最後為reviews服務調用添加0.5秒請求超時,順序如圖24-29所示:

圖24 流量導入reviews v2

圖25 productpage頁面顯示reviews v2

圖26 ratings服務添加2秒延遲

圖27 ratings服務添加延遲web頁面效果

圖28 reviews服務添加0.5秒請求超時

圖29 reviews服務添加超時web頁面效果
最終刷新頁面由圖29顯示,看到返回時間為1秒左右並且評論不可用,這是為什麼呢?答案是productpage服務有硬編碼重試,因此在頁面刷新時,請求返回之前需要調用超時reviews服務兩次,每次為0.5秒左右,兩次就為1秒左右了。
大家想像下,當微服務的數量增多時,運維人員根據需求需要對部分微服務進行A/B測試,金絲雀發布或是限流、流量分片等操作,這無疑增加了運維人員的管理複雜度,Istio考慮的非常周全,在安裝包中附加了監控、跟蹤等組件,以下分別展示:
(1)Trace

圖30 bookinfo應用分散式追蹤頁面

圖31 bookinfo應用分散式追蹤詳細頁面
(2)Prometheus

圖32 Istio請求總數
(3)Service Graph

圖33 bookinfo應用service圖表
(4)Grafana

圖34 Grafana監控web頁面
Istio還有許多功能特性例如熔斷機制,控制Ingress流量等,在此由於篇幅限制不多做描述,大家感興趣的話可以去官網查看https://istio.io/docs/tasks/
四、總結
通過以上對Istio的實踐大家不難看出Istio相比於Spring Cloud的幾個優點。首先相比於Spring Cloud學習組件內容多,門檻高的痛點,Istio是非常容易上手的,只需在k8s平台上跑一個yaml文件即可完成部署;再者相比於Spring Cloud需要把認證授權、分散式追蹤、監控等這些高級功能加入到應用程式內部導致了應用本身複雜度的痛點,反觀Istio是很輕量級的,它將以上那些高級功能作為組件內置在Istio中,從而達到了對應用程式的無侵入性,只需要配置相應的yaml文件並下發至Istio控制平面執行後續的操作即可,操作過程用戶是無感知的;最後相比於Spring Cloud對Java環境的過度依賴以及跨語言痛點,Istio也完美的解決了,其支援多種語言,包括新興程式語言Golang、Rust、Node.js、R語言等。
雖然目前Istio在社區有眾多的支援者,但從第一個版本到現在只有不到 一年半的時間,目前Istio中國生產落地的公司還相對較少,華為的CES Mesher、新浪微博的Motan、唯品會的OSP等都已經在使用,阿里雲和騰訊雲的持續跟進相信也不遠了, Istio的未來一片光明,讓我們共同期待。
參考文獻:
[1] https://martinfowler.com/articles/microservices.html
[2] https://istio.io/
[3] https://mp.weixin.qq.com/s?__biz=MzA3MDg4Nzc2NQ==&mid=2652136078&idx=1&sn=b261631ffe4df0638c448b0c71497021&chksm=84d532b4b3a2bba2c1ed22a62f4845eb9b6f70f92ad9506036200f84220d9af2e28639a22045&scene=21#wechat_redirect
內容編輯:雲安全實驗室 浦明 責任編輯:肖晴

