基于阿里云托管服務網格ASM完成應用全自動化漸進式發布的GitOps解決方案實踐-阿里云開發者社區

開發者社區> 阿里云容器服務 ACK> 正文

基于阿里云托管服務網格ASM完成應用全自動化漸進式發布的GitOps解決方案實踐

簡介: 本文是基于阿里云托管服務網格 ASM 完成應用在多集群環境中全自動化漸進式發布的 GitOps 實踐。

簡介

ASM

ASM當前處于公測階段,歡迎掃碼入群進一步交流:
dingding.png

阿里云服務網格(Alibaba Cloud Service Mesh,簡稱 )提供了一個全托管式的服務網格平臺,兼容于社區 Istio 開源服務網格,用于簡化服務的治理,包括服務調用之間的流量路由與拆分管理、服務間通信的認證安全以及網格可觀測性能力,從而極大地減輕開發與運維的工作負擔。ASM的架構示意圖如下:
asm_arch.png
ASM 定位于混合云、多云、多集群、非容器應用遷移等核心場景中,構建托管式統一的服務網格能力,能夠為阿里云用戶提供以下功能:

  • 一致的管理方式
    以一致的方式來管理運行于 ACK 托管 Kubernetes 集群、專有 Kubernetes 集群、ServerlessKubernetes 集群、混合云或多云場景下的接入集群上的應用服務,從而提供一致的可觀測性和流量控制
  • 統一的流量管理
    支持容器或者虛擬機混合環境下統一的流量管理
  • 控制平面核心組件托管化
    托管控制平面的核心組件,最大限度地降低用戶資源開銷和運維成本

ArgoCD

是一個用于持續交付的Kubernetes配置管理工具。Argo CD 遵循 GitOps 模式,監聽當前運行中應用的狀態并與Git Repository中聲明的狀態進行比對,并自動將更新部署到環境中。ArgoCD的架構示意圖如下:
argocd-arch.png

Flagger

是一個用于全自動化漸進式完成應用發布的Kubernetes operator可以领救济金的游戏,它通過分析Prometheus收集到的監控指標并通過Istio、App Mesh等流量管理技術或工具完成應用的漸進式發布。架構示意圖如下:
flagger-arch.png

創建ASM實例

參考ASM創建ASM實例并添加mesh01和mesh02 2個ACK集群:
asm-instance.png

部署入口網關服務到mesh01集群:
ingressgateway.png
ingressgateway.png

在控制平面創建一個命名空間test:
asm-controllpanel.png

在控制平面創建一個Gateway:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: public-gateway
  namespace: istio-system
spec:
  selector:
    istio: ingressgateway
  servers:
    - port:
        number: 80
        name: http
        protocol: HTTP
      hosts:
        - "*"

asm-gateway.png
asm-gateway.png

部署Flagger

分別在mesh1和mesh2 2個ACK集群上按照以下步驟部署Flagger及其依賴組件:

部署Prometheus

$ kubectl apply -k github.com/haoshuwei/argocd-samples/flagger/prometheus/

部署Flagger

使用ASM實例的kubeconfig創建secret:

$ kubectl -n istio-system create secret generic istio-kubeconfig --from-file kubeconfig
$ kubectl -n istio-system label secret istio-kubeconfig  istio/multiCluster=true

helm安裝Flagger:

$ helm repo add flagger https://flagger.app
$ helm repo update
$ kubectl apply -f https://raw.githubusercontent.com/weaveworks/flagger/master/artifacts/flagger/crd.yaml
$ helm upgrade -i flagger flagger/flagger --namespace=istio-system --set crd.create=false --set meshProvider=istio --set metricsServer=http://prometheus:9090 --set istio.kubeconfig.secretName=istio-kubeconfig --set istio.kubeconfig.key=kubeconfig

部署Grafana

$ helm upgrade -i flagger-grafana flagger/grafana --namespace=istio-system --set url=http://prometheus:9090

