Istio服務(wù)網(wǎng)格技術(shù)解析與實(shí)踐(中級(jí)篇)_第1頁(yè)
Istio服務(wù)網(wǎng)格技術(shù)解析與實(shí)踐(中級(jí)篇)_第2頁(yè)
Istio服務(wù)網(wǎng)格技術(shù)解析與實(shí)踐(中級(jí)篇)_第3頁(yè)
Istio服務(wù)網(wǎng)格技術(shù)解析與實(shí)踐(中級(jí)篇)_第4頁(yè)
Istio服務(wù)網(wǎng)格技術(shù)解析與實(shí)踐(中級(jí)篇)_第5頁(yè)
已閱讀5頁(yè),還剩247頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

Istio服務(wù)網(wǎng)格技術(shù)解析與實(shí)踐(中級(jí)篇)目錄TOC\h\h中級(jí)篇\h第4章東西向流量管理\h4.1流量管理\h4.2實(shí)現(xiàn)東西向流量路由\h4.3實(shí)現(xiàn)流量鏡像及對(duì)比分析\h4.4通過(guò)Istio管理應(yīng)用的灰度發(fā)布\h4.5本章總結(jié)\h第5章南北向流量管理\h5.1Istio網(wǎng)關(guān)\h5.2用HTTPS加密網(wǎng)關(guān)\h5.3基于SNI的TLS路由\h5.4服務(wù)條目\h5.5實(shí)現(xiàn)出口流量路由的統(tǒng)一管理\h5.6實(shí)現(xiàn)服務(wù)條目的DNS尋址\h5.7本章總結(jié)\h第6章流量治理\h6.1使用流量策略\h6.2設(shè)置負(fù)載均衡\h6.3熔斷\h6.4服務(wù)重試\h6.5故障注入\h6.6命名空間隔離下的流量管理\h6.7本章總結(jié)\h第7章安全\h7.1Istio安全架構(gòu)\h7.2剖析認(rèn)證機(jī)制\h7.3使用認(rèn)證策略\h7.4使用自定義CA證書(shū)和密鑰\h7.5使用cert-manager管理網(wǎng)關(guān)證書(shū)\h7.6剖析授權(quán)機(jī)制\h7.7本章總結(jié)\h第8章Mixer的控制與觀測(cè)\h8.1Mixer架構(gòu)設(shè)計(jì)\h8.2剖析適配器機(jī)制\h8.3指標(biāo)數(shù)據(jù)收集\h8.4集成日志數(shù)據(jù)收集\h8.5啟用基于Zipkin或Jaeger的分布式跟蹤\h8.6啟用速率限制策略\h8.7啟用黑白名單策略\h8.8本章總結(jié)中級(jí)篇第4章東西向流量管理第5章南北向流量管理第6章流量治理第7章安全第8章Mixer的控制與觀測(cè)第4章東西向流量管理作為開(kāi)源的獨(dú)立服務(wù)網(wǎng)格,Istio可在部署規(guī)模逐步擴(kuò)大的過(guò)程中幫助開(kāi)發(fā)人員簡(jiǎn)化流量管理。我們知道,使用Ingress將Kubernetes中的應(yīng)用暴露成對(duì)外提供的服務(wù),針對(duì)這個(gè)對(duì)外暴露的服務(wù)可以實(shí)現(xiàn)灰度發(fā)布、流量管理等。我們把這種流量管理稱(chēng)為南北向流量管理,也就是入口請(qǐng)求到集群服務(wù)的流量管理。除了南北向流量管理之外,Istio還有側(cè)重于集群內(nèi)服務(wù)網(wǎng)格之間的流量管理,我們把這類(lèi)管理稱(chēng)為東西向流量管理。本章重點(diǎn)介紹Istio在東西向流量方面的路由控制能力,下一章介紹南北向流量控制。本章首先介紹Istio流量管理的基本內(nèi)容以及如何使用東西向流量管理,接著針對(duì)流量路由規(guī)則、流量鏡像通過(guò)示例展開(kāi)詳細(xì)介紹,最后介紹如何通過(guò)Istio管理應(yīng)用的灰度發(fā)布場(chǎng)景,并詳述了流量路由規(guī)則的定義。4.1流量管理Istio的流量管理本質(zhì)上是將流量與基礎(chǔ)設(shè)施解耦,讓運(yùn)維人員可以通過(guò)Pilot指定流量遵循什么規(guī)則,而不是指定哪些pod虛擬機(jī)應(yīng)該接收流量,這樣通過(guò)Pilot和智能Envoy代理就可以進(jìn)行流量控制。例如,你可以通過(guò)Pilot指定特定服務(wù)的5%流量轉(zhuǎn)到金絲雀版本,而不必考慮金絲雀部署的大小,或根據(jù)請(qǐng)求的內(nèi)容將流量發(fā)送到特定版本。很明顯,將流量管理與基礎(chǔ)設(shè)施擴(kuò)縮分離開(kāi)來(lái),使得系統(tǒng)可提供獨(dú)立于應(yīng)用代碼的多種功能,例如A/B測(cè)試、金絲雀發(fā)布等機(jī)制所依賴(lài)的動(dòng)態(tài)請(qǐng)求路由。此外,Istio還使用超時(shí)、重試和熔斷器來(lái)處理故障恢復(fù),并使用故障注入來(lái)跨服務(wù)測(cè)試故障恢復(fù)政策的兼容性。這些功能都是通過(guò)在服務(wù)網(wǎng)格中部署的Sidecar代理Envoy來(lái)實(shí)現(xiàn)的。Istio流量管理的核心組件是Pilot,Pilot管理和配置部署在特定Istio服務(wù)網(wǎng)格中的所有Envoy代理實(shí)例,如圖4-1Istio架構(gòu)中的描述。Pilot允許你指定在Envoy代理之間使用什么樣的路由流量規(guī)則,并配置故障恢復(fù)功能,如超時(shí)、重試和熔斷器。Pilot還維護(hù)了網(wǎng)格中所有服務(wù)的規(guī)范模型,并使用這個(gè)模型通過(guò)發(fā)現(xiàn)服務(wù)讓Envoy了解網(wǎng)格中的其他實(shí)例。每個(gè)Envoy實(shí)例都會(huì)維護(hù)負(fù)載均衡信息,這些信息來(lái)自Pilot以及對(duì)負(fù)載均衡池中其他實(shí)例的定期健康檢查。從而允許其在目標(biāo)實(shí)例之間智能分配流量,同時(shí)遵循其指定的路由規(guī)則。Pilot負(fù)責(zé)管理通過(guò)Istio服務(wù)網(wǎng)格發(fā)布的Envoy實(shí)例的生命周期。圖4-1Istio架構(gòu)4.1.1術(shù)語(yǔ)為了更好地理解Istio的流量管理,我們需要先搞清楚其中涉及的幾個(gè)基本術(shù)語(yǔ):·Sidecar(邊車(chē)):Sidecar自定義資源描述了Sidecar代理的配置,該代理協(xié)調(diào)與其連接的工作負(fù)載實(shí)例的入站和出站通信。默認(rèn)情況下,Istio將為網(wǎng)格中的所有Sidecar代理進(jìn)行配置,使其具有到達(dá)網(wǎng)格中每個(gè)工作負(fù)載實(shí)例所需的必要配置,并接受與工作負(fù)載關(guān)聯(lián)的所有端口上的流量。Sidecar資源提供了一種細(xì)粒度調(diào)整端口、協(xié)議的方法,使得代理能接受向工作負(fù)載轉(zhuǎn)發(fā)流量或從工作負(fù)載轉(zhuǎn)發(fā)流量。此外,可以限制代理在從工作負(fù)載實(shí)例轉(zhuǎn)發(fā)出站流量時(shí)可以達(dá)到的服務(wù)集。·服務(wù)(Service):綁定到服務(wù)注冊(cè)表中唯一名稱(chēng)的應(yīng)用程序行為單位。服務(wù)由運(yùn)行在pod、容器、虛擬機(jī)上的工作負(fù)載實(shí)例實(shí)現(xiàn)的多個(gè)網(wǎng)絡(luò)端點(diǎn)組成?!し?wù)版本(Serviceversions):也稱(chēng)為子集(subsets),在持續(xù)部署場(chǎng)景中,對(duì)于給定服務(wù),可能會(huì)存在運(yùn)行著應(yīng)用程序二進(jìn)制文件的不同變種的不同實(shí)例子集。這些變種不一定是不同的API版本,也可以是對(duì)同一服務(wù)的迭代更改,部署在不同的環(huán)境中,如生產(chǎn)環(huán)境、預(yù)發(fā)環(huán)境或者開(kāi)發(fā)測(cè)試環(huán)境等?!ぴ矗⊿ource):調(diào)用目標(biāo)服務(wù)的下游客戶端?!ぶ鳈C(jī)(Host):客戶端在嘗試連接服務(wù)時(shí)使用的地址?!ぴL問(wèn)模型(Accessmodel):應(yīng)用程序在不知道各個(gè)服務(wù)版本(子集)的情況下僅對(duì)目標(biāo)服務(wù)(主機(jī))進(jìn)行尋址。版本的實(shí)際選擇由Sidecar代理確定,使應(yīng)用程序代碼能夠脫離依賴(lài)服務(wù)的演變?!ぬ摂M服務(wù)(VirtualService):一個(gè)虛擬服務(wù)定義了一系列針對(duì)指定服務(wù)的流量路由規(guī)則。每個(gè)路由規(guī)則都針對(duì)特定協(xié)議定義流量匹配規(guī)則。如果流量符合這些特征,就會(huì)根據(jù)規(guī)則發(fā)送到服務(wù)注冊(cè)表中的目標(biāo)服務(wù)(或者目標(biāo)服務(wù)的子集或版本)?!つ繕?biāo)規(guī)則(DestinationRule):目標(biāo)規(guī)則定義了在路由發(fā)生后應(yīng)用于服務(wù)的流量的策略。這些規(guī)則指定負(fù)載均衡的配置,來(lái)自Sidecar代理的連接池大小以及異常檢測(cè)設(shè)置,以便從負(fù)載均衡池中檢測(cè)和驅(qū)逐不健康的主機(jī)。4.1.2流量拆分與導(dǎo)向Istio提供了兩種流量路由管理方式:基于比例的流量拆分、基于請(qǐng)求內(nèi)容的流量導(dǎo)向。1.基于比例的流量拆分Istio根據(jù)輸入的流量比例來(lái)確定流量分發(fā)的比重,范圍限制為[0,100]。如圖4-2所示,當(dāng)服務(wù)B提供了新版本時(shí),可以通過(guò)指定一定的比例將從服務(wù)A到服務(wù)B調(diào)用的流量切換到新版本。例如,指定10%的流量權(quán)重到新版本之后,服務(wù)流量就會(huì)按照權(quán)重比例以對(duì)應(yīng)的概率分發(fā)當(dāng)前版本,即10%的流量走新版本,90%的流量走當(dāng)前版本。圖4-2基于比例的流量拆分2.基于請(qǐng)求內(nèi)容的流量導(dǎo)向除了指定比例進(jìn)行流量拆分之外,Istio也提供了基于請(qǐng)求內(nèi)容的流量拆分,包括以下幾種方式:·基于瀏覽器的分發(fā):選擇允許訪問(wèn)的瀏覽器。·基于操作系統(tǒng)的分發(fā):選擇允許訪問(wèn)的操作系統(tǒng)?!せ贑ookie的分發(fā):使用正則表達(dá)式來(lái)匹配Cookie內(nèi)容?!せ贖TTP請(qǐng)求頭(header)的分發(fā):使用正則表達(dá)式來(lái)匹配自定義的請(qǐng)求頭?!D4-3是基于HTTP請(qǐng)求頭的分發(fā)示例,其中android應(yīng)用走服務(wù)B的新版本。4.1.3Istio服務(wù)與Kubernetes服務(wù)Istio引入了服務(wù)版本的概念,可以通過(guò)版本(v1、v2)或環(huán)境對(duì)服務(wù)進(jìn)行進(jìn)一步的細(xì)分。這些版本不一定是不同的API版本,可能是部署在不同環(huán)境(如生產(chǎn)環(huán)境,預(yù)發(fā)環(huán)境、測(cè)試環(huán)境等)中的同一服務(wù)的不同迭代版本。使用這種方式的常見(jiàn)場(chǎng)景包括A/B測(cè)試或金絲雀部署。Istio的流量路由規(guī)則可以根據(jù)服務(wù)版本對(duì)服務(wù)流量進(jìn)行附加控制。圖4-3基于請(qǐng)求內(nèi)容的分發(fā)如圖4-4所示,服務(wù)的客戶端不知道服務(wù)不同版本間的差異,但可以使用服務(wù)的主機(jī)名或者IP地址繼續(xù)訪問(wèn)服務(wù)。Envoy代理攔截并轉(zhuǎn)發(fā)客戶端和服務(wù)器之間的所有請(qǐng)求和響應(yīng)。圖4-4啟用Istio后的Kubernetes服務(wù)調(diào)用運(yùn)維人員使用Pilot指定路由規(guī)則,Envoy根據(jù)這些規(guī)則動(dòng)態(tài)地確定其服務(wù)版本的實(shí)際選擇。該模型使應(yīng)用程序代碼與服務(wù)解耦,不受服務(wù)演進(jìn)的影響。路由規(guī)則讓Envoy能夠根據(jù)諸如header、與源/目的地相關(guān)聯(lián)的標(biāo)簽和/或分配給每個(gè)版本的權(quán)重等標(biāo)準(zhǔn)來(lái)進(jìn)行版本選擇。Istio還為同一服務(wù)版本的多個(gè)實(shí)例提供流量負(fù)載均衡。Istio不提供DNS,應(yīng)用程序可以嘗試使用底層平臺(tái)(kube-dns、mesos-dns等)中存在的DNS服務(wù)來(lái)解析全限定域名FQDN。Kubernetesservice如何關(guān)聯(lián)一個(gè)Istio虛擬服務(wù)?參見(jiàn)圖4-5,步驟如下:圖4-5Kubernetesservice如何關(guān)聯(lián)Istio虛擬服務(wù)1)EnvoyProxy首先根據(jù)請(qǐng)求匹配一個(gè)Istio虛擬服務(wù),每一個(gè)Proxy都會(huì)對(duì)應(yīng)一個(gè)主機(jī)與虛擬服務(wù)信息列表,根據(jù)請(qǐng)求地址,選擇其中對(duì)應(yīng)的主機(jī)(Kubernetes服務(wù)),并根據(jù)選擇的主機(jī)信息,找到對(duì)應(yīng)的Istio虛擬服務(wù)。2)Istio虛擬服務(wù)描述路由到目標(biāo)主機(jī)的規(guī)則,并根據(jù)選擇的主機(jī)信息,找到對(duì)應(yīng)的Istio虛擬服務(wù);根據(jù)規(guī)則,Proxy找到滿足條件的第一個(gè)目標(biāo)主機(jī)(對(duì)應(yīng)到一個(gè)Kubernetesservice)。3)Proxy調(diào)用目標(biāo)pod,Proxy根據(jù)滿足條件的目標(biāo)主機(jī)信息尋找對(duì)應(yīng)的目標(biāo)pod,并根據(jù)定義的流量策略(包括負(fù)載均衡等)路由到相應(yīng)的pod。4.1.4示例下面通過(guò)一個(gè)簡(jiǎn)單的示例來(lái)了解Istio中的路由控制能力。部署版本v1的服務(wù)service1、service2、service3、service4與service5及其Deployment資源,其中service1會(huì)調(diào)用service2,service2調(diào)用service3,以此類(lèi)推。注意執(zhí)行以下kubectl命令之前,請(qǐng)先創(chuàng)建命名空間servicedependency,并為命名空間servicedependency打上標(biāo)簽istio-injection=enabled。例如可以通過(guò)命令kubectlcreatensservicedependency來(lái)創(chuàng)建命令空間,通過(guò)命令kubectllabelnsservicedependencyistio-injection=enabled設(shè)置標(biāo)簽。下載本書(shū)所使用的示例代碼之后,切換到目錄traffic-sample1可以查看所有相關(guān)的代碼文件。下面是app.yaml中定義的service1的yaml示例:apiVersion:v1

