Linkerd 2.10(Step by Step)(二) 自動(dòng)化的金絲雀發(fā)布
通過(guò)結(jié)合 Linkerd 和 Flagger 來(lái)根據(jù)服務(wù)指標(biāo)自動(dòng)金絲雀(canary)發(fā)布,從而降低部署風(fēng)險(xiǎn)。
Linkerd 2.10 中文手冊(cè)持續(xù)修正更新中:
https://linkerd.hacker-linner.com/
Linkerd 2.10 系列
- 快速上手 Linkerd v2 Service Mesh(服務(wù)網(wǎng)格)
 - 騰訊云 K8S 集群實(shí)戰(zhàn) Service Mesh—Linkerd2 & Traefik2 部署 emojivoto 應(yīng)用
 - 詳細(xì)了解 Linkerd 2.10 基礎(chǔ)功能,一起步入 Service Mesh 微服務(wù)架構(gòu)時(shí)代
 - Linkerd 2.10(Step by Step)—1. 將您的服務(wù)添加到 Linkerd
 
Linkerd 的流量拆分(traffic split)功能允許您在服務(wù)之間動(dòng)態(tài)轉(zhuǎn)移流量。這可用于實(shí)施低風(fēng)險(xiǎn)部署策略,如藍(lán)綠(blue-green)部署和金絲雀(canaries)。
但簡(jiǎn)單地將流量從一個(gè)服務(wù)版本轉(zhuǎn)移到下一個(gè)版本只是一個(gè)開(kāi)始。我們可以將流量拆分與 Linkerd 的自動(dòng)黃金指標(biāo)(golden metrics)遙測(cè)相結(jié)合, 并根據(jù)觀察到的指標(biāo)推動(dòng)流量決策。例如,我們可以逐漸將流量從舊部署轉(zhuǎn)移到新部署, 同時(shí)持續(xù)監(jiān)控其成功率。如果在任何時(shí)候成功率下降, 我們可以將流量轉(zhuǎn)移回原始部署并退出發(fā)布。理想情況下,我們的用戶始終保持快樂(lè)(remain happy),沒(méi)有注意到任何事情!
在本教程中,我們將引導(dǎo)您了解如何將 Linkerd 與 Flagger 結(jié)合使用, 后者是一種漸進(jìn)式交付工具, 可將 Linkerd 的指標(biāo)和流量拆分綁定在一個(gè)控制循環(huán)中, 從而實(shí)現(xiàn)全自動(dòng)、指標(biāo)感知的金絲雀部署。
先決條件
- 要使用本指南,您需要在集群上安裝 Linkerd 及其 Viz 擴(kuò)展。
 
如果您還沒(méi)有這樣做,請(qǐng)按照安裝Linkerd 指南進(jìn)行操作。
- Flagger 的安裝依賴于 kubectl 1.14 或更新版本。
 
安裝 Flagger
Linkerd 將管理實(shí)際的流量路由, 而 Flagger 會(huì)自動(dòng)執(zhí)行創(chuàng)建新 Kubernetes 資源(resources)、 觀察指標(biāo)(watching metrics)和逐步將用戶發(fā)送到新版本的過(guò)程。要將 Flagger 添加到您的集群并將其配置為與 Linkerd 一起使用,請(qǐng)運(yùn)行:
- kubectl apply -k github.com/fluxcd/flagger/kustomize/linkerd
 - # customresourcedefinition.apiextensions.k8s.io/alertproviders.flagger.app created
 - # customresourcedefinition.apiextensions.k8s.io/canaries.flagger.app created
 - # customresourcedefinition.apiextensions.k8s.io/metrictemplates.flagger.app created
 - # serviceaccount/flagger created
 - # clusterrole.rbac.authorization.k8s.io/flagger created
 - # clusterrolebinding.rbac.authorization.k8s.io/flagger created
 - # deployment.apps/flagger created
 
此命令添加:
- Canary
 
CRD 可以配置發(fā)布的方式。
- RBAC 授予 Flagger 修改它需要的所有資源的權(quán)限,例如部署(deployments)和服務(wù)(services)。
 - 配置為與 Linkerd 控制平面交互的控制器。
 
要觀察直到一切正常運(yùn)行,您可以使用 kubectl:
- kubectl -n linkerd rollout status deploy/flagger
 - # Waiting for deployment "flagger" rollout to finish: 0 of 1 updated replicas are available...
 - # deployment "flagger" successfully rolled out
 
