上一篇文章中,我們介紹了Istio針對(duì)單集群的三種主流部署安裝方式:使用Istioctl安裝、使用Helm自定義安裝、獨(dú)立Operator安裝。本文將向大家介紹kubernetes 中的應(yīng)用接入Istio。主要包括kubernetes 中應(yīng)用接入Istio使用實(shí)例、應(yīng)用技巧、基本知識(shí)點(diǎn)總結(jié)和需要注意事項(xiàng)。
用什么姿勢(shì)接入 istio?
雖然 istio 能解決那么多的問(wèn)題,但是引入 istio 并不是沒(méi)有代價(jià)的。最大的問(wèn)題是 istio 的復(fù)雜性,強(qiáng)大的功能也意味著 istio 的概念和組件非常多,要想理解和掌握 istio ,并成功在生產(chǎn)環(huán)境中部署需要非常詳細(xì)的規(guī)劃。一般情況下,集群管理團(tuán)隊(duì)需要對(duì) kubernetes 非常熟悉,了解常用的使用模式,然后采用逐步演進(jìn)的方式把 istio 的功能分批掌控下來(lái)。
我們?cè)O(shè)定以下目標(biāo):
istio部署
dfb相關(guān)服務(wù)部署
網(wǎng)關(guān)功能
流量分配,按比例,header
超時(shí),重試
Istio的幾個(gè)基本資源對(duì)象:
1. VirtualService配置影響流量路由的參數(shù),VirtualService 定義了對(duì)特定目標(biāo)服務(wù)的一組流量規(guī)則。如其名字所示, VirtualService在形式上表示一個(gè)虛擬服務(wù),將滿足條件的流量都轉(zhuǎn)發(fā)到對(duì)應(yīng)的服務(wù)后端,這個(gè)服務(wù)后端可以是一個(gè)服務(wù),也可以是在Dest in at i onRu l e 中定義的服務(wù)的子集。
2. DestinationRule配置目標(biāo)規(guī)則,DestinationRule定義了在路由發(fā)生后應(yīng)用于服務(wù)流量的策略。這些規(guī)則指定負(fù)載平衡的配置,邊車的連接池大小以及離群值檢測(cè)設(shè)置,以從負(fù)載平衡池中檢測(cè)和清除不正常的主機(jī)。
3. Gateway服務(wù)網(wǎng)關(guān),入口.Gateway描述了一個(gè)負(fù)載均衡器,該負(fù)載均衡器在網(wǎng)格的邊緣運(yùn)行,以接收傳入或傳出的HTTP / TCP連接。
4. Service Entry外部服務(wù)配置,通過(guò)ServiceEntry,可以在Istio的內(nèi)部服務(wù)注冊(cè)表中添加其他條目,以便網(wǎng)格中自動(dòng)發(fā)現(xiàn)的服務(wù)可以訪問(wèn)/路由到這些手動(dòng)指定的服務(wù)。
網(wǎng)關(guān)功能:Gateway
Gateway 在網(wǎng)格邊緣接收外部訪問(wèn),并將流量轉(zhuǎn)發(fā)到網(wǎng)格內(nèi)的服務(wù)。Istio 通過(guò)Gateway將網(wǎng)格內(nèi)的服務(wù)發(fā)布成外部可訪問(wèn)的服務(wù),還可以通過(guò)Gateway 配置外部訪問(wèn)的端口、協(xié)議及與內(nèi)部服務(wù)的映射關(guān)系。
網(wǎng)關(guān)功能常見(jiàn)的應(yīng)用:
1. 將網(wǎng)格內(nèi)的HTTP 服務(wù)發(fā)布為HTTP 外部訪問(wèn)
2. 將網(wǎng)格內(nèi)的HTTPS 服務(wù)發(fā)布為HTTPS 外部訪問(wèn)
3. 將網(wǎng)格內(nèi)的HTTP 服務(wù)發(fā)布為HTTPS 外部訪問(wèn)
4. 將網(wǎng)格內(nèi)的HTTP 服務(wù)發(fā)布為雙向HTTPS 外部訪問(wèn)
5. 將網(wǎng)格內(nèi)的HTTP 服務(wù)發(fā)布為HTTPS 外部訪問(wèn)和HTTPS 內(nèi)部訪問(wèn)
在實(shí)踐中。我們更多需要的是1,3兩個(gè)場(chǎng)景。
在dfb服務(wù)中,dfb-login 作為最外層的前端,是幾個(gè)服務(wù)中唯一和外部用戶產(chǎn)生交互的服務(wù)。因此我們通過(guò)網(wǎng)關(guān)功能,將dfb-login 通過(guò)域名暴露給用戶。
創(chuàng)建gateway 的yml文件:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: login-gateway
namespace: dfb-istio
spec:
selector:
istio: ingressgateway servers:
- hosts:
- istio-login.dfb.com
port:
name: https
number: 443
protocol: HTTPS
tls:
mode: SIMPLE
privateKey: /etc/istio/ingressgateway-certs/dfb.pem
serverCertificate: /etc/istio/ingressgateway-certs/dfb.pem
- hosts:
- istio-login.dfb.com
port:
name: http
number: 80
protocol: HTTP
創(chuàng)建virtualservice.yml:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: dfb-login
namespace: dfb-istio
spec:
gateways:
- login-gateway
hosts:
- '*'
http:
- uri:
prefix: /
- route:
- destination:
host: dfb-login.dfb-istio.svc.cluster.local
我們創(chuàng)建了兩個(gè)資源對(duì)象,一個(gè)VirtualService 用來(lái)描述流量的路由關(guān)系。所有url 前綴為/ 的請(qǐng)求都route 到后端dfb-login.dfb-istio.svc.cluster.local 服務(wù)。
這個(gè)virtuaservice 通過(guò)gateways 字段和我們申明的另一個(gè)gateway 資源相互綁定。在Gateway 資源對(duì)象中。定義了入口的域名,協(xié)議,以及TLS 相關(guān)的配置。在istio 中。默認(rèn)的ingressgateway 會(huì)監(jiān)聽(tīng)gateway 資源對(duì)象的變更。多個(gè)ingressgateway 通過(guò)selector 進(jìn)行選擇.默認(rèn)ingressgateway 是一個(gè)loadbalancer的service 。
我們將這個(gè)ingressgateway 修改為宿主機(jī)網(wǎng)絡(luò),并固定到一個(gè)單獨(dú)的節(jié)點(diǎn)。這樣我們就可以通過(guò)將域名解析到這個(gè)node節(jié)點(diǎn)的方式訪問(wèn)部署好的入口。
流量分配:按比例,根據(jù)請(qǐng)求內(nèi)容
我們?cè)O(shè)置了兩個(gè)版本的login 服務(wù)。V1 版本用戶登錄后顯示的余額是從數(shù)據(jù)庫(kù)取出來(lái)的。V2版本則是0。根據(jù)這兩個(gè)版本的差異來(lái)判斷流量的流向。
首先通過(guò)DestinationRule定義兩個(gè)版本:
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata: name: dfb-login
namespace: dfb-istio
spec:
host: dfb-login
subsets:
- labels:
version: v1
name: v1
- labels:
version: v2
name: v2
根據(jù)比例:
修改在網(wǎng)關(guān)功能中創(chuàng)建的virtualservice
kind: VirtualService
apiVersion: networking.istio.io/v1alpha3
metadata:
name: dfb-login
namespace: dfb-istio
spec:
hosts:
- '*'
gateways:
- login-gateway
http:
- match:
- uri:
prefix: /
route:
- destination:
host: dfb-login.dfb-istio.svc.cluster.local
subset: v1
weight: 50
- destination:
host: dfb-login.dfb-istio.svc.cluster.local
subset: v2
weight: 50
此時(shí)多次刷新頁(yè)面??梢钥吹接脩舻默F(xiàn)金賬戶余額在0 和真實(shí)額度之間變動(dòng)。
根據(jù)請(qǐng)求內(nèi)容決定路由:
kind: VirtualService
apiVersion: networking.istio.io/v1alpha3
metadata:
name: dfb-login
namespace: dfb-istio
spec:
hosts:
- '*'
gateways:
- login-gateway
http:
- match:
- headers:
version:
exact: v2
route:
- destination:
host: dfb-login.dfb-istio.svc.cluster.local
subset: v2
- route:
- destination:
host: dfb-login.dfb-istio.svc.cluster.local
subset: v1
修改上文yml 。通過(guò)postman請(qǐng)求dfb服務(wù)/home頁(yè)面。默認(rèn)情況下會(huì)路由指向V1版本的login服務(wù)。在請(qǐng)求頭添加version=v2的header。則會(huì)轉(zhuǎn)到v2的服務(wù)。
超時(shí),重試功能
我們首先在擴(kuò)容dfb-api 這個(gè)服務(wù)為2個(gè)pod,在其中一個(gè)pod中攔截用戶資產(chǎn)接口, 直接返回500 ,另一個(gè)pod 正常返回。此時(shí)在dfb-login服務(wù)中請(qǐng)求。我們可以發(fā)現(xiàn),接口500 和200 狀態(tài)碼交替出現(xiàn)。
location =/user/account/list/338fbcd2-1be6-4dde-9918-84b7629b1ba5 {
return500;
}
此時(shí)應(yīng)用下面的重試規(guī)則,再次調(diào)用接口。此時(shí)接口狀態(tài)碼一直返回200。
kind: VirtualService
apiVersion: networking.istio.io/v1alpha3
metadata:
name: dfb-api
namespace: dfb-istio
spec:
hosts:
- dfb-api.dfb-istio.svc.cluster.local
gateways: ~
http:
- route:
- destination:
host: dfb-api.dfb-istio.svc.cluster.local
port:
number: 80
weight: 100
retries:
attempts: 3
perTryTimeout: 2s
retryOn: 5xx,gateway-error,connect-failure,refused-stream
通過(guò)jaeger查看調(diào)用鏈,可以看到調(diào)用了兩次dfb-api。雖然中間調(diào)用失敗了,但是最終的狀態(tài)碼是200。