kind:Service

metadata:

name:service1

labels:

app:service1

spec:

ports:

-port:5678

name:http

selector:

app:service1

apiVersion:extensions/v1beta1

kind:Deployment

metadata:

name:service1-v1

spec:

replicas:1

template:

metadata:

labels:

app:service1

version:v1

spec:

containers:

-name:service1

image:/istio-samples/mirrorservice:rev-dep-call

imagePullPolicy:Always

env:

-name:myself

value:"service1"

-name:serviceName

value:"service2.servicedependency"

ports:

-containerPort:5678

部署版本v2的服務(wù)service1~5對(duì)應(yīng)的Deployment資源,從下面的service1的yaml示例(可參見(jiàn)app-v2.yaml)可以看出,通過(guò)標(biāo)簽version:v2來(lái)指定的當(dāng)前服務(wù)的版本:apiVersion:extensions/v1beta1

kind:Deployment

metadata:

name:service1-v2

spec:

replicas:1

template:

metadata:

labels:

app:service1

version:v2

spec:

containers:

-name:service1

image:/istio-samples/mirrorservice:rev-dep-call

imagePullPolicy:Always

env:

-name:myself

value:"service1"

-name:serviceName

value:"service2.servicedependency"

ports:

-containerPort:5678

DestinationRule定義的策略決定了經(jīng)過(guò)路由處理之后的流量的訪問(wèn)策略。具體定義可以參見(jiàn)文件destinationrule.yaml,內(nèi)容摘錄如下:apiVersion:networking.istio.io/v1alpha3