我們可以在ASM實例的控制面板上創建grafana服務的虛擬服務來供外部訪問:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: grafana
  namespace: istio-system
spec:
  hosts:
    - "grafana.istio.example.com"
  gateways:
    - public-gateway.istio-system.svc.cluster.local
  http:
    - route:
        - destination:
            host: flagger-grafana

grafana-gateway.png

訪問服務:
grafana-view.png

創建命名空間并添加標簽

$ kubectl create ns test
$ kubectl label namespace test istio-injection=enabled

部署ArgoCD

我們可以選擇任意一個ACK集群部署ArgoCD
部署ArgoCD Server:

$ kubectl create namespace argocd
$ kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

部署ArgoCD CLI:

$ VERSION=$(curl --silent "https://api.github.com/repos/argoproj/argo-cd/releases/latest" | grep '"tag_name"' | sed -E 's/.*"([^"]+)".*/\1/')
$ curl -sSL -o /usr/local/bin/argocd https://github.com/argoproj/argo-cd/releases/download/$VERSION/argocd-linux-amd64
$ chmod +x /usr/local/bin/argocd

獲取和修改登錄密碼:

$ kubectl get pods -n argocd -l app.kubernetes.io/name=argocd-server -o name | cut -d'/' -f 2
$ argocd login ip:port
$ argocd account update-password

訪問服務:
argocd-view.png

完成應用全自動化漸進式發布的GitOps流程示例

ArgoCD添加集群并部署應用

在這個示例中可以领救济金的游戏,我們將會把示例應用podinfo部署到mesh02集群,把loadtester測試應用部署到mesh01集群,統一部署在test命名空間下。
添加Git Repository 到ArgoCD:

$ argocd repo add https://github.com/haoshuwei/argocd-samples.git--name argocd-samples
repository 'https://github.com/haoshuwei/argocd-samples.git' added
$ argocd repo list
TYPE  NAME         REPO                                          INSECURE  LFS    CREDS  STATUS      MESSAGE
git   argocd-samples  https://github.com/haoshuwei/argocd-samples.git  false     false  false  Successful

使用kubeconfig添加mesh01和mesh02 2個集群到ArgoCD:

$ argocd cluster add mesh01 --kubeconfig=mesh01
INFO[0000] ServiceAccount "argocd-manager" created in namespace "kube-system"
INFO[0000] ClusterRole "argocd-manager-role" created
INFO[0000] ClusterRoleBinding "argocd-manager-role-binding" created
$ argocd cluster add mesh02 --kubeconfig=mesh02
INFO[0000] ServiceAccount "argocd-manager" created in namespace "kube-system"
INFO[0000] ClusterRole "argocd-manager-role" created
INFO[0000] ClusterRoleBinding "argocd-manager-role-binding" created
$ argocd cluster list |grep mesh
https://xx.xx.xxx.xx:6443       mesh02   1.16+    Successful
https://xx.xxx.xxx.xx:6443      mesh01   1.16+    Successful

部署應用podinfomesh02集群:

$ argocd app create --project default --name podinfo --repo https://github.com/haoshuwei/argocd-samples.git --path flagger/podinfo --dest-server https://xx.xx.xxx.xx:6443 --dest-namespace test --revision latest --sync-policy automated

以上命令行做的事情是創建一個應用podinfo,這個應用的Git Repository源是https://github.com/haoshuwei/gitops-demo.git 項目flagger/podinfo子目錄下的文件,分支為latest,應用部署到https://xx.xx.xxx.xx:6443集群的test命名空間下,應用的同步策略是automated

flagger/podinfo 子目錄下包括4個編排文件deployment.yaml hpa.yaml kustomization.yamlcanary.yaml,其中canary.yaml文件就是我們這個示例中完成應用全自動化漸進式金絲雀發布的核心編排文件,內容如下:

apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
  name: podinfo
  namespace: test
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: podinfo
  progressDeadlineSeconds: 60
  autoscalerRef:
    apiVersion: autoscaling/v2beta1
    kind: HorizontalPodAutoscaler
    name: podinfo
  service:
    port: 9898
    gateways:
    - public-gateway.istio-system.svc.cluster.local
    hosts:
    - app.istio.example.com
    trafficPolicy:
      tls:
        # use ISTIO_MUTUAL when mTLS is enabled
        mode: DISABLE
  analysis:
    interval: 30s
    threshold: 10
    maxWeight: 50
    stepWeight: 5
    metrics:
    - name: request-success-rate
      threshold: 99
      interval: 30s
    - name: request-duration
      threshold: 500
      interval: 30s
    webhooks:
      - name: load-test
        url: http://loadtester.test/
        timeout: 5s
        metadata:
          cmd: "hey -z 1m -q 10 -c 2 http://podinfo-canary.test:9898/"

canary.yaml文件中定義了以下幾個關鍵部分

spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: podinfo
  progressDeadlineSeconds: 60
  autoscalerRef:
    apiVersion: autoscaling/v2beta1
    kind: HorizontalPodAutoscaler
    name: podinfo

以上字段表示這個canary資源會監聽和引用名為podinfo的deployments資源和HorizontalPodAutoscaler資源。

service:
    port: 9898
    gateways:
    - public-gateway.istio-system.svc.cluster.local
    hosts:
    - app.istio.example.com
    trafficPolicy:
      tls:
        # use ISTIO_MUTUAL when mTLS is enabled
        mode: DISABLE

以上字段表示canary資源會在ASM控制面板自動為podinfo應用創建虛擬服務,名字也是podinfo

analysis:
    interval: 30s
    threshold: 5
    maxWeight: 50
    stepWeight: 5
    metrics:
    - name: request-success-rate
      threshold: 99
      interval: 30s
    - name: request-duration
      threshold: 500
      interval: 30s
    webhooks:
      - name: load-test
        url: http://loadtester.test/
        timeout: 5s
        metadata:
          cmd: "hey -z 1m -q 10 -c 2 http://podinfo-canary.test:9898/"

以上字段表示我們在發布新版本podinfo應用時,要先對新版本應用做一些測試和分析,
interval: 30s, 每隔30s測試一次
threshold: 5, 失敗次數超過5次則認為失敗
maxWeight: 50, 流量權重最大可以切換到50
stepWeight: 5, 每次增加權重為5
metrics中定義了2種指標,
request-success-rate 請求成功率不能小于99
request-duration RT均值不能大于500ms
用來生成測試任務的則定義在webhooks字段。

部署測試應用loadtestermesh01集群:

$ argocd app create --project default --name loadtester --repo https://github.com/haoshuwei/argocd-samples.git --path flagger/charts/loadtester --dest-server https://xx.xxx.xxx.xx:6443 --dest-namespace test --revision latest --sync-policy automated

以上應用創建完成后,由于我們設置的sync策略為自動部署,所以應用會自動部署到mesh01和mesh02集群中,我們可以在ArgoCD頁面上查看應用詳細信息:
argocd-app.png
podinfo詳情:
podinfo.png
loadtester詳情:
loadtester.png

在ASM的控制面板我們可以查看flagger動態創建的虛擬服務和目標規則:
podinfo-vs.png
podinfo-rules.png

訪問服務:
podinfo-view.png

GitOps自動發布

新建分支修改應用容器鏡像版本提交,并創建指向latest分支的PullRequest:
github-pr.png

管理員審批并merge pr后,latest分支有新代碼進入,ArgoCD會自動把更新同步集群環境中,flagger檢測到podinfo應用有新版本變更,則開始自動化漸進式地發布新版本應用可以领救济金的游戏,通過以下命令可以查看應用發布進度:

$ watch kubectl get canaries --all-namespaces
Every 2.0s: kubectl get canaries --all-namespaces                                                                                                         Tue Mar 17 19:04:20 2020
NAMESPACE   NAME      STATUS        WEIGHT   LASTTRANSITIONTIME
test        podinfo   Progressing   10       2020-03-17T11:04:01Z