設(shè)置 demo
該 demo 由三個(gè)組件組成:負(fù)載生成器(load generator)、部署(deployment)和前端(frontend)。部署會(huì)創(chuàng)建一個(gè) pod,該 pod 會(huì)返回一些信息,例如名稱。您可以使用響應(yīng)(responses)來(lái)觀察隨著 Flagger 編排的增量部署。由于需要某種活動(dòng)流量才能完成操作,因此負(fù)載生成器可以更輕松地執(zhí)行部署。這些組件的拓?fù)浣Y(jié)構(gòu)如下所示:
要將這些組件添加到您的集群并將它們包含在 Linkerd 數(shù)據(jù)平面中,請(qǐng)運(yùn)行:
- kubectl create ns test && \
 - kubectl apply -f https://run.linkerd.io/flagger.yml
 - # namespace/test created
 - # deployment.apps/load created
 - # configmap/frontend created
 - # deployment.apps/frontend created
 - # service/frontend created
 - # deployment.apps/podinfo created
 - # service/podinfo created
 
通過(guò)運(yùn)行以下命令驗(yàn)證一切是否已成功啟動(dòng):
- kubectl -n test rollout status deploy podinfo
 - # Waiting for deployment "podinfo" rollout to finish: 0 of 1 updated replicas are available...
 - # deployment "podinfo" successfully rolled out
 
通過(guò)在本地轉(zhuǎn)發(fā)前端服務(wù)并通過(guò)運(yùn)行在本地的 http://localhost:8080 來(lái)打開(kāi)檢查它:
- kubectl -n test port-forward svc/frontend 8080
 
我這里,為方便看到真實(shí)的一個(gè) demo,直接加個(gè) IngressRoute。
ingress-route.yaml
- apiVersion: traefik.containo.us/v1alpha1
 - kind: IngressRoute
 - metadata:
 - name: podinfo-dashboard-route
 - namespace: test
 - spec:
 - entryPoints:
 - - websecure
 - tls:
 - secretName: hacker-linner-cert-tls
 - routes:
 - - match: Host(`podinfo.hacker-linner.com`)
 - kind: Rule
 - services:
 - - name: frontend
 - port: 8080
 
你可以直接訪問(wèn) https://podinfo.hacker-linner.com。
流量轉(zhuǎn)移發(fā)生在連接的客戶端而不是服務(wù)器端。來(lái)自網(wǎng)格外部的任何請(qǐng)求都不會(huì)被轉(zhuǎn)移,并且將始終被定向到主后端。 LoadBalancer 類型的服務(wù)將表現(xiàn)出這種行為,因?yàn)樵床皇蔷W(wǎng)格的一部分。要轉(zhuǎn)移外部流量,請(qǐng)將入口控制器添加到網(wǎng)格中。
配置發(fā)布
在更改任何內(nèi)容之前,您需要配置發(fā)布應(yīng)如何在集群上推出(rolled out)。該配置包含在 Canary 定義中。要應(yīng)用于您的集群,請(qǐng)運(yùn)行:
- cat <<EOF | kubectl apply -f -
 - apiVersion: flagger.app/v1beta1
 - kind: Canary
 - metadata:
 - name: podinfo
 - namespace: test
 - spec:
 - targetRef:
 - apiVersion: apps/v1
 - kind: Deployment
 - name: podinfo
 - service:
 - port: 9898
 - analysis:
 - interval: 10s
 - threshold: 5
 - stepWeight: 10
 - maxWeight: 100
 - metrics:
 - - name: request-success-rate
 - thresholdRange:
 - min: 99
 - interval: 1m
 - - name: request-duration
 - thresholdRange:
 - max: 500
 - interval: 1m
 - EOF
 
Flagger 控制器正在監(jiān)視這些定義(definitions),并將在集群上創(chuàng)建一些新的資源。要觀察這個(gè)過(guò)程,運(yùn)行:
- kubectl -n test get ev --watch
 
將創(chuàng)建一個(gè)名為 podinfo-primary 的新部署, 其副本數(shù)量與 podinfo 具有的副本數(shù)量相同 一旦新 Pod 準(zhǔn)備就緒,原始部署將縮減為零。這提供了由 Flagger 作為實(shí)現(xiàn)細(xì)節(jié)管理的部署,并維護(hù)您的原始配置文件和工作流。看到以下行后,一切都已設(shè)置:
- 0s Normal Synced canary/podinfo Initialization done! podinfo.test
 
除了托管部署之外,還創(chuàng)建了一些服務(wù)來(lái)協(xié)調(diào)應(yīng)用程序的新舊版本之間的路由流量。這些可以使用 kubectl -n test get svc 查看,應(yīng)該如下所示:
- NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
 - frontend ClusterIP 10.7.251.33 <none> 8080/TCP 96m
 - podinfo ClusterIP 10.7.252.86 <none> 9898/TCP 96m
 - podinfo-canary ClusterIP 10.7.245.17 <none> 9898/TCP 23m
 - podinfo-primary ClusterIP 10.7.249.63 <none> 9898/TCP 23m
 
此時(shí),拓?fù)淇雌饋?lái)有點(diǎn)像:
本指南沒(méi)有涉及 Flagger 提供的所有功能。如果您有興趣將 Canary 版本與 HPA 相結(jié)合、 處理自定義指標(biāo)或進(jìn)行其他類型的版本發(fā)布 (例如 A/B 測(cè)試),請(qǐng)務(wù)必閱讀文檔。
開(kāi)始推出(rollout)
作為一個(gè)系統(tǒng),Kubernetes resources 有兩個(gè)主要部分:spec 和 status。當(dāng)控制器看到 spec 時(shí),它會(huì)盡其所能使當(dāng)前系統(tǒng)的 status 與 spec 相匹配。通過(guò)部署,如果任何 pod 規(guī)范配置發(fā)生更改,控制器將啟動(dòng) rollout。默認(rèn)情況下,部署控制器(deployment controller)將協(xié)調(diào)滾動(dòng)更新(rolling update)。
在這個(gè)例子中,F(xiàn)lagger 會(huì)注意到部署的規(guī)范(spec)發(fā)生了變化, 并開(kāi)始編排金絲雀部署(canary rollout)。要啟動(dòng)此過(guò)程,您可以通過(guò)運(yùn)行以下命令將鏡像更新為新版本:
- kubectl -n test set image deployment/podinfo \
 - podinfod=quay.io/stefanprodan/podinfo:1.7.1
 
對(duì) pod 規(guī)范的任何修改(例如更新環(huán)境變量或annotation)都會(huì)導(dǎo)致與更新 image 相同的行為。
更新時(shí),金絲雀部署 (podinfo) 將擴(kuò)大(scaled up)。準(zhǔn)備就緒后,F(xiàn)lagger 將開(kāi)始逐步更新 TrafficSplit CRD。配置 stepWeight 為 10,每增加一次,podinfo 的權(quán)重就會(huì)增加 10。對(duì)于每個(gè)周期,都會(huì)觀察成功率,只要超過(guò) 99% 的閾值,F(xiàn)lagger 就會(huì)繼續(xù)推出(rollout)。要查看整個(gè)過(guò)程,請(qǐng)運(yùn)行:
- kubectl -n test get ev --watch
 
在發(fā)生更新時(shí),資源和流量在較高級(jí)別將如下所示:
更新完成后,這張圖會(huì)變回上一節(jié)的圖。
您可以在 1.7.1 和 1.7.0 之間切換 image 標(biāo)簽以再次開(kāi)始發(fā)布(rollout)。
Resource
canary resource 會(huì)更新當(dāng)前狀態(tài)和進(jìn)度,你可以通過(guò)運(yùn)行以下命令來(lái)查看:
- watch kubectl -n test get canary
 
在幕后,F(xiàn)lagger 正在通過(guò)更新流量拆分 resource 來(lái)拆分主后端和金絲雀后端之間的流量。要查看此配置在推出期間如何更改,請(qǐng)運(yùn)行:
- kubectl -n test get trafficsplit podinfo -o yaml
 
每次增加都會(huì)增加 podinfo-canary 的權(quán)重并減少 podinfo-primary 的權(quán)重。一旦部署成功,podinfo-primary 的權(quán)重將重新設(shè)置為 100, 并且底層金絲雀部署(podinfo)將被縮減。
指標(biāo)
隨著流量從主要部署轉(zhuǎn)移到金絲雀部署,Linkerd 提供了對(duì)請(qǐng)求目的地發(fā)生的事情的可見(jiàn)性。這些指標(biāo)顯示后端實(shí)時(shí)接收流量并衡量成功率(success rate)、延遲(latencies)和吞吐量(throughput)。在 CLI 中,您可以通過(guò)運(yùn)行以下命令來(lái)觀看:
- watch linkerd viz -n test stat deploy --from deploy/load
 
對(duì)于更直觀的東西,您可以使用儀表板。通過(guò)運(yùn)行 linkerd viz dashboard 啟動(dòng)它, 然后查看 podinfo 流量拆分的詳細(xì)信息頁(yè)面。
瀏覽器
再次訪問(wèn) http://localhost:8080。刷新頁(yè)面將顯示新版本和不同標(biāo)題顏色之間的切換?;蛘撸\(yùn)行 curl http://localhost:8080 將返回一個(gè) 類似于以下內(nèi)容的 JSON 響應(yīng):
- {
 - "hostname": "podinfo-primary-74459c7db8-lbtxf",
 - "version": "1.7.0",
 - "revision": "4fc593f42c7cd2e7319c83f6bfd3743c05523883",
 - "color": "blue",
 - "message": "greetings from podinfo v1.7.0",
 - "goos": "linux",
 - "goarch": "amd64",
 - "runtime": "go1.11.2",
 - "num_goroutine": "6",
 - "num_cpu": "8"
 - }
 
隨著推出的繼續(xù),這種 response 會(huì)慢慢改變。
清理
要進(jìn)行清理,請(qǐng)從集群中刪除 Flagger 控制器并通過(guò)運(yùn)行以下命令刪除 test 命名空間:
- kubectl delete -k github.com/fluxcd/flagger/kustomize/linkerd && \
 - kubectl delete ns test
 
【編輯推薦】




















 
 
 




 
 
 
 