kind:DestinationRule

metadata:

name:service1

spec:

host:service1

subsets:

-name:v1

labels:

version:v1

-name:v2

labels:

version:v2

apiVersion:networking.istio.io/v1alpha3

kind:DestinationRule

metadata:

name:service2

spec:

host:service2

subsets:

-name:v1

labels:

version:v1

-name:v2

labels:

version:v2

apiVersion:networking.istio.io/v1alpha3

kind:DestinationRule

metadata:

name:service3

spec:

host:service3

subsets:

-name:v1

labels:

version:v1

-name:v2

labels:

version:v2

apiVersion:networking.istio.io/v1alpha3

kind:DestinationRule

metadata:

name:service4

spec:

host:service4

subsets:

-name:v1

labels:

version:v1

-name:v2

labels:

version:v2

apiVersion:networking.istio.io/v1alpha3

kind:DestinationRule

metadata:

name:service5

spec:

host:service5

subsets:

-name:v1

labels:

version:v1

-name:v2

labels:

version:v2

VirtualService定義了一系列針對(duì)指定服務(wù)的流量路由規(guī)則。每個(gè)路由規(guī)則都針對(duì)特定協(xié)議的匹配規(guī)則。如果流量符合這些特征,就會(huì)根據(jù)規(guī)則發(fā)送到服務(wù)注冊(cè)表中的目標(biāo)服務(wù)(或者目標(biāo)服務(wù)的子集或版本)。具體定義可參見(jiàn)文件virtualservice-v1.yaml,內(nèi)容摘錄如下:apiVersion:networking.istio.io/v1alpha3

kind:VirtualService

metadata:

name:service1

spec:

hosts:

-service1

http:

-route:

-destination:

host:service1

subset:v1

weight:100

-destination:

host:service1

subset:v2

weight:0

apiVersion:networking.istio.io/v1alpha3

kind:VirtualService

metadata:

name:service2

spec:

hosts:

-service2

http:

-route:

-destination:

host:service2

subset:v1

weight:100

-destination:

host:service2

subset:v2

weight:0

apiVersion:networking.istio.io/v1alpha3

kind:VirtualService

metadata:

name:service3

spec:

hosts:

-service3

http:

-route:

-destination:

host:service3

subset:v1

weight:100

-destination:

host:service3

subset:v2

weight:0

apiVersion:networking.istio.io/v1alpha3

kind:VirtualService

metadata:

name:service4

spec:

hosts:

-service4

http:

-route:

-destination:

host:service4

subset:v1

weight:100

-destination:

host:service4

subset:v2

weight:0

apiVersion:networking.istio.io/v1alpha3

kind:VirtualService

metadata:

name:service5

spec:

hosts:

-service5

http:

-route:

-destination:

host:service5

subset:v1

weight:100

-destination:

host:service5

subset:v2

weight:0

創(chuàng)建命名空間servicedependency之后,執(zhí)行以下命令:kubectlapply-nservicedependency-fapp.yaml

kubectlapply-nservicedependency-fapp-v2.yaml

kubectlapply-nservicedependency-fvirtualservice-v1.yaml

啟動(dòng)測(cè)試程序:kubectlapply-nservicedependency-fsleep.yaml

kubectlexec-it$(kubectlgetpod-lapp=sleep-nservicedependency-ojsonpath=

{.})-csleep-nservicedependencysh

添加如下腳本到test.sh文件:foriin`seq1000`

do

curl-Ihttp://service1.servicedependency:5678;

sleep1;

done;

設(shè)置為執(zhí)行模式,并執(zhí)行測(cè)試:chmod+xtest.sh

./test.sh

打開(kāi)Kiali控制臺(tái)UI可以看到如圖4-6所示的效果。圖4-6Kiali控制臺(tái)UI通過(guò)修改權(quán)重比例,使得流量切換到版本v2:apiVersion:networking.istio.io/v1alpha3

kind:VirtualService

metadata:

name:service1

spec:

hosts:

-service1

http:

-route:

-destination:

host:service1

subset:v1

weight:0

-destination:

host:service1

subset:v2

weight:100

apiVersion:networking.istio.io/v1alpha3

kind:VirtualService

metadata:

name:service2

spec:

hosts:

-service2

http:

-route:

-destination:

host:service2

subset:v1

weight:0

-destination:

host:service2

subset:v2

weight:100

apiVersion:networking.istio.io/v1alpha3

kind:VirtualService

metadata:

name:service3

spec:

hosts:

-service3

http:

-route:

-destination:

host:service3

subset:v1

weight:0

-destination:

host:service3

subset:v2

weight:100

apiVersion:networking.istio.io/v1alpha3

kind:VirtualService

metadata:

name:service4

spec:

hosts:

-service4

http:

-route:

-destination:

host:service4

subset:v1

weight:0

-destination:

host:service4

subset:v2

weight:100

apiVersion:networking.istio.io/v1alpha3

kind:VirtualService

metadata:

name:service5

spec:

hosts:

-service5

http:

-route:

-destination:

host:service5

subset:v1

weight:0

-destination:

host:service5

subset:v2

weight:100

執(zhí)行上述版本v2的VirtualService,啟用版本v2的服務(wù):kubectlapply-nservicedependency-fvirtualservice-v2.yaml

此時(shí),從Kiali控制臺(tái)UI上可以看到服務(wù)的調(diào)用從v1切換到了v2,如圖4-7所示。圖4-7服務(wù)的調(diào)用的結(jié)果4.2實(shí)現(xiàn)東西向流量路由本節(jié)用實(shí)例講解如何實(shí)現(xiàn)東西向流量路由。應(yīng)用由四個(gè)單獨(dú)的微服務(wù)構(gòu)成,模仿某銀行金融產(chǎn)品的一個(gè)分類(lèi),顯示某一金融產(chǎn)品的信息,如圖4-8所示。頁(yè)面上會(huì)顯示該產(chǎn)品的描述、明細(xì),以及針對(duì)特定用戶的增值服務(wù)。四個(gè)單獨(dú)的微服務(wù)如下:·productpage:該微服務(wù)會(huì)調(diào)用details和addedvalues兩個(gè)微服務(wù),用來(lái)生成頁(yè)面。·details:該微服務(wù)包含了金融產(chǎn)品的信息?!ddedvalues:該微服務(wù)包含了針對(duì)特定用戶的增值服務(wù),還會(huì)調(diào)用styletransfer微服務(wù)?!tyletransfer:該微服務(wù)提供了轉(zhuǎn)換照片藝術(shù)風(fēng)格的API功能。圖4-8實(shí)現(xiàn)東西向流量路由的案例addedvalues微服務(wù)有3個(gè)版本:·v1版本不會(huì)調(diào)用styletransfer服務(wù),也不會(huì)提供風(fēng)險(xiǎn)和投資分析結(jié)果?!2版本不會(huì)調(diào)用styletransfer服務(wù),但會(huì)提供風(fēng)險(xiǎn)和投資分析結(jié)果?!3版本會(huì)調(diào)用styletransfer服務(wù),提供針對(duì)特定用戶的增值服務(wù),即允許用戶上傳圖片進(jìn)行風(fēng)格轉(zhuǎn)換,并返回一張轉(zhuǎn)換后的圖片。4.2.1自動(dòng)Sidecar注入使用kubectl命令查看當(dāng)前命名空間的情況,如下所示:通過(guò)使用kubectl為default命名空間打上標(biāo)簽istio-injection=enabled,執(zhí)行結(jié)果如下所示:4.2.2部署下載本書(shū)所使用的示例代碼之后,切換到目錄traffic-sample2,使用kubectl部署簡(jiǎn)單的服務(wù):kubectlapply-fapp.yaml