訪問應用可以看到有流量切換到新版本上:
podinfo.png

同時我們也可以在grafana面板中查看到新版本測試指標情況:
grafana.png

整個發布過程的messages輸出如下:

"msg":"New revision detected! Scaling up podinfo.test","canary":"podinfo.test"
"msg":"Starting canary analysis for podinfo.test","canary":"podinfo.test"
"msg":"Advance podinfo.test canary weight 5","canary":"podinfo.test"
"msg":"Advance podinfo.test canary weight 10","canary":"podinfo.test"
"msg":"Advance podinfo.test canary weight 15","canary":"podinfo.test"
"msg":"Advance podinfo.test canary weight 20","canary":"podinfo.test"
"msg":"Advance podinfo.test canary weight 25","canary":"podinfo.test"
"msg":"Advance podinfo.test canary weight 30","canary":"podinfo.test"
"msg":"Advance podinfo.test canary weight 35","canary":"podinfo.test"
"msg":"Advance podinfo.test canary weight 40","canary":"podinfo.test"
"msg":"Advance podinfo.test canary weight 45","canary":"podinfo.test"
"msg":"Advance podinfo.test canary weight 50","canary":"podinfo.test"
"msg":"Copying podinfo.test template spec to podinfo-primary.test","canary":"podinfo.test"
"msg":"Halt advancement podinfo-primary.test waiting for rollout to finish: 3 of 4 updated replicas are available","canary":"podinfo.test"
"msg":"Routing all traffic to primary","canary":"podinfo.test"
"msg":"Promotion completed! Scaling down podinfo.test","canary":"podinfo.test"

應用發布完畢后,所有流量切換到新版本上:
podinfo.png

若新版本應用測試指標不達標,則應用自動回滾到初始穩定狀態:

"msg":"New revision detected! Scaling up podinfo.test","canary":"podinfo.test"
"msg":"Starting canary analysis for podinfo.test","canary":"podinfo.test"
"msg":"Advance podinfo.test canary weight 10","canary":"podinfo.test"
"msg":"Halt advancement no values found for istio metric request-success-rate probably podinfo.test is not receiving traffic","canary":"podinfo.test"
"msg":"Halt advancement no values found for istio metric request-duration probably podinfo.test is not receiving traffic","canary":"podinfo.test"
"msg":"Halt advancement no values found for istio metric request-duration probably podinfo.test is not receiving traffic","canary":"podinfo.test"
"msg":"Halt advancement no values found for istio metric request-duration probably podinfo.test is not receiving traffic","canary":"podinfo.test"
"msg":"Halt advancement no values found for istio metric request-duration probably podinfo.test is not receiving traffic","canary":"podinfo.test"
"msg":"Synced test/podinfo"
"msg":"Rolling back podinfo.test failed checks threshold reached 5","canary":"podinfo.test"
"msg":"Canary failed! Scaling down podinfo.test","canary":"podinfo.test"

參考資料





[](

版權聲明:本文中所有內容均屬于阿里云開發者社區所有,任何媒體、網站或個人未經阿里云開發者社區協議授權不得轉載、鏈接、轉貼或以其他方式復制發布/發表。申請授權請郵件developerteam@list.alibaba-inc.com,已獲得阿里云開發者社區協議授權的媒體、網站,在轉載使用時必須注明"稿件來源:阿里云開發者社區,原文作者姓名",違者本社區將依法追究責任。 如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至:developer2020@service.aliyun.com 進行舉報,并提供相關證據,一經查實,本社區將立刻刪除涉嫌侵權內容。

分享:
阿里云容器服務 ACK
使用釘釘掃一掃加入圈子
+ 訂閱

云端最佳容器應用運行環境,安全、穩定、極致彈性

官方博客
官網鏈接
  • 官網:
  • 控制臺: