Pages - Menu

2021年4月5日 星期一

[istio]flagger 自動金絲雀佈署 for istio 1.8.2

前言

本來自動佈署配上istio都好了,
但在實際上測試的時候發現,如果不導入自動藍綠佈署或金絲雀佈署的話,
到時開發人員發佈程式時,需要更改istio 的 VirtualService 以及 DestinationRule。
除非發佈的人懂這些東西,不然…改壞就…,所以只好先研究flagger了。減少開發人員佈署的know how,
只要git tag ,然後『等』 就好了。


正文

  1. 簡易流程介紹

目前正在執行的deploy 為abc-primary ,當有新的deploy 佈署在 abc 時,flagger啟動,
先將流量從 abc-primary 轉到 abc ,因為abc 為新版本。
當流量全部轉到abc後,將 abc-primary 刪除,並佈署成新的版本。
當abc-primary佈署完後,再將 流量從 abc 轉回 abc-primary,
等待全部流量轉回來後,再將abc的deploy刪除。

  1. 先安裝flagger

  kustomize build https://github.com/fluxcd/flagger/kustomize/istio?ref=main | kubectl apply -f -

ref. Flagger Install on Kubernetes

  1. 佈署負載測試服務 flagger-loadtester

如果namespace要先建立test ,如果不想使用這個名稱,請下載yaml檔後修改 kustomization.yaml 的namespace

flagger-loadtester

  kubectl apply -k https://github.com/fluxcd/flagger//kustomize/tester?ref=main

這裏面主要是使用hey 作爲連線測試的工具,
在後面的webhook會用到此服務。

  1. 設定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

  1. 引入 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

  1. 佈署失敗,重新佈署方式

藍綠佈署或金絲雀佈署上面有提到,會自動新增一個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

  1. 佈署失敗原因

目前測試,每次一定會跳這個出來。差別只在次數
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

  1. 監控方式

  • 查詢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

  1. 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入門系列之自動化灰度發佈

沒有留言:

張貼留言