ACK One GitOps可實現多叢集GitOps應用的持續傳遞,Container RegistryACR支援綁定業務代碼倉庫,以實現應用的持續整合。本實踐基於這兩者構建開發(Dev)、預發(Staging)、生產(Production)叢集的CI/CD流水線,實現代碼修改提交到代碼倉庫後,自動將最新鏡像更新至應用,並將最新鏡像部署到各環境中。
使用限制
僅適用於通過ACK One GitOps系統建立的應用。
僅適用於通過Kustomize或Helm編排渲染託管在Git系統中的應用編排。
前提條件
已開啟艦隊管理功能。
已從ACK One控制台擷取Fleet執行個體的KubeConfig,並通過kubectl串連至Fleet執行個體。
已在ACK One Fleet執行個體中開啟GitOps功能。具體操作,請參見登入GitOps系統。
已通過ArgoCD下載安裝最新版本的ArgoCD CLI。
流程概述
本實踐基於ACK One GitOps和ACR來構建開發(Dev)、預發(Staging)、生產(Production)叢集的CI/CD流水線,實現代碼修改提交到Git倉庫後,自動將最新鏡像更新至應用,並按以下方式部署最新鏡像到各環境中。
Dev叢集:應用自動同步,部署最新鏡像。
Staging、Produciton叢集:應用手動同步,並基於Rollout灰階發布,部署最新鏡像。
準備業務倉庫代碼倉庫和應用部署代碼倉庫。
開啟和登入ACK One GitOps後,營運團隊首先配置CI構建流程和規則,並關聯ACR EE執行個體。
Team Dev將程式碼推送到代碼倉庫中,觸發ACR EE構建鏡像,並將新版本的鏡像推送到ACR EE鏡像倉庫中。
鏡像倉庫的變更會被ACK One GitOps檢測到,然後,ACK One GitOps將新的鏡像版本號碼回寫到應用部署代碼倉庫中。
ACK One GitOps檢測到應用部署代碼倉庫中鏡像版本號碼的變化後,觸發Application將最新鏡像部署到持續整合開發叢集(Dev)。
對於配置了自動同步Application的持續整合測試叢集,ACK One GitOps會自動變更應用的鏡像版本。
Image Updater會監測鏡像倉庫中符合配置規則的鏡像的更新。
ArgoCD會監測應用部署倉庫中YAML的變化。
在完成持續部署之後,Team Dev驗證Dev環境中的應用是否符合預期。
Dev環境驗證符合預期後,由營運團隊手動觸發預發(Staging)和生產(Production)環境的應用同步,並使用Argo Rollout或Kruise Rollout實現灰階發布,最終更新預發和生產環境中應用的鏡像。更多資訊,請參見基於ACK One Gitops使用Argo Rollouts實現金絲雀發布、基於ACK One Gitops使用Kruise Rollout實現金絲雀發布。
重要預發(Staging)和生產(Production)叢集一般需要通過額外的發布流程來做多叢集多地區的滾動發布,不能通過代碼變更直接影響到預發和生產環境。
樣本說明
本文的應用樣本為echo-server樣本,業務代碼倉庫包含2個,分別從echo-server專案和echo-web-server專案分支得到;應用部署代碼倉庫是Fork的gitops-demo專案。由於涉及到將應用變更回寫到應用部署代碼倉庫,所以您首先需要將該倉庫Fork到您自己的帳號下,並可根據個人情況修改配置,例如不同環境對應的values.yaml中的image.repository和image.tag。關於本實踐的最終改動,請參見echo-server example。
image:
repository: registry.cn-hangzhou.aliyuncs.com/haoshuwei24/echo-server
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
tag: "v1.0"步驟一:基於ACR構建CI
建立ACR鏡像倉庫,綁定您Fork的echo-server專案,並設定構建規則。具體配置操作請參見使用企業版執行個體構建鏡像。您可以在企業版執行個體的概覽頁開啟公開匿名拉取或參見使用免密組件拉取容器鏡像來免密拉取鏡像。
如果您使用的代碼源是Github,並且遇到了拉取代碼逾時的問題,可開啟海外機器構建來嘗試解決問題。
本實踐ACR配置的規則如下:檢測到有新的release-開頭的Tag,ACR就會自動Build docker image並Push到相應的鏡像倉庫。規則中Regex您可按需設定。

