Knative Service 之流量灰度和版本管理
本篇主要介紹 Knative Serving 的流量灰度,通過(guò)一個(gè) rest-api 的例子演示如何創(chuàng)建不同的 Revision、如何在不同的 Revision 之間按照流量比例灰度。
部署 rest-api v1
- 代碼?
測(cè)試之前我們需要寫一段 rest-api 的代碼,并且還要能夠區(qū)分不同的版本。下面我基于官方的例子進(jìn)行了修改,為了使用方便去掉了?github.com/gorilla/mux?依賴,直接使用 Golang 系統(tǒng)包?net/http?替代。這段代碼可以通過(guò) RESOURCE 環(huán)境變量來(lái)區(qū)分不同的版本。
- Dockerfile
創(chuàng)建一個(gè)叫做 Dockerfile 的文件,把下面這些內(nèi)容復(fù)制到文件中。執(zhí)行?docker build --tag registry.cn-hangzhou.aliyuncs.com/knative-sample/rest-api-go:v1 --file ./Dockerfile .?命令即可完成鏡像的編譯。
你在測(cè)試的時(shí)候請(qǐng)把?registry.cn-hangzhou.aliyuncs.com/knative-sample/rest-api-go:v1?換成你自己的鏡像倉(cāng)庫(kù)地址。
編譯好鏡像以后執(zhí)行?docker push registry.cn-hangzhou.aliyuncs.com/knative-sample/rest-api-go:v1?把鏡像推送到鏡像倉(cāng)庫(kù)。
- Service 配置
鏡像已經(jīng)有了,我們開(kāi)始部署 Knative Service。把下面的內(nèi)容保存到 revision-v1.yaml 中,然后執(zhí)行?kubectl apply -f revision-v1.yaml??即可完成 Knative Service 的部署。
首次安裝會(huì)創(chuàng)建出一個(gè)叫做?stock-service-example-v1?的 Revision,并且是把 100% 的流量都打到?stock-service-example-v1?上。
驗(yàn)證 Serving 的各個(gè)資源
如下圖所示,我們先回顧一下 Serving 涉及到的各種資源。接下來(lái)我們分別看一下剛才部署的?revision-v1.yaml?各個(gè)資源配置。
- Knative Service
- Knative Configuration
- Knative Revision
- Knative Route
訪問(wèn) rest-api 服務(wù)
我們部署的 Service 名稱是: stock-service-example。訪問(wèn)這個(gè) Service 需要獲取 Istio Gateway 的 IP,然后使用 stock-service-example Domain 綁定 Host 的方式發(fā)起 curl 請(qǐng)求。為了方便測(cè)試我寫成了一個(gè)腳本。創(chuàng)建一個(gè) run-test.sh 文件,把下面這些內(nèi)容復(fù)制到文件內(nèi),然后賦予文件可執(zhí)行權(quán)限。執(zhí)行執(zhí)行此腳本就能得到測(cè)試結(jié)果。
測(cè)試結(jié)果:
從下面的命令輸出結(jié)果可以看到現(xiàn)在返回的是 v1 的信息,說(shuō)明請(qǐng)求打到 v1 上面了。
灰度 50% 的流量到 v2
修改 Service 創(chuàng)建 v2 revision , 創(chuàng)建一個(gè)?revision-v2.yaml?文件,內(nèi)容如下:
apiVersion: serving.knative.dev/v1alpha1 kind: Service metadata:name: stock-service-examplenamespace: default spec:template:metadata:name: stock-service-example-v2spec:containers:- image: registry.cn-hangzhou.aliyuncs.com/knative-sample/rest-api-go:v1env:- name: RESOURCEvalue: v2readinessProbe:httpGet:path: /initialDelaySeconds: 0periodSeconds: 3traffic:- tag: v1revisionName: stock-service-example-v1percent: 50- tag: v2revisionName: stock-service-example-v2percent: 50- tag: latestlatestRevision: truepercent: 0我們對(duì)比一下 v1 版本和 v2 版本可以發(fā)現(xiàn),v2 版本的 Service 中增加了?traffic:?的配置。在 traffic 中指定了每一個(gè) Revision。 執(zhí)行?kubectl apply -f revision-v2.yaml?安裝 v2 版本的配置。然后執(zhí)行測(cè)試腳本就能看到現(xiàn)在返回的結(jié)果中 v1 和 v2 基本上是各占 50% 的比例。下面這是我真實(shí)測(cè)試的結(jié)果。
└─# ./run-test.sh Welcome to the v2 app! └─# ./run-test.sh Welcome to the v1 app! └─# ./run-test.sh Welcome to the v2 app! └─# ./run-test.sh Welcome to the v1 app!提前驗(yàn)證 Revision
上面展示的 v2 的例子,在創(chuàng)建 v2 的時(shí)候直接就把流量分發(fā)到 v2 ,如果此時(shí) v2 有問(wèn)題就會(huì)導(dǎo)致有 50% 的流量異常。下面我們就展示一下如何在轉(zhuǎn)發(fā)流量之前驗(yàn)證新的 revision 服務(wù)是否正常。我們?cè)賱?chuàng)建一個(gè) v3 版本。
創(chuàng)建一個(gè)?revision-v3.yaml?的文件,內(nèi)容如下:
執(zhí)行?kubectl apply -f revision-v3.yaml?部署 v3 版本。然后查看一下 Revision 情況:
└─# kubectl get revision NAME SERVICE NAME GENERATION READY REASON stock-service-example-v1 stock-service-example-v1 1 True stock-service-example-v2 stock-service-example-v2 2 True stock-service-example-v3 stock-service-example-v3 3 True可以看到現(xiàn)在已經(jīng)創(chuàng)建出來(lái)了三個(gè) Revision 。
此時(shí)我們?cè)倏匆幌?stock-service-example 的真實(shí)生效:
可以看到 v3 Revision 雖然創(chuàng)建出來(lái)了,但是因?yàn)闆](méi)有設(shè)置 traffic,所以并不會(huì)有流量轉(zhuǎn)發(fā)。此時(shí)你執(zhí)行多少次?./run-test.sh?都不會(huì)得到 v3 的輸出。
在 Service 的 status.traffic 配置中可以看到 latest Revision 的配置:
每一個(gè) Revision 都有一個(gè)自己的 URL,所以只需要基于 v3 Revision 的 URL 發(fā)起請(qǐng)求就能開(kāi)始測(cè)試了。
我已經(jīng)寫好了一個(gè)測(cè)試腳本,你可以把下面這段腳本保存在?latest-run-test.sh?文件中,然后執(zhí)行這個(gè)腳本就能直接發(fā)起到 latest 版本的請(qǐng)求:
測(cè)試 v3 版本如果沒(méi)問(wèn)題就可以把流量分發(fā)到 v3 版本了。
下面我們?cè)賱?chuàng)建一個(gè)文件?revision-v3-2.yaml?, 內(nèi)容如下:
用 vimdiff 看一下 revision-v3.yaml 和 revision-v3-2.yaml 的區(qū)別:
revision-v3-2.yaml 增加了到 v3 的流量轉(zhuǎn)發(fā)。此時(shí)執(zhí)行?./run-test.sh?可以看到 v1、v2 和 v3 的比例基本是:4:3:3
└─# ./run-test.sh Welcome to the v1 app! └─# ./run-test.sh Welcome to the v2 app! └─# ./run-test.sh Welcome to the v1 app! └─# ./run-test.sh Welcome to the v2 app! └─# ./run-test.sh Welcome to the v3 app! ... ...版本回滾
Knative Service 的 Revision 是不能修改的,每次 Service Spec 的更新創(chuàng)建的 Revision 都會(huì)保留在 kube-apiserver 中。如果應(yīng)用發(fā)布到某個(gè)新版本發(fā)現(xiàn)有問(wèn)題想要回滾到老版本的時(shí)候只需要指定相應(yīng)的 Revision,然后把流量轉(zhuǎn)發(fā)過(guò)去就行了。
小結(jié)
Knative Service 的灰度、回滾都是基于流量的。Workload(Pod) 是根據(jù)過(guò)來(lái)的流量自動(dòng)創(chuàng)建出來(lái)的。所以在 Knative Serving 模型中流量是核心驅(qū)動(dòng)。這和傳統(tǒng)的應(yīng)用發(fā)布、灰度模型是有區(qū)別的。
假設(shè)有一個(gè)應(yīng)用 app1 ,傳統(tǒng)的做法首先是設(shè)置應(yīng)用的實(shí)例個(gè)數(shù)( Kubernetes 體系中就是 Pod ),我們假設(shè)實(shí)例個(gè)數(shù)是 10 個(gè)。如果要進(jìn)行灰度發(fā)布,那么傳統(tǒng)的做法就是先發(fā)布一個(gè) Pod,此時(shí) v1 和 v2 的分布方式是:v1 的 Pod 9個(gè),v2 的 Pod 1 個(gè)。如果要繼續(xù)擴(kuò)大灰度范圍的話那就是 v2 的 Pod 數(shù)量變多,v1 的 Pod 數(shù)量變少,但總的 Pod 數(shù)量維持 10 個(gè)不變。
在 Knative Serving 模型中 Pod 數(shù)量永遠(yuǎn)都是根據(jù)流量自適應(yīng)的,不需要提前指定。在灰度的時(shí)候只需要指定流量在不同版本之間的灰度比例即可。每一個(gè) Revision 的實(shí)例數(shù)都是根據(jù)流量的大小自適應(yīng),不需要提前指定。
從上面的對(duì)比中可以發(fā)現(xiàn) Knative Serving 模型是可以精準(zhǔn)的控制灰度影響的范圍的,保證只灰度一部分流量。而傳統(tǒng)的模型中 Pod 灰度的比例并不能真實(shí)的代表流量的比例,是一個(gè)間接的灰度方法。
原文鏈接
本文為云棲社區(qū)原創(chuàng)內(nèi)容,未經(jīng)允許不得轉(zhuǎn)載。
總結(jié)
以上是生活随笔為你收集整理的Knative Service 之流量灰度和版本管理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 干货|Flutter 原理与闲鱼深度实践
- 下一篇: 10 人,2 个月 | 虾米音乐的监控体