昨天讓服務能夠在git commit推到master的branch下就立刻進行佈署,但是僅就這一些功能其實沒辦法突顯argo的優勢,所以今天會再進階的利用argo rollouts的功能讓佈屬更加行雲流水。
在開始之前要先知道一件事情,argocd 與 argo rollouts 兩個是不相依的,不用argocd 也可以使用argo rollouts,argo rollouts的用途是在於完成服務的漸進式佈署or藍綠佈署,那麼就來玩看看吧
安裝argo rollouts
kubectl create namespace argo-rollouts
kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml
安裝完成後,會發現多了很多關於argo 的crd可以使用,先來嘗試看看簡單的藍綠佈署,
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: app-name-rollouts
spec:
replicas: 1
revisionHistoryLimit: 2
workloadRef:
apiVersion: apps/v1
kind: Deployment
name: app-name
strategy:
blueGreen:
activeService: active-service
previewService: preview-preview
autoPromotionEnabled: false
基於這個做法,在app-name的deployment異動時,他會自動的做出一份preview的service,這時候可以搭配istio做流量轉送讓原本的服務正常運行,開發人員到preview的service驗證功能,如果沒有問題的話再promote讓服務更新,那麼要如何promote呢?
有兩種方法
透過argo rollouts的plugins 讓k8s具有kubectl argo rollouts promote的功能,這樣就可以kubectl argo rollouts promote app-name-rollouts -n ns,不過指令操作難免有些人不夠熟悉,所以其實也可以透過介面的方式達成。
介面也同樣的,可以透過kubectl argo rollouts dashboard的方式啟動,只是這樣就會佔用到3100 port 這個剛好是loki使用的(不過其實不影響),所以我選擇讓argo rollout dashboard 成為一個pod,官方提供了一個image quay.io/argoproj/kubectl-argo-rollouts:master ,把這個container包成deployment並且曝露出service,就可以輕易使用promote的功能囉。
argo rollouts其實也不僅是這樣,可以透過更進階一點的方式,讓服務透過prometheus自動發現自己的流量是否可以promote,接下來就來做個示例
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: app-name
spec:
replicas: 1
revisionHistoryLimit: 2
strategy:
canary:
analysis:
templates:
- templateName: service-check
startingStep: 2
args:
- name: service-name
value: svc-name.ns-name.svc.cluster.local
steps:
- setWeight: 20
- pause: {duration: 10}
- setWeight: 40
- pause: {duration: 10}
- setWeight: 60
- pause: {duration: 10}
- setWeight: 80
- pause: {duration: 10}
基於以上的rollouts yaml,會利用到另一個crd AnalysisTemplate,這個crd可以協助進行一些簡易的測試,像是從prometheus確認流量之類的,達成自動化的佈署。
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: service-check
spec:
args:
- name: service-name
metrics:
- name: success-rate
interval: 5m
successCondition: result[0] >= 0.95
failureLimit: 3
provider:
prometheus:
address: http://prometheus:9090
query: |
sum(irate(
istio_requests_total{reporter="source",destination_service=~"{{args.service-name}}",response_code!~"5.*"}[5m]
)) /
sum(irate(
istio_requests_total{reporter="source",destination_service=~"{{args.service-name}}"}[5m]
))
根據這個示例,就會配合rollouts的內容每10秒切換一次,如果istio request回應不足95%就會算失敗,自動化的完成佈署作業。