步驟二:為GitOps配置ACR鏡像倉庫和應用部署倉庫憑證
ACK One GitOps組件會自動監聽ACR鏡像倉庫的變化,並拉取最新鏡像,同時會將最新鏡像Tag資訊回寫到Git倉庫中,更新應用。您通過為GitOps配置相應的訪問憑證,可實現與ACR、Git倉庫的互動。
串連和訪問GitOps系統。具體操作,請參見登入GitOps系統。
添加Git源倉庫。具體操作,請參見添加倉庫。
建立GitOps應用。具體操作,請參見Application管理。
配置ACR鏡像倉庫訪問憑證,以使GitOps監聽ACR鏡像變化。
執行以下命令,在ACK One Fleet執行個體的argocd命名空間下配置名為acr的Secret資源。
kubectl -n argocd apply -f - <<EOF apiVersion: v1 kind: Secret metadata: name: acr type: Opaque stringData: acr: <your_username>:<your_password> # 將<your_username>:<your_password>更換為您自己的容器鏡像倉庫訪問憑證。 EOF配置Git倉庫訪問憑證,以使GitOps回寫應用鏡像變更資訊到Git倉庫。
若您在GitOps系統中添加Git倉庫時,配置了使用者名稱和密碼或配置了私密金鑰認證,則使用該Git倉庫的應用預設擁有回寫應用程式容器鏡像變更資訊到Git系統的許可權。
添加Git倉庫時,已配置使用者名稱和密碼、私密金鑰認證(包含使用SSH私密金鑰添加的Repo)
您可以通過添加以下Annotation,配置使用該Git倉庫的訪問憑證:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
annotations:
argocd-image-updater.argoproj.io/write-back-method: git添加Git倉庫時,未配置使用者名稱和密碼、私密金鑰認證
您可以通過添加以下Annotation,配置使用該Git倉庫的訪問憑證:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
annotations:
argocd-image-updater.argoproj.io/write-back-method: git:secret:argocd/git-creds其中git:secret:argocd/git-creds表示argocd命名空間下名為git-creds的Secret資源,建立該Secret的樣本如下所示:
kubectl -n argocd create secret generic git-creds \
--from-literal=username=<your_username> \
--from-literal=password=<your_password>步驟三:配置應用的自動更新並多個叢集部署應用
應用的自動更新配置可以通過在Application上添加以下Annotations實現,更多配置資訊請參見更多應用鏡像自動更新的相關配置。
metadata:
annotations:
argocd-image-updater.argoproj.io/image-list: echoserver=demo-test-registry.cn-hangzhou.cr.aliyuncs.com/cidemo/echo-server,webserver=demo-test-registry.cn-hangzhou.cr.aliyuncs.com/cidemo/echo-web-server
argocd-image-updater.argoproj.io/echoserver.helm.image-name: image.echoServer.repository
argocd-image-updater.argoproj.io/echoserver.helm.image-tag: image.echoServer.tag
argocd-image-updater.argoproj.io/echoserver.update-strategy: latest
argocd-image-updater.argoproj.io/webserver.helm.image-name: image.echoWebServer.repository
argocd-image-updater.argoproj.io/webserver.helm.image-tag: image.echoWebServer.tag
argocd-image-updater.argoproj.io/webserver.update-strategy: latest
argocd-image-updater.argoproj.io/write-back-method: git:secret:argocd/git-credsargocd-image-updater.argoproj.io/image-list的value中的echoserver是別名,其值為鏡像倉庫地址,可配置多個地址,中間用英文半形逗號(,)分隔。請根據您實際情況進行修改。此處為Helm編排的應用的配置,對於Kustomize編排的應用的配置,請參見Kustomize編排的應用參數設定。
在開發叢集上部署應用並實現自動部署最新的鏡像
使用以下YAML內容,在開發叢集上建立app-helm-dev.yaml檔案。
${url}:替換為開發叢集的Server URL。關於如何擷取叢集的Server URL,請參見使用GitOps管理叢集。repoURL:替換為您實際的應用部署倉庫地址。
由於在syncPolicy中配置了automated,所以在按規則提交了新Branch、Tag以後,可以實現自動同步和部署。
apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: app-helm-dev annotations: argocd-image-updater.argoproj.io/image-list: echoserver=demo-test-registry.cn-hangzhou.cr.aliyuncs.com/cidemo/echo-server,webserver=demo-test-registry.cn-hangzhou.cr.aliyuncs.com/cidemo/echo-web-server argocd-image-updater.argoproj.io/echoserver.helm.image-name: image.echoServer.repository argocd-image-updater.argoproj.io/echoserver.helm.image-tag: image.echoServer.tag argocd-image-updater.argoproj.io/echoserver.update-strategy: latest argocd-image-updater.argoproj.io/webserver.helm.image-name: image.echoWebServer.repository argocd-image-updater.argoproj.io/webserver.helm.image-tag: image.echoWebServer.tag argocd-image-updater.argoproj.io/webserver.update-strategy: latest argocd-image-updater.argoproj.io/write-back-method: git spec: destination: namespace: app-helm-dev # https://XX.XX.XX.XX:6443 server: ${url} source: path: manifests/helm/echo-server repoURL: 'git@github.com:ivan-cai/gitops-demo.git' targetRevision: stable-example helm: valueFiles: - values-dev.yaml project: default syncPolicy: automated: {} syncOptions: - CreateNamespace=true部署開發環境應用。
串連至ACK One Fleet執行個體,執行以下命令建立部署到開發環境的應用。
您也可以將以下YAML複製到ArgoCD UI中建立。
argocd app create -f app-helm-dev.yaml
在預發和生產叢集上部署應用並實現手動觸發灰階發布
使用以下YAML內容,在預發和生產叢集上建立app-helm-staging.yaml和app-helm-production.yaml檔案。
${url}:分別替換為預發和生產叢集的Server URL。關於如何擷取叢集的Server URL,請參見使用GitOps管理叢集。repoURL:替換為您實際的應用部署倉庫地址。
由於在syncPolicy中未配置automated,所以在按規則提交了新Branch、Tag以後,只能手動同步,觸發部署最新鏡像。
預發叢集對應Application
生產叢集對應Application
查看鏡像變更並手動同步變更。
當存在鏡像變更時,您可以查看應用部署倉庫是否有更新,也可以在ArgoCD UI的應用頁面,單擊REFRESH重新整理,更新後單擊SYNC進行同步。您還可以通過應用詳情頁查看APP DIFF。

串連至ACK One Fleet執行個體,執行以下命令建立部署到預發和生產環境的應用。
argocd app sync argocd/app-helm-staging argocd app sync argocd/app-helm-production
觸發灰階發布(金絲雀發布)。具體操作,請參見基於ACK One Gitops使用Kruise Rollout實現金絲雀發布。
執行以下命令,恢複灰階發布。
kubectl-kruise rollout approve rollout/rollouts-demo --kubeconfig <子叢集KubeConfig檔案路徑>說明本實踐使用Kruise Rollout完成灰階發布,您可以通過Argo Rollouts實現灰階發布。具體操作,請參見基於ACK One Gitops使用Argo Rollouts實現金絲雀發布。
步驟四:復原應用
如果應用發布失敗,則需要復原應用。您可以通過以下兩種方式進行應用復原。
快速復原
在ArgoCD控制台的應用頁面,單擊HISTORY AND ROLLBACK,然後選擇相應版本,單擊ROLLBACK進行復原。更多資訊,請參見復原應用版本。
通過ArgoCD CLI復原應用。具體操作,請參見通過Argo CLI復原應用。
端到端復原
您可以通過以下Git命令完成復原提交的代碼,並自動觸發CI/CD。
# 復原上一個commit。
git revert HEAD
# git revert HEAD~3..HEAD 表示從當前 HEAD 節點開始向前回退3個commit。
# git revert <commit-id-1> <commit-id-2> ... <commit-id-n> 可用來回退非連續的多個commit。
# revert完後,推送至原來分支,觸發CI/CD。
git push origin HEAD:${branch}復原後的變更被Image Updater更新到應用部署代碼倉庫後,再次同步到應用中。
步驟五:測試CI/CD流水線
根據ACR CI配置的構建規則,向原始碼倉庫推送滿足規則的Branch/Tag,觸發ACR自動Build並Push image。可執行以下命令,推送新的Tag,您可按需設定實際Tag名稱。
git clone https://github.com/{xxx}/echo-web-server.git cd echo-web-server git tag release-v3 git push origin release-v3查看新的鏡像是否構建完成。
在頂部功能表列,選擇所需地區。
在左側導覽列,選擇執行個體列表。
在執行個體列表頁面單擊目標企業版執行個體。
在企業版執行個體管理頁面選擇。
在鏡像倉庫頁面,單擊目標鏡像倉庫,然後在左側導覽列選擇構建,在構建日誌地區,查看新的鏡像是否構建完成。
新鏡像構建完成以後,執行以下命令,查看argocd-image-updater的日誌。
kubectl -nargocd logs argocd-server-<xxxxx> -c argocd-image-updater -f預期輸出:
time="2023-07-19T07:35:41Z" level=info msg="Successfully updated image 'demo-test-registry.cn-hangzhou.cr.aliyuncs.com/cidemo/echo-web-server:v1.0' to 'demo-test-registry.cn-hangzhou.cr.aliyuncs.com/cidemo/echo-web-server:v3-5a7147', but pending spec update (dry run=false)" alias=echowebserver application=echo-web-server time="2023-07-19T07:35:41Z" level=info msg="Committing 1 parameter update(s) for application echo-web-server" application=echo-web-server在GitHub上查看應用部署代碼倉庫中是否自動產生
manifests/helm/echo-server/.argocd-source-${appname}.yaml檔案。如成功產生,表示回寫成功。本實踐將產生3個此類檔案,分別對應開發、預發和生產環境下對應的3個Application,其中開發環境檔案樣本內容如下圖所示。
在開發環境查看Deployment的image已經更新為v3-5a7147版本;而預發環境和生產環境則需要手動觸發同步,並觸發灰階發布後,相應的Deployment的image才會變更為v3-5a7147版本。
更多應用鏡像自動更新的相關配置
配置更新指定的容器鏡像
您可以通過設定Annotation,為GitOps系統中建立的應用標記一個或者多個自動更新的容器鏡像,格式如下。
argocd-image-updater.argoproj.io/image-list: <image_spec_list>image_spec_list可以填寫單個容器鏡像,也可以填寫多個,多個容器鏡像之間用英文半形逗號(,)分割,每個容器鏡像描述的格式如下所示。
<alias_name>=<image_path>:<version_constraint>alias_name是應用的容器鏡像別名,可用於在做其他配置時引用。別名需為字母字串,且只允許在image-list的Annotation中使用。在本文樣本中,指定需要自動更新的鏡像為echoserver=demo-test-registry.cn-hangzhou.cr.aliyuncs.com/cidemo/echo-server:v1.0,為其設定的別名為echoserver。
argocd-image-updater.argoproj.io/image-list: echoserver=demo-test-registry.cn-hangzhou.cr.aliyuncs.com/cidemo/echo-server:v1.0鏡像Tags的條件過濾
以echoserver=demo-test-registry.cn-hangzhou.cr.aliyuncs.com/cidemo/echo-server:v1.0鏡像為例,您可以設定過濾條件,若且唯若ACR鏡像倉庫中echo-server鏡像有符合過濾條件的新Tags推送時,才觸發應用的自動更新。
通過Regex過濾允許的Tags,規範如下所示。
argocd-image-updater.argoproj.io/<image_name>.allow-tags: <match_func>其中,match_func的格式為標準的Regex。本樣本如下所示。
argocd-image-updater.argoproj.io/echoserver.allow-tags: regexp:^v[1-9].*設定容器鏡像更新策略
容器鏡像的更新策略有以下幾種,預設鏡像更新策略為semver。
更新策略 | 描述 |
semver | 按語義化版本號碼排序並更新到最新的鏡像Tag。 |
latest | 按建立時間排序並更新到最新的鏡像Tag。 說明 此時間並非鏡像推送到倉庫的時間。 |
name | 按字母排序並更新到最新的鏡像Tag。 |
digest | 更新到最新推送的可變標籤版本。 |
Annotation的格式如下所示。
argocd-image-updater.argoproj.io/<image_name>.update-strategy: <strategy>本樣本中使用的鏡像更新策略為semver,如下所示。
argocd-image-updater.argoproj.io/echoserver.update-strategy: semverHelm、Kustomize編排的應用參數設定
Helm編排的應用參數設定
應用可能包含多個容器鏡像的描述,比如gitops-demo樣本應用的values.yaml檔案中有image.echoServer.repository和image.echoServer.tag配置,Annotations相關配置如下所示。
annotations:
argocd-image-updater.argoproj.io/image-list: echoserver=demo-test-registry.cn-hangzhou.cr.aliyuncs.com/cidemo/echo-server:v1.0
argocd-image-updater.argoproj.io/echoserver.helm.image-name: image.echoServer.repository
argocd-image-updater.argoproj.io/echoserver.helm.image-tag: image.echoServer.tag
argocd-image-updater.argoproj.io/echoserver.update-strategy: latest
argocd-image-updater.argoproj.io/write-back-method: gitKustomize編排的應用參數設定
Kustomize編排類型的應用程式容器鏡像的自動更新設定,需要先設定被更新的容器鏡像的別名(可以包含Tag),然後設定原始容器鏡像地址(不包含Tag),Annotation格式如下所示:
annotations:
argocd-image-updater.argoproj.io/image-list: <image_alias>=<image_name>:<image_tag>
argocd-image-updater.argoproj.io/<image_alias>.kustomize.image-name: <original_image_name>