前言
本來自動佈署配上istio都好了,
但在實際上測試的時候發現,如果不導入自動藍綠佈署或金絲雀佈署的話,
到時開發人員發佈程式時,需要更改istio 的 VirtualService 以及
DestinationRule。
除非發佈的人懂這些東西,不然…改壞就…,所以只好先研究flagger了。減少開發人員佈署的know
how,
只要git tag ,然後『等』 就好了。
正文
-
簡易流程介紹
目前正在執行的deploy 為abc-primary ,當有新的deploy 佈署在 abc
時,flagger啟動,
先將流量從 abc-primary 轉到 abc ,因為abc 為新版本。
當流量全部轉到abc後,將 abc-primary 刪除,並佈署成新的版本。
當abc-primary佈署完後,再將 流量從 abc 轉回 abc-primary,
等待全部流量轉回來後,再將abc的deploy刪除。
-
先安裝flagger
kustomize build https://github.com/fluxcd/flagger/kustomize/istio?ref=main | kubectl apply -f -
ref. Flagger Install on Kubernetes
-
佈署負載測試服務 flagger-loadtester
如果namespace要先建立test ,如果不想使用這個名稱,請下載yaml檔後修改
kustomization.yaml 的namespace kubectl apply -k https://github.com/fluxcd/flagger//kustomize/tester?ref=main
這裏面主要是使用hey
作爲連線測試的工具,
在後面的webhook會用到此服務。
-
設定Canary
此範例為AB佈署,另有金絲雀佈署,請參考
spec 底下的參數,
- targetRef.name 是
deploy會截取現有的deploy設定,確認名稱與現有的deploy名稱一樣
- autoscalerRef.name 是
HPA會截取現有的HPA設定,確認名稱與現有的HPA名稱一樣。
- service.name是
service會截取現有的service設定,確認名稱與現有的service名稱一樣。
- service.host 需指定目前服務的domain,如果為ip只能有一組
- webhooks.metadata.cmd ,網址必須更改成服務能夠訪問的網址。
apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
name: video
namespace: sex-system
spec:
provider: istio
targetRef:
apiVersion: apps/v1
kind: Deployment
name: video-api
autoscalerRef:
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
name: video-api
service:
name: video-api
port: 80
targetPort: 80
portName: http
portDiscovery: true
gateways:
- istio-gateway-external.istio-system.svc.cluster.local
- istio-gateway-internal.istio-system.svc.cluster.local
- mesh
hosts:
- 123.123.123.123
trafficPolicy:
tls:
mode: DISABLE
match:
- uri:
prefix: /
rewrite:
uri: /
timeout: 30s
analysis:
# analysis spend time : interval * iterations
# 時間間隔 (默認 60s)
interval: 30s
# 回滾前的最大失敗指標檢查次數(可能因為檢查時間差的關係,至少會有兩次失敗)
threshold: 5
iterations: 1
metrics:
- name: request-success-rate
thresholdRange:
min: 99
interval: 1m
- name: request-duration
thresholdRange:
max: 500
interval: 30s
webhooks:
- name: load-test
type: rollout
url: http://flagger-loadtester.tools/
timeout: 5s
metadata:
type: cmd
cmd: "hey -z 1m -q 10 http://video-api-canary.test/api/v1/Health/health"
寫好canary,然後直接佈署。
此時,k8s會根據你的設定,建立起 一些相關的service以及 deployment ,
例如,本來的deployment、service以及 hpa的 名稱叫 abc ,
那同時會建立 abc-primary 的deployment 跟 hpa,
以及 abc-canary 、 abc-primary 的 service 。
然後再istio上面也會自動建立 VirtualService 跟 DestinationRule
所以Canary很重要、很重要、很重要。
ref.
flagger/artifacts/examples/istio-canary.yaml
Istio Canary Deployments
Istio A/B Testing
-
引入 grafana
因為istio本身就有grafana了,所以我不想重複安裝,
到他們的git
將json檔下載下來,
到grafana匯入json(fig.1),
(fig.1)
此時會發生錯誤
Template variables could not be initialized: Datasource named prometheus was not found
原因是原本的json檔裡面的datasource是 prometheus
而目前安裝的是 Promethus ,將本來的json更改後再匯入。
ref.
Flagger - Monitor Your Canary Deployments with Grafana
-
佈署失敗,重新佈署方式
藍綠佈署或金絲雀佈署上面有提到,會自動新增一個deployment,再原有的名稱上面加上-primary,
然後原有的deployment還會存在,但他的pod會清除。
當有新的image時,會觸發動作,在原有的deployment上將pod產生出來,
然後開始做流量的導轉,並發佈新版本。
但在測試的時候,如果canary寫錯了,會導致發佈失敗。
此時修改完,重新apply ,也會卡在Fail的狀態,
需到 原本的deployment 增加 下面的程式,
讓canary重新觸發。
apiVersion: apps/v1
kind: Deployment
spec:
template:
metadata:
annotations:
timestamp: "2020-03-10T14:24:48+0000"
ref. How to retry a failed release
-
佈署失敗原因
目前測試,每次一定會跳這個出來。差別只在次數
Halt advancement no values found for istio metric request-success-rate
probably video-api.sex-system is not receiving traffic: running query failed:
no values found
用curl打 不會產生此錯誤,
interval 時間壓在30s ,此錯誤只會發生1次
interval 時間壓在20s ,此錯誤會發生2次
threshold:回滾最大錯誤發生次數,設成5,只要小於錯誤發生的次數,還是可以成功自動佈署
有查到會發生這個錯誤的原因,如果在流量導轉期間沒有收到流量的話就會發生此錯誤。
ref.Load Testing
-
監控方式
- 查詢flagger佈署狀態,需額外安裝jq(解析json的軟體)
watch "kubectl -n istio-system logs deployment/flagger --tail=10 | jq '.ts,.msg'"
或
kubectl -n test describe canary/video-api | tail -20f
- 看流量比重
watch kubectl get canaries -A
-
webhook主動通知
在flagger裡面,有實作webhook,可以將事件的狀態通知給需要的人。
內建有 slack 、discord , 這段我沒實作 ,看起來只要加參數即可,
請參考 Alerting
但因為公司政策,我不能用slack所以只好自己做telegram了,
telegram做機器人還挺快的,改天再寫一篇關於telegram的使用方式。
webhooks:
- name: "notify"
type: event
url: http://webhook-api-v2.test/webhook/flagger
timeout: 5s
metadata:
some: "some message"
在canary上面加入上面的程式碼,然後當有事件觸發時,
會回傳下面的json格式。
注意 webhook-api-v2.test 是一個我自己建立在 namespce :test ,deployment:webhook-api-v2 的api
webhook其實就是自己建立一個api的接收機制,當server端有資料時,
會根據上面的url送出json給你,此時要怎麼利用,就看各自的需求了。
{
"name":"video",
"namespace":"test",
"phase":"Failed",
"metadata":{
"eventMessage":"Canary failed! Scaling down abc.test",
"eventType":"Warning",
"some":"some message",
"timestamp":"1616654792750"
}
}
ref.
webhook 是什麼以及如何創建
LINE Bot 系列文 — 什麼是 Webhook?
結論
有時文章測試有問題的話,建議到他們的git
找相關的範例,做測試。
ref.
基於Flagger和Istio實現自動化金絲雀部署
Istio 實踐
Service Mesh - Istio實戰篇(上)
Automated canary deployments with Flagger and Istio
istio入門系列之自動化灰度發佈
0 意見:
張貼留言