通過結合 Linkerd
和 Flagger
來根據服務指標自動金絲雀(canary
)釋出,從而降低部署風險。
Linkerd 2.10 中文手冊持續修正更新中:
Linkerd 2.10 系列
- 快速上手 Linkerd v2 Service Mesh(服務網格)
- 騰訊雲 K8S 叢集實戰 Service Mesh—Linkerd2 & Traefik2 部署 emojivoto 應用
- 詳細瞭解 Linkerd 2.10 基礎功能,一起步入 Service Mesh 微服務架構時代
- Linkerd 2.10(Step by Step)—1. 將您的服務新增到 Linkerd
Linkerd
的流量拆分(traffic split
)功能允許您在服務之間動態轉移流量。
這可用於實施低風險部署策略,如藍綠(blue-green
)部署和金絲雀(canaries
)。
但簡單地將流量從一個服務版本轉移到下一個版本只是一個開始。
我們可以將流量拆分與
Linkerd
的自動黃金指標(golden metrics
)遙測相結合,
並根據觀察到的指標推動流量決策。例如,我們可以逐漸將流量從舊部署轉移到新部署,
同時持續監控其成功率。如果在任何時候成功率下降,
我們可以將流量轉移回原始部署並退出釋出。
理想情況下,我們的使用者始終保持快樂(remain happy
),沒有注意到任何事情!
在本教程中,我們將引導您瞭解如何將 Linkerd
與
Flagger 結合使用,
後者是一種漸進式交付工具,
可將 Linkerd
的指標和流量拆分繫結在一個控制迴圈中,
從而實現全自動、指標感知的金絲雀部署。
先決條件
- 要使用本指南,您需要在叢集上安裝
Linkerd
及其Viz
擴充套件。
如果您還沒有這樣做,請按照安裝Linkerd
指南進行操作。 Flagger
的安裝依賴於kubectl
1.14 或更新版本。
安裝 Flagger
Linkerd
將管理實際的流量路由,
而 Flagger
會自動執行建立新 Kubernetes
資源(resources
)、
觀察指標(watching metrics
)和逐步將使用者傳送到新版本的過程。
要將 Flagger
新增到您的叢集並將其配置為與 Linkerd
一起使用,請執行:
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
可以配置釋出的方式。 RBAC
授予Flagger
修改它需要的所有資源的許可權,例如部署(deployments
)和服務(services
)。- 配置為與
Linkerd
控制平面互動的控制器。
要觀察直到一切正常執行,您可以使用 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
設定 demo
該 demo
由三個元件組成:負載生成器(load generator
)、部署(deployment
)和前端(frontend
)。
部署會建立一個 pod
,該 pod
會返回一些資訊,例如名稱。
您可以使用響應(responses)來觀察隨著 Flagger
編排的增量部署。
由於需要某種活動流量才能完成操作,因此負載生成器可以更輕鬆地執行部署。
這些元件的拓撲結構如下所示:
要將這些元件新增到您的叢集並將它們包含在 Linkerd
資料平面中,請執行:
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
通過執行以下命令驗證一切是否已成功啟動:
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
通過在本地轉發前端服務並通過執行在本地的
http://localhost:8080 來開啟檢查它:
kubectl -n test port-forward svc/frontend 8080
我這裡,為方便看到真實的一個 demo,直接加個 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
你可以直接訪問 https://podinfo.hacker-linner.com。
流量轉移發生在連線的客戶端而不是伺服器端。
來自網格外部的任何請求都不會被轉移,並且將始終被定向到主後端。
LoadBalancer
型別的服務將表現出這種行為,因為源不是網格的一部分。
要轉移外部流量,請將入口控制器新增到網格中。
配置釋出
在更改任何內容之前,您需要配置釋出應如何在叢集上推出(rolled out)。
該配置包含在
Canary
定義中。要應用於您的叢集,請執行:
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 控制器正在監視這些定義(definitions),並將在叢集上建立一些新的資源。
要觀察這個過程,執行:
kubectl -n test get ev --watch
將建立一個名為 podinfo-primary
的新部署,
其副本數量與 podinfo
具有的副本數量相同
一旦新 Pod 準備就緒,原始部署將縮減為零。
這提供了由 Flagger 作為實現細節管理的部署,並維護您的原始配置檔案和工作流。
看到以下行後,一切都已設定:
0s Normal Synced canary/podinfo Initialization done! podinfo.test
除了託管部署之外,還建立了一些服務來協調應用程式的新舊版本之間的路由流量。
這些可以使用 kubectl -n test get svc
檢視,應該如下所示:
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
此時,拓撲看起來有點像:
本指南沒有涉及 Flagger 提供的所有功能。
如果您有興趣將 Canary 版本與 HPA 相結合、
處理自定義指標或進行其他型別的版本釋出
(例如 A/B 測試),請務必閱讀文件。
開始推出(rollout)
作為一個系統,Kubernetes resources 有兩個主要部分:spec 和 status。
當控制器看到 spec 時,它會盡其所能使當前系統的 status 與 spec 相匹配。
通過部署,如果任何 pod 規範配置發生更改,控制器將啟動 rollout。
預設情況下,部署控制器(deployment controller)將協調滾動更新(rolling
update)。
在這個例子中,Flagger 會注意到部署的規範(spec)發生了變化,
並開始編排金絲雀部署(canary rollout)。
要啟動此過程,您可以通過執行以下命令將映象更新為新版本:
kubectl -n test set image deployment/podinfo \
podinfod=quay.io/stefanprodan/podinfo:1.7.1
對 pod 規範的任何修改(例如更新環境變數或annotation)都會導致與更新 image 相同的行為。
更新時,金絲雀部署 (podinfo
) 將擴大(scaled up)。
準備就緒後,Flagger 將開始逐步更新 TrafficSplit CRD。
配置 stepWeight 為 10,每增加一次,podinfo
的權重就會增加 10。
對於每個週期,都會觀察成功率,只要超過 99% 的閾值,Flagger 就會繼續推出(rollout)。
要檢視整個過程,請執行:
kubectl -n test get ev --watch
在發生更新時,資源和流量在較高階別將如下所示:
更新完成後,這張圖會變回上一節的圖。
您可以在 1.7.1
和 1.7.0
之間切換 image 標籤以再次開始釋出(rollout)。
Resource
canary resource 會更新當前狀態和進度,你可以通過執行以下命令來檢視:
watch kubectl -n test get canary
在幕後,Flagger 正在通過更新流量拆分 resource 來拆分主後端和金絲雀後端之間的流量。
要檢視此配置在推出期間如何更改,請執行:
kubectl -n test get trafficsplit podinfo -o yaml
每次增加都會增加 podinfo-canary
的權重並減少 podinfo-primary
的權重。
一旦部署成功,podinfo-primary
的權重將重新設定為 100,
並且底層金絲雀部署(podinfo
)將被縮減。
指標
隨著流量從主要部署轉移到金絲雀部署,Linkerd 提供了對請求目的地發生的事情的可見性。
這些指標顯示後端實時接收流量並衡量成功率(success rate
)、延遲(latencies
)和吞吐量(throughput
)。
在 CLI 中,您可以通過執行以下命令來觀看:
watch linkerd viz -n test stat deploy --from deploy/load
對於更直觀的東西,您可以使用儀表板。
通過執行 linkerd viz dashboard
啟動它,
然後檢視 podinfo 流量拆分的詳細資訊頁面。
瀏覽器
再次訪問 http://localhost:8080。
重新整理頁面將顯示新版本和不同標題顏色之間的切換。
或者,執行 curl http://localhost:8080
將返回一個
類似於以下內容的 JSON 響應:
{
"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"
}
隨著推出的繼續,這種 response
會慢慢改變。
清理
要進行清理,請從叢集中刪除 Flagger
控制器並通過執行以下命令刪除 test
名稱空間:
kubectl delete -k github.com/fluxcd/flagger/kustomize/linkerd && \
kubectl delete ns test
我是為少
微信:uuhells123
公眾號:黑客下午茶
加我微信(互相學習交流),關注公眾號(獲取更多學習資料~)