上面的命令會(huì)啟動(dòng)全部的3個(gè)服務(wù),其中也包括了addedvalues服務(wù)的三個(gè)版本(v1、v2及v3)。定義Ingressgateway:kubectlapply-fgateway.yaml

確認(rèn)所有的服務(wù)和pod都已經(jīng)正確定義和啟動(dòng):kubectlgetsvc

kubectlgetpo

確認(rèn)網(wǎng)關(guān)創(chuàng)建完成:kubectlgetgateway

應(yīng)用默認(rèn)的目標(biāo)規(guī)則:kubectlapply-fdestination-rule-all.yaml

等待幾秒鐘,等待目標(biāo)規(guī)則生效。這就意味著上述3個(gè)微服務(wù)已經(jīng)部署在Istio環(huán)境中??梢允褂靡韵旅畈榭茨繕?biāo)規(guī)則:kubectlgetdestinationrules

4.2.3查看IngressGateway的地址通過(guò)查看Kubernetes服務(wù)列表或者通過(guò)命令行Kubectlgetservice-istio-system,在列表中找到istio-ingressgateway的外部端點(diǎn)地址。打開(kāi)瀏覽器,訪問(wèn)\hhttp://{GATEWAY-IP}/productpage。多次刷新頁(yè)面,會(huì)得到如下3種不同的顯示內(nèi)容,也就是上述提到的3個(gè)版本的addedvalues微服務(wù)。微服務(wù)addedvalues版本v1對(duì)應(yīng)的頁(yè)面如圖4-9所示。圖4-9版本v1對(duì)應(yīng)的頁(yè)面微服務(wù)addedvalues版本v2對(duì)應(yīng)的頁(yè)面如圖4-10所示。圖4-10版本v2對(duì)應(yīng)的頁(yè)面微服務(wù)addedvalues版本v3對(duì)應(yīng)的頁(yè)面如圖4-11所示。4.2.4請(qǐng)求路由請(qǐng)求路由任務(wù)首先會(huì)把應(yīng)用的進(jìn)入流量導(dǎo)向addedvalues服務(wù)的v2版本。接下來(lái)會(huì)把特定用戶(登錄名稱(chēng)以yunqi開(kāi)頭的請(qǐng)求)的請(qǐng)求發(fā)送給v3版本,其他用戶則不受影響:圖4-11版本v3對(duì)應(yīng)的頁(yè)面kubectlapply-fvirtual-service-user-v2-v3.yaml

打開(kāi)瀏覽器,訪問(wèn)\hhttp://{GATEWAY-IP}/productpage。不論刷新多少次頁(yè)面,如果沒(méi)有登錄或者登錄名不是以yunqi開(kāi)頭的,始終得到如下的顯示內(nèi)容,也就是上述提到的第2個(gè)版本的addedvalues微服務(wù),如圖4-12和圖4-13所示。圖4-12未登錄時(shí)的結(jié)果圖4-13以非yunqi開(kāi)頭的用戶名登錄時(shí)的結(jié)果當(dāng)使用以yunqi開(kāi)頭的用戶名登錄時(shí),就會(huì)看到如圖4-14所示頁(yè)面的內(nèi)容,也就是上述提到的第3個(gè)版本的addedvalues微服務(wù)。圖4-14以yunqi開(kāi)頭的用戶名登錄時(shí)的結(jié)果需要注意的是,第3個(gè)版本的addedvalues微服務(wù)提供的頁(yè)面中,按鈕是disabled狀態(tài),無(wú)法點(diǎn)擊。這是因?yàn)槟J(rèn)情況下,Istio服務(wù)網(wǎng)格內(nèi)的pod,由于其iptables將所有外發(fā)流量都透明轉(zhuǎn)發(fā)給了Sidecar,所以這些集群內(nèi)的服務(wù)無(wú)法訪問(wèn)集群之外的URL,而只能處理集群內(nèi)部的目標(biāo)。4.3實(shí)現(xiàn)流量鏡像及對(duì)比分析流量鏡像提供了一種盡可能降低生產(chǎn)環(huán)境變化風(fēng)險(xiǎn)的方式。鏡像會(huì)將實(shí)時(shí)流量的副本發(fā)送到鏡像服務(wù),鏡像流量發(fā)生在主服務(wù)的關(guān)鍵請(qǐng)求路徑之外。一旦我們能夠可靠地鏡像流量,就可以開(kāi)始做一些有價(jià)值的事情,例如通過(guò)請(qǐng)求流量對(duì)比工具Diffy,可以將引入測(cè)試集群的流量與生產(chǎn)集群中的預(yù)期行為進(jìn)行比較。4.3.1流量鏡像流量鏡像也稱(chēng)為影子流量,指將實(shí)時(shí)流量的副本發(fā)送到鏡像服務(wù)。流量鏡像發(fā)生在主服務(wù)的關(guān)鍵請(qǐng)求路徑之外。在非生產(chǎn)或者測(cè)試環(huán)境中,嘗試訪問(wèn)一個(gè)服務(wù)所有可能的測(cè)試用例組合是個(gè)非常不現(xiàn)實(shí)的任務(wù)。在某些情況下,編寫(xiě)這些用例的所有工作也可能與實(shí)際生產(chǎn)所需的用例不匹配。在理想情況下,可以使用實(shí)時(shí)的生產(chǎn)用例和流量來(lái)幫助完善在測(cè)試環(huán)境中錯(cuò)過(guò)的功能區(qū)域。一旦我們能夠可靠地進(jìn)行流量鏡像,就可以開(kāi)始做一些有價(jià)值的事情,例如通過(guò)請(qǐng)求流量對(duì)比工具Diffy,可以將引入測(cè)試集群的流量與生產(chǎn)集群中的預(yù)期行為進(jìn)行比較。例如,我們可能想比較請(qǐng)求結(jié)果與預(yù)期結(jié)果間的偏差,或者API協(xié)議中的數(shù)據(jù)損壞情況,以便更好地兼容。除此之外,需要注意以下問(wèn)題:·當(dāng)流量鏡像到不同的服務(wù)時(shí),會(huì)發(fā)生在請(qǐng)求的關(guān)鍵路徑之外。·忽略對(duì)任何鏡像流量的響應(yīng),鏡像流量被視為“即發(fā)即忘”。4.3.2流量對(duì)比插入一個(gè)代理就可以負(fù)責(zé)對(duì)流量的協(xié)調(diào),并對(duì)其進(jìn)行有趣的比較。Diffy就是一款這樣的代理工具。Diffy啟動(dòng)一個(gè)代理服務(wù)(例如監(jiān)聽(tīng)端口8880),再根據(jù)用戶設(shè)置的primary、secondary兩個(gè)舊服務(wù)地址(primary和secondary代碼完全相同,目的是為了減少噪音干擾)、candidate新服務(wù)地址。Diffy還能夠檢測(cè)結(jié)果中的噪音,并通過(guò)先調(diào)用兩個(gè)實(shí)時(shí)服務(wù)的實(shí)例來(lái)忽略它們(例如時(shí)間戳、單調(diào)遞增計(jì)數(shù)器等提示),總結(jié)來(lái)說(shuō)就是檢測(cè),然后在測(cè)試服務(wù)中忽略掉這部分。Diffy還提供了一個(gè)不錯(cuò)的頁(yè)面可以用來(lái)查看調(diào)用結(jié)果、對(duì)比情況和基于某些特征的過(guò)濾。它還有一個(gè)很好的管理控制臺(tái),可以查看有關(guān)調(diào)用比較結(jié)果的功能指標(biāo)(metrics)和統(tǒng)計(jì)數(shù)據(jù)(statistics),如圖4-15所示。圖4-15服務(wù)的調(diào)用的結(jié)果4.3.3創(chuàng)建用于Istio流量鏡像的服務(wù)在此任務(wù)中,將首先強(qiáng)制所有流量到v1版本的服務(wù)。然后,將使用規(guī)則將一部分流量鏡像到v2版本。首先部署兩個(gè)版本的示例服務(wù)。注意執(zhí)行以下kubectl命令之前,請(qǐng)先創(chuàng)建命名空間diffy,并為命名空間diffy打上標(biāo)簽istio-injection=enabled。例如,可以通過(guò)命令kubectlcreatensdiffy來(lái)創(chuàng)建命令空間,通過(guò)命令kubectllabelnsdiffyistio-injection=enabled設(shè)置標(biāo)簽。下載本書(shū)所使用的示例代碼之后,切換到目錄traffic-sample3可以查看所有相關(guān)的代碼文件。版本1的部署使用了Docker鏡像httpbin,提供常見(jiàn)的http請(qǐng)求訪問(wèn),具體參見(jiàn)sample-service.yaml中的定義:apiVersion:extensions/v1beta1

kind:Deployment

metadata:

name:mirrorservice-sample-v1

spec:

replicas:1

template:

metadata:

labels:

app:mirrorservice-sample

version:v1

spec:

containers:

-image:docker.io/kennethreitz/httpbin

imagePullPolicy:IfNotPresent

name:mirrorservice-sample

command:["gunicorn","--access-logfile","-","-b",":44134","httpbin:app"]

ports:

-containerPort:44134

版本2的部署使用了自定義的Docker鏡像,對(duì)應(yīng)的Dockerfile如下:FROMnginx:latest

COPYdefault.conf/etc/nginx/conf.d/

EXPOSE80

所需的nginx配置文件:server{

listen44134;

server_namelocalhost;

location/{

proxy_passhttp://httpbin-diffy.diffy:8880/;

proxy_http_version1.1;

proxy_set_headerUpgrade$http_upgrade;

proxy_set_headerConnection"upgrade";

}

}

版本2的部署作為Istio的流量鏡像目標(biāo),在接收到流量之后會(huì)轉(zhuǎn)發(fā)到Diffy的代理中。當(dāng)前沒(méi)有直接將Diffy代理作為Istio流量鏡像目標(biāo),原因是Diffy代理與Envoy代理目前本身有沖突,無(wú)法正常流量轉(zhuǎn)發(fā),因此需要此部署中轉(zhuǎn)一下。apiVersion:extensions/v1beta1

kind:Deployment

metadata:

name:mirrorservice-sample-v2

spec:

replicas:1

template:

metadata:

labels:

app:mirrorservice-sample

version:v2

spec:

containers:

-name:mirrorservice-sample

image:/istio-samples/mirrorservice:0.1

imagePullPolicy:Always

ports:

-containerPort:44134

對(duì)應(yīng)的Kubernetesservice,具體參見(jiàn)sample-service.yaml中的定義:apiVersion:v1

kind:Service

metadata:

name:mirrorservice-sample

spec:

type:ClusterIP

ports:

-name:http

port:44134

selector:

app:mirrorservice-sample

最后,通過(guò)執(zhí)行命令kubectlapply-ndiffy-fsample-service.yaml,創(chuàng)建示例服務(wù)以及相應(yīng)的pod。4.3.4創(chuàng)建流量鏡像的Istio策略默認(rèn)情況下,Kubernetes在服務(wù)的兩個(gè)版本之間進(jìn)行負(fù)載均衡。創(chuàng)建如下流量鏡像規(guī)則(具體代碼參見(jiàn)sample-mirror-policy.yaml)將100%的流量發(fā)送到v1,同時(shí)指定流量鏡像到v2。當(dāng)流量被鏡像時(shí),請(qǐng)求將通過(guò)其主機(jī)/授權(quán)報(bào)頭發(fā)送到鏡像服務(wù)附上-shadow:apiVersion:networking.istio.io/v1alpha3

kind:DestinationRule

metadata:

name:mirrorservice-sample

spec:

host:mirrorservice-sample

subsets:

-name:v1

labels:

version:v1

-name:v2

labels:

version:v2

apiVersion:networking.istio.io/v1alpha3

kind:VirtualService

metadata:

name:mirrorservice-sample

spec:

hosts:

-mirrorservice-sample

http:

-route:

-destination:

host:mirrorservice-sample

subset:v1

weight:100

mirror:

host:mirrorservice-sample

subset:v2

4.3.5搭建Diffy用于請(qǐng)求流量對(duì)比Diffy可以作為代理,截取請(qǐng)求并發(fā)送至所有運(yùn)行的服務(wù)實(shí)例,通過(guò)對(duì)比響應(yīng)結(jié)果來(lái)發(fā)現(xiàn)每次迭代代碼中可能存在的問(wèn)題。其中,Diffy上運(yùn)行了三類(lèi)代碼實(shí)例(如圖4-16所示):·線上穩(wěn)定版本:一個(gè)運(yùn)行線上穩(wěn)定版本代碼的節(jié)點(diǎn)?!ぞ€上穩(wěn)定版本備份:同樣運(yùn)行了線上的穩(wěn)定版本,用于消除噪音?!y(cè)試版本:待上線的測(cè)試版本,用于和線上環(huán)境代碼進(jìn)行對(duì)比。圖4-16Diffy運(yùn)行機(jī)制在實(shí)際Diffy測(cè)試中,會(huì)發(fā)現(xiàn)大部分的接口都會(huì)有一定差異,原因是這些響應(yīng)中存在噪音,噪音可能包括:·server響應(yīng)中生成的時(shí)間戳?!るS機(jī)生成的數(shù)字?!は到y(tǒng)服務(wù)間的有條件競(jìng)爭(zhēng)。Diffy能夠通過(guò)一定的方式清除這類(lèi)噪音,保證分析結(jié)果不被影響。下面的YAML代碼(可參見(jiàn)diff.yaml)包括一個(gè)Diffy的KubernetesService與一個(gè)相應(yīng)的KubernetesDep-loyment資源定義描述,可以創(chuàng)建出一個(gè)可運(yùn)行的Diffy服務(wù):apiVersion:v1

kind:Service

metadata:

name:httpbin-diffy

labels:

app:httpbin-diffy

spec:

ports:

-name:http-proxy

port:8880

-name:http-admin

port:8881

-name:http-console

port:8888

selector:

app:httpbin-diffy

apiVersion:extensions/v1beta1

kind:Deployment

metadata:

labels:

app:httpbin-diffy

version:v2

name:httpbin-diffy-v2

spec:

replicas:1

selector:

matchLabels:

app:httpbin-diffy

version:v2

template:

metadata:

labels:

app:httpbin-diffy

version:v2

spec:

containers:

-image:diffy/diffy:latest

imagePullPolicy:IfNotPresent

livenessProbe:

exec:

command:

-curl

-localhost:8888

initialDelaySeconds:10

periodSeconds:60

timeoutSeconds:1

name:httpbin-diffy

args:["-candidate=httpbin-candidate:8080","-master.primary=httpbin-master:8080","-master.secondary=httpbin-master:8080","-tocol=http","-serviceName=httpbin","-proxy.port=:8880","-admin.port=:8881","-http.port=:8888",

"-rootUrl='localhost:8888'"]

ports:

-containerPort:8888

name:http-console

protocol:TCP

-containerPort:8880

name:http-proxy

protocol:TCP

-containerPort:8881

name:http-admin

protocol:TCP

readinessProbe:

exec:

command:

-curl

-localhost:8888

initialDelaySeconds:10

periodSeconds:60

timeoutSeconds:1

securityContext:

privileged:false

通過(guò)以下YAML(具體可參見(jiàn)httpbin-service.yaml)創(chuàng)建示例所用的primary、secondary(當(dāng)前示例中與primary相同)與candidate服務(wù):apiVersion:v1

kind:Service

metadata:

name:httpbin-master

labels:

app:httpbin-master

spec:

ports:

-name:http

port:8080

selector:

app:httpbin

version:v1

apiVersion:v1

kind:Service

metadata:

name:httpbin-candidate

labels:

app:httpbin-candidate

spec:

ports:

-name:http

port:8080

selector:

app:httpbin

version:v2

apiVersion:extensions/v1beta1

kind:Deployment

metadata:

name:httpbin-v1

spec:

replicas:1

template:

metadata:

labels:

app:httpbin

version:v1

spec:

containers:

-image:docker.io/kennethreitz/httpbin

imagePullPolicy:IfNotPresent

name:httpbin

command:["gunicorn","--access-logfile","-","-b",":8080","httpbin:app"]

ports:

-containerPort:8080

apiVersion:extensions/v1beta1

kind:Deployment

metadata:

name:httpbin-v2

spec:

replicas:1

template:

metadata:

labels:

app:httpbin

version:v2

spec:

containers:

-image:docker.io/kennethreitz/httpbin

imagePullPolicy:IfNotPresent

name:httpbin

command:["gunicorn","--access-logfile","-","-b",":8080","httpbin:app"]

ports:

-containerPort:8080

4.3.6發(fā)送流量進(jìn)行鏡像驗(yàn)證啟動(dòng)sleep服務(wù),這樣就可以使用curl來(lái)提供負(fù)載:cat<<EOF|istioctlkube-inject-f-|kubectlcreate-f-

apiVersion:extensions/v1beta1

kind:Deployment

metadata:

name:sleep

spec:

replicas:1

template:

metadata:

labels:

app:sleep

spec:

containers:

-name:sleep

image:tutum/curl

command:["/bin/sleep","infinity"]

imagePullPolicy:IfNotPresent

EOF

進(jìn)入到SLEEP_POD,具體POD名稱(chēng)根據(jù)實(shí)際賦值:kubectlexec-it$SLEEP_POD-csleepsh

發(fā)送流量:curl-vhttp://mirrorservice-sample:44134/headers

可以查看v1的訪問(wèn)日志記錄,如圖4-17所示,創(chuàng)建的請(qǐng)求100%指向了v1。圖4-17v1的訪問(wèn)日志記錄與此同時(shí),查看Diffy的Web界面,如圖4-18所示,可以看到創(chuàng)建的請(qǐng)求也被鏡像到DiffyProxy,如圖4-19所示。圖4-18Diffy查看界面圖4-19返回結(jié)果的差異結(jié)果Diffy能夠通過(guò)一定的方式清除這類(lèi)噪音,保證分析結(jié)果不被影響,如圖4-20所示。圖4-20消除噪音后的結(jié)果4.4通過(guò)Istio管理應(yīng)用的灰度發(fā)布在項(xiàng)目迭代的過(guò)程中,不可避免需要上線。上線對(duì)應(yīng)著部署,或者重新部署;部署對(duì)應(yīng)著修改,修改則意味著風(fēng)險(xiǎn)。灰度發(fā)布是指用平滑過(guò)渡的方式進(jìn)行發(fā)布?;叶劝l(fā)布可以保證整體系統(tǒng)的穩(wěn)定,在初始發(fā)布的時(shí)候就可以發(fā)現(xiàn)、調(diào)整問(wèn)題,以保證其影響度,而我們平常所說(shuō)的藍(lán)綠發(fā)布、A/B測(cè)試、金絲雀發(fā)布等是灰度發(fā)布的不同方式。1.藍(lán)綠發(fā)布藍(lán)綠發(fā)布是指不停止老版本,部署新版本,然后進(jìn)行測(cè)試,確認(rèn)沒(méi)有問(wèn)題之后,再將流量切到新版本,然后老版本同時(shí)也升級(jí)到新版本。這樣做的好處是無(wú)需停機(jī),并且風(fēng)險(xiǎn)較小。圖4-21藍(lán)綠發(fā)布示例藍(lán)綠發(fā)布的步驟大致如下:1)部署版本1的應(yīng)用(一開(kāi)始的狀態(tài)),所有外部請(qǐng)求的流量都打到這個(gè)版本上。2)部署版本2的應(yīng)用,版本2的代碼與版本1不同(新功能、Bug修復(fù)等)。3)將流量從版本1切換到版本2,即流量從v1:v2為100:0,切換為0:100。4)如果版本2存在問(wèn)題,需要回滾到版本1,進(jìn)行流量切換回v1:v2為100:0。2.A/B測(cè)試A/B測(cè)試是用來(lái)測(cè)試應(yīng)用功能表現(xiàn)的一種方法,例如可用性、受歡迎程度、可見(jiàn)性等。A/B測(cè)試通常會(huì)針對(duì)特定的用戶群體進(jìn)行,其目的在于通過(guò)科學(xué)的實(shí)驗(yàn)設(shè)計(jì)、采樣樣本代表性、流量分割與小流量測(cè)試等方式來(lái)獲得具有代表性的實(shí)驗(yàn)結(jié)論,并確信該結(jié)論在推廣到全部流量可信;這與藍(lán)綠發(fā)布的目的不盡相同,藍(lán)綠發(fā)布主要用于安全穩(wěn)定地發(fā)布新版本應(yīng)用。圖4-22A/B測(cè)試示例3.金絲雀發(fā)布金絲雀發(fā)布是指通過(guò)讓一小部分用戶流量引入的新版本進(jìn)行測(cè)試,如果一切順利,則可以增加(可能逐漸增加)百分比,逐步替換舊版本。如在過(guò)程中出現(xiàn)任何問(wèn)題,則可以中止并回滾到舊版本。最簡(jiǎn)單的方式是隨機(jī)選擇百分比請(qǐng)求到金絲雀版本,但在更復(fù)雜的方案下,則可以基于請(qǐng)求的內(nèi)容、特定范圍的用戶或其他屬性等。圖4-23金絲雀發(fā)布示例4.4.1Kubernetes中的灰度發(fā)布Kubernetes自帶的rolling-update(滾動(dòng)升級(jí))功能提供了一種漸進(jìn)式的更新方法,可以實(shí)現(xiàn)在不中斷業(yè)務(wù)的情況下進(jìn)行應(yīng)用升級(jí)。下面簡(jiǎn)要回顧一下Kubernetes的升級(jí)策略:spec:

replicas:5

strategy:

type:RollingUpdate

rollingUpdate:

maxSurge:2

maxUnavailable:2

minReadySeconds:5

上述代碼定義了一些關(guān)鍵值,如下所示:·maxSurge:升級(jí)過(guò)程中最多可以比原先設(shè)定多出的pod數(shù)量,此值可以為固定值或是比例(%)。例如:maxSurge:1、replicas:5,代表Kubernetes會(huì)先開(kāi)好1個(gè)新pod后才刪掉一個(gè)舊的pod,整個(gè)升級(jí)過(guò)程中最多會(huì)有5+1個(gè)pod。·maxUnavailable:最多可以有幾個(gè)pod處在無(wú)法服務(wù)的狀態(tài),當(dāng)maxSurge不為零時(shí),此值亦不可為零。例如.maxUnavailable:1,代表Kubernetes整個(gè)升級(jí)過(guò)程中最多會(huì)有1個(gè)pod處在無(wú)法服務(wù)的狀態(tài)?!inReadySeconds:容器內(nèi)應(yīng)用啟動(dòng)時(shí)間,Kubernetes會(huì)等待設(shè)定的時(shí)間后才繼續(xù)進(jìn)行升級(jí)流程,如果沒(méi)有此值的話,Kubernetes會(huì)假設(shè)該容器一開(kāi)完后即可進(jìn)行服務(wù)。實(shí)現(xiàn)滾動(dòng)升級(jí)的方式也有以下幾種:kubectlsetimage、kubectlreplace、kubectlrollout。盡管這種機(jī)制能夠很好地工作,但只適用于部署的經(jīng)過(guò)適當(dāng)測(cè)試的版本,也就是說(shuō),更多適用于藍(lán)/綠發(fā)布場(chǎng)景。實(shí)際上,Kubernetes中的金絲雀發(fā)布將使用具有相同Label的兩個(gè)部署來(lái)完成。在這種情況下,我們不能再使用AutoScaler,因?yàn)橛杏蓛蓚€(gè)獨(dú)立的AutoScaler來(lái)進(jìn)行控制,不同負(fù)載情況下,replicas比例(百分比)可能與所需的比例不同。無(wú)論我們使用一個(gè)還是兩個(gè)部署,使用Kubernetes進(jìn)行的金絲雀發(fā)布都存在一個(gè)根本問(wèn)題:使用實(shí)例擴(kuò)容來(lái)管理流量;這是因?yàn)榘姹玖髁糠职l(fā)和部署在Kubernetes平臺(tái)中的副本并非獨(dú)立。所有pod副本,無(wú)論版本如何,在kube-proxy循環(huán)池中都被相同對(duì)待,因此管理特定版本接收的流量的唯一方法是控制副本比例。以小百分比例的金絲雀流量需要許多副本(例如1%將需要至少100個(gè)副本)。即使我們可以忽略這個(gè)問(wèn)題,部署方式功能仍然非常有限,因?yàn)樗恢С趾?jiǎn)單(隨機(jī)百分比)金絲雀部署。如果想根據(jù)某些特定規(guī)則將請(qǐng)求路由到金絲雀版本上,仍然需要另一種解決方案。這就需要用到Istio。4.4.2使用Istio進(jìn)行灰度發(fā)布在使用Istio實(shí)現(xiàn)灰度發(fā)布的情況下,流量路由和副本部署是兩個(gè)完全獨(dú)立的功能。服務(wù)的pod數(shù)量可以根據(jù)流量負(fù)載靈活伸縮,與版本流量路由的控制完全無(wú)關(guān)。這在自動(dòng)縮放的情況下能夠更加簡(jiǎn)單地管理金絲雀版本。Istio的路由規(guī)則非常靈活,可以支持細(xì)粒度控制流量百分比(例如,路由1%的流量而不需要100個(gè)pod),也可以使用其他規(guī)則來(lái)控制流量(例如,將特定用戶的流量路由到金絲雀版本)。案例如下所示:apiVersion:networking.istio.io/v1alpha3

kind:VirtualService

metadata:

name:addedvalues

spec:

hosts:

-addedvalues

http:

-match:

-headers:

end-user:

prefix:yunqi

route:

-destination:

host:addedvalues

subset:v3

-route:

-destination:

host:addedvalues

subset:v2

weight:50

-destination:

host:addedvalues

subset:v1

weight:50

4.4.3統(tǒng)一的流量路由規(guī)則使用Istio進(jìn)行灰度發(fā)布時(shí),由于不再使用副本比例維持流量分發(fā)比例,所以可以安全地設(shè)置KubernetesHPA來(lái)管理兩個(gè)版本部署的副本。無(wú)論是藍(lán)綠發(fā)布,還是A/B測(cè)試或金絲雀發(fā)布,均可基于Istio提供的統(tǒng)一的流量路由規(guī)則定義來(lái)實(shí)現(xiàn)??梢杂谢诹髁勘壤陌l(fā)布、基于請(qǐng)求內(nèi)容的發(fā)布。下面分別介紹。1.基于流量比例的發(fā)布Istio根據(jù)輸入的流量比例來(lái)確定流量分發(fā)的比重。范圍限制為[0,100],例如,當(dāng)版本v1配置為0,版本v2配置為100時(shí),這種場(chǎng)景即為藍(lán)綠發(fā)布。此外,如果版本v1比例設(shè)置為x,則x%的服務(wù)流量會(huì)走向此版本v1,(100-x)%的流量會(huì)走向版本v2,即從版本v1分走一部分流量。這種場(chǎng)景即為金絲雀發(fā)布或A/B測(cè)試。2.基于請(qǐng)求內(nèi)容的發(fā)布基于請(qǐng)求內(nèi)容的發(fā)布會(huì)遍歷除默認(rèn)版本外的全部金絲雀規(guī)則,若滿足某個(gè)版本的規(guī)則,則流量走向此版本,若全部不滿足,則流量會(huì)走到默認(rèn)版本。這種場(chǎng)景即為金絲雀發(fā)布或A/B測(cè)試中使用到的規(guī)則。例如,可以支持如下基于請(qǐng)求內(nèi)容的分發(fā):·基于瀏覽器的分發(fā)·基于操作系統(tǒng)的分發(fā)·基于Cookie的分發(fā)·Cookie的cookiename包含string?!ご嬖贑ookie的cookiename?!げ淮嬖贑ookie的cookiename。·基于HTTP請(qǐng)求頭的分發(fā)·請(qǐng)求頭headername包含string?!ふ?qǐng)求頭中包含headername?!ふ?qǐng)求頭中不包含headername針對(duì)來(lái)自不同瀏覽器的請(qǐng)求規(guī)則定義參見(jiàn)表4-1。表4-1基于瀏覽器的請(qǐng)求規(guī)則針對(duì)來(lái)自不同操作系統(tǒng)的請(qǐng)求規(guī)則定義參見(jiàn)表4-2。表4-2基于操作系統(tǒng)的請(qǐng)求規(guī)則針對(duì)不同cookie內(nèi)容的請(qǐng)求規(guī)則定義參見(jiàn)表4-3。表4-3基于Cookie的請(qǐng)求規(guī)則如上所述,Istio可以支持靈活規(guī)則下的金絲雀發(fā)布,以及區(qū)別于Kubernetes部署方式。Istio服務(wù)網(wǎng)格提供了管理流量分配所需的基礎(chǔ)控制,并完全獨(dú)立于AutoScaler,從而允許開(kāi)發(fā)者用簡(jiǎn)單而強(qiáng)大的方式來(lái)進(jìn)行金絲雀測(cè)試和上線操作。4.5本章總結(jié)東西向流量管理是服務(wù)網(wǎng)格的最重要核心功能之一,也是服務(wù)網(wǎng)格區(qū)別于類(lèi)似API網(wǎng)關(guān)、Kubernetes入口網(wǎng)關(guān)等的關(guān)鍵點(diǎn)。希望讀者通過(guò)本章可以掌握服務(wù)網(wǎng)格Istio的核心元素,如VirtualService、DestinationRule、Sidecar等自定義資源類(lèi)型,并能夠熟練使用這些自定義資源來(lái)定義服務(wù)的流量管理規(guī)則。第5章南北向流量管理在本書(shū)的大部分內(nèi)容中,我們假設(shè)單個(gè)集群具有單個(gè)Istio控制平面部署,但實(shí)際上Istio的功能不僅限于單個(gè)集群部署,還適合非Kubernetes混合環(huán)境的部署。在本章中,我們將介紹將集群外部的客戶端連接到集群內(nèi)運(yùn)行的服務(wù),以及如何從集群內(nèi)的服務(wù)訪問(wèn)集群外部的任何服務(wù),即通常所說(shuō)的南北向流量管理。其中介紹了Istio在南北向流量方面的路由控制能力,引出Istio網(wǎng)關(guān)的概念及其工作原理,接著介紹了如何通過(guò)HTTPS加密Istio網(wǎng)關(guān),以及介紹了基于SNI的TLS路由能力,之后介紹服務(wù)條目(ServiceEntry)的概念,詳細(xì)介紹如何實(shí)現(xiàn)出口流量路由的統(tǒng)一管理,最后介紹基于CoreDNSPlugin擴(kuò)展實(shí)現(xiàn)服務(wù)條目的DNS尋址。5.1Istio網(wǎng)關(guān)網(wǎng)絡(luò)社區(qū)中有一個(gè)術(shù)語(yǔ)Ingress,是指入口請(qǐng)求到集群內(nèi)服務(wù)的流量管理。Ingress指的是源自本地網(wǎng)絡(luò)之外的流量,指向本地集群網(wǎng)絡(luò)中的端點(diǎn)。此流量首先路由到公開(kāi)的入口點(diǎn),以便通過(guò)執(zhí)行一些本地網(wǎng)絡(luò)的規(guī)則和策略來(lái)確認(rèn)哪些流量被允許進(jìn)入。如果流量未通過(guò)這些入口點(diǎn),則無(wú)法與集群內(nèi)的任何服務(wù)連接。如果入口點(diǎn)允許流量進(jìn)入,則將其代理到本地網(wǎng)絡(luò)中的合適節(jié)點(diǎn)。Istio對(duì)入口流量的管理是由Istio網(wǎng)關(guān)進(jìn)行的。接下來(lái)將會(huì)介紹Istio網(wǎng)關(guān)的工作機(jī)制,以及Istio網(wǎng)關(guān)的負(fù)載均衡器原理,然后介紹入口網(wǎng)關(guān)(IngressGateway)的服務(wù)與部署的定義,以及網(wǎng)關(guān)資源、網(wǎng)關(guān)虛擬服務(wù)的定義,最后通過(guò)一個(gè)示例介紹如何調(diào)試入口網(wǎng)關(guān)可能遇到的問(wèn)題。5.1.1Istio網(wǎng)關(guān)的工作原理傳統(tǒng)上,Kubernetes使用Ingress控制器來(lái)處理從外部進(jìn)入集群的流量。使用Istio時(shí),情況不再如此。Istio網(wǎng)關(guān)用新的Gateway資源和VirtualServices資源來(lái)控制入口流量,它們協(xié)同工作以將流量路由到網(wǎng)格中。在網(wǎng)格內(nèi)部不需要Gateways,因?yàn)榉?wù)可以通過(guò)集群本地服務(wù)名稱(chēng)相互訪問(wèn)。那么Istio網(wǎng)關(guān)是怎樣工作的?請(qǐng)求如何到達(dá)它想要的應(yīng)用程序?基本步驟如下:1)客戶端在特定端口上發(fā)出請(qǐng)求。2)負(fù)載均衡器在這個(gè)端口上進(jìn)行偵聽(tīng),并將請(qǐng)求轉(zhuǎn)發(fā)到集群中(在相同或新的端口)。3)在集群內(nèi)部,請(qǐng)求被路由到IstioIngressGateway服務(wù)所偵聽(tīng)的負(fù)載均衡器轉(zhuǎn)發(fā)過(guò)來(lái)的端口上。4)IstioIngressGateway服務(wù)將請(qǐng)求(在相同或新的端口)轉(zhuǎn)發(fā)到對(duì)應(yīng)的pod上。5)在IngressGatewaypod上會(huì)配置Gateway資源和VirtualService資源定義。Gateway會(huì)配置端口、協(xié)議以及相關(guān)安全證書(shū)。VirtualService的路由配置信息用于找到正確的服務(wù)。6)IstioIngressGatewaypod會(huì)根據(jù)路由配置信息將請(qǐng)求路由到對(duì)應(yīng)的應(yīng)用服務(wù)上。7)應(yīng)用服務(wù)將請(qǐng)求路由到對(duì)應(yīng)的應(yīng)用pod上。Istio網(wǎng)關(guān)工作原理如圖5-1所示。圖5-1Istio網(wǎng)關(guān)的工作原理5.1.2Istio網(wǎng)關(guān)的負(fù)載均衡作用典型的服務(wù)網(wǎng)格具有一個(gè)或多個(gè)負(fù)載均衡器,也稱(chēng)為網(wǎng)關(guān)(Gateway),它們從外部網(wǎng)絡(luò)終止TLS并允許流量進(jìn)入網(wǎng)格。然后,流量通過(guò)邊車(chē)網(wǎng)關(guān)(Sidecargateway)流經(jīng)內(nèi)部服務(wù)。應(yīng)用程序使用外部服務(wù)的場(chǎng)景也很常見(jiàn),可以直接調(diào)用外部服務(wù),或者在某些部署中強(qiáng)制通過(guò)專(zhuān)用出口網(wǎng)關(guān)(EgressGateway)離開(kāi)網(wǎng)格的所有流量。圖5-2描繪了網(wǎng)關(guān)在網(wǎng)格中的使用情況。Istio具有入口網(wǎng)關(guān)的概念,它扮演網(wǎng)絡(luò)入口點(diǎn)的角色,負(fù)責(zé)保護(hù)和控制來(lái)自集群外部的流量對(duì)集群的訪問(wèn)。圖5-2網(wǎng)關(guān)在網(wǎng)格中的使用情況此外,Istio的網(wǎng)關(guān)還扮演負(fù)載均衡和虛擬主機(jī)路由的角色。如圖5-3所示,可以看到默認(rèn)情況下Istio使用Envoy代理作為入口代理。我們?cè)谇懊娴恼鹿?jié)中看到,Envoy是一個(gè)功能強(qiáng)大的服務(wù)到服務(wù)代理,但它也有負(fù)載均衡和路由的功能,可代理的流量包括從服務(wù)網(wǎng)格外部到其內(nèi)部運(yùn)行的服務(wù),或者從集群內(nèi)部服務(wù)到外部服務(wù)。在前面章節(jié)中介紹的Envoy的所有功能也可以在入口網(wǎng)關(guān)中使用。圖5-3Istio的入口網(wǎng)關(guān)服務(wù)對(duì)于入口流量管理,你可能會(huì)問(wèn):為什么不直接使用KubernetesIngressAPI?第一個(gè)原因,KubernetesIngress是一個(gè)面向HTTP工作負(fù)載的非常簡(jiǎn)單的規(guī)范。有KubernetesIngress的實(shí)現(xiàn)(如Nginx、HeptioContour等),但每個(gè)都適用于HTTP流量。實(shí)際上,Ingress規(guī)范只將端口80和端口443視為入口點(diǎn)。這嚴(yán)重限制了集群運(yùn)維人員可以允許進(jìn)入服務(wù)網(wǎng)格的流量類(lèi)型。例如,如果你有Kafka工作負(fù)載,則可能希望向這些消息代理公開(kāi)直接TCP連接。第二個(gè)原因,KubernetesIngressAPI無(wú)法表達(dá)Istio的路由需求。Ingress沒(méi)有通用的方法來(lái)指定復(fù)雜的流量路由規(guī)則,如流量拆分或流量鏡像等。這個(gè)領(lǐng)域缺乏規(guī)范會(huì)導(dǎo)致每個(gè)供應(yīng)商重新設(shè)想如何更好地為每種類(lèi)型的Ingress實(shí)現(xiàn)(如HAProxy、Nginx等)做好配置管理。Ingress試圖在不同的HTTP代理之間取一個(gè)公共的交集,因此只能支持最基本的HTTP路由。最后一個(gè)原因,由于事前沒(méi)有明確規(guī)定,大多數(shù)供應(yīng)商的選擇是通過(guò)部署上的定制注釋來(lái)做配置。供應(yīng)商之間的注釋各不相同,并且不可移植,如果Istio繼續(xù)延續(xù)這種趨勢(shì),那么就會(huì)有更多的注釋來(lái)解釋Envoy作為邊緣網(wǎng)關(guān)的所有功能。Istio網(wǎng)關(guān)通過(guò)將L4-L6配置與L7配置分離克服了Ingress的這些缺點(diǎn)。Istio網(wǎng)關(guān)只用于配置L4-L6功能(例如,對(duì)外公開(kāi)的端口、TLS配置),所有主流的L7代理均以統(tǒng)一的方式實(shí)現(xiàn)了這些功能。然后,通過(guò)在Gateway上綁定VirtualService的方式,可以使用標(biāo)準(zhǔn)的Istio規(guī)則來(lái)控制進(jìn)入Gateway的HTTP和TCP流量。負(fù)載均衡器可以手動(dòng)配置或通過(guò)服務(wù)自動(dòng)配置其類(lèi)型,例如type:LoadBalancer。在這種情況下,由于并非所有云都支持自動(dòng)配置,假設(shè)手動(dòng)配置負(fù)載均衡器以將流量轉(zhuǎn)發(fā)到IngressGatewayService正在偵聽(tīng)的端口。例如如下的負(fù)載均衡器正在監(jiān)聽(tīng)以下端口:·HTTP:端口80,將流量轉(zhuǎn)發(fā)到端口30080?!TTPS:端口443,將流量轉(zhuǎn)發(fā)到端口30443?!ySQL:端口3306,將流量轉(zhuǎn)發(fā)到端口30306。確保負(fù)載均衡器配置轉(zhuǎn)發(fā)到所有工作節(jié)點(diǎn)。這將確保即使某些節(jié)點(diǎn)關(guān)閉也會(huì)轉(zhuǎn)發(fā)流量。5.1.3入口網(wǎng)關(guān)服務(wù)IngressGateway服務(wù)(入口網(wǎng)關(guān)服務(wù))必須監(jiān)聽(tīng)上節(jié)介紹的所有端口,以便能夠?qū)⒘髁哭D(zhuǎn)發(fā)到IngressGatewaypod上。Kubernetes服務(wù)不是“真正的”服務(wù),該請(qǐng)求將由Kubernetes提供的kube-proxy轉(zhuǎn)發(fā)到具有運(yùn)行對(duì)應(yīng)pod的節(jié)點(diǎn)上。在節(jié)點(diǎn)上,IPtable配置將請(qǐng)求轉(zhuǎn)發(fā)到適當(dāng)?shù)膒od:ports:

-name:http2

nodePort:30000

port:80

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論