來自社群使用者 willqy 的分享
argo cd 是用于 kubernetes 的聲明性 gitops 持續傳遞工具,應用程式定義,配置和環境應為聲明性的,并應受版本控制,應用程式部署和生命周期管理應該是自動化、可稽核且易于了解。
argo cd 遵循 gitops 模式,該模式使用 git 倉庫作為定義所需應用程式狀态的真實來源。
argo cd 可在指定的目标環境中自動部署所需的應用程式狀态,應用程式部署可以在 git 送出時跟蹤對分支,标簽的更新,或固定到清單的特定版本。
官網:https://argoproj.github.io/
argo cd 架構圖:
argo cd 被實作為 kubernetes 控制器,該控制器持續監視正在運作的應用程式,并将目前的活動狀态與所需的目标狀态(在 git 存儲庫中指定)進行比較。當已部署應用程式的運作狀态偏離目标狀态時将被 argo cd 視為 outofsync。
argo cd 報告并可視化差異,同時提供了自動或手動将實時狀态同步回所需目标狀态的功能。在 git 存儲庫中對所需目标狀态所做的任何修改都可以自動應用并同步到指定的目标環境中。
argo cd 支援的 kubernetes 配置清單包括 helm charts、kustomize 或純 yaml/json 檔案等。
本篇文章涉及内容:
使用 kubesphere devops 實作 ci 部分, cd 部分由 argo cd 完成;
argo cd 持續監測 git 倉庫某個目錄下 yaml 檔案變動,自動将 yaml 檔案部署到 k8s 叢集;
argo cd 持續監測 harbor 鏡像倉庫某個鏡像 tag 變動,自動将最新鏡像部署到 k8s 叢集。
基本原理圖:
準備 2 個 git 倉庫,一個源碼倉庫,一個 yaml 檔案倉庫,源碼和 yaml 檔案分離。
源碼倉庫可參考以下連結,離線環境原因,這裡選擇第二個示例 spring-demo:
https://github.com/kubesphere/devops-java-sample
https://github.com/willzhang/spring-demo
yaml 檔案倉庫可參考以下連結,這裡命名為 argocd-gitops:
https://github.com/argoproj/argocd-example-apps
yaml 倉庫下建立 javademo 目錄,并建立 2 個簡單的 yaml 檔案:
javademo-deployment.yaml 示例,目前鏡像 tag 可随意指定,執行 ci 時會實時替換該參數:
javademo-svc.yaml
argo cd 有多種部署方式,可以直接部署 yaml 檔案.
這裡使用 helm 方式部署,可直接指定 argo cd server service 類型 nodeport:
檢視運作的 pod:
如果使用 kubesphere 部署 argo cd,首先需要配置 argo cd helm 倉庫,進入企業空間,選擇應用模闆上傳離線 helm chart 包,或在應用倉庫配置公網 helm repo 位址。
完成後進入項目,點選部署新應用,選擇 argo cd helm chart 進行部署即可:
要與 argo cd api server 進行互動,我們需要安裝 cli 指令:
如果上面 argo cd 使用 yaml 方式部署,修改 serivce 類型為 nodeport,以便通路 argo cd api server
檢視 argo cd server service,記錄 nodeport 資訊:
argo cd 預設登入使用者為 admin,初始密碼為 argocd-server pod 名稱,擷取 pod 名稱
使用 argo cd cli 登入,以 nodeip 和 nodeport 作為 argo cd server 登入位址:
修改預設密碼:
浏覽器登入 argo cd ui:
登陸 argo cd ui 後,選擇 new app 建立 application,選擇 edit as ayml:
粘貼以下内容,save 後點選左上 create,當然也可以直接使用 kubectl apply 指令執行以下内容,效果相同。
參數說明:
metadata 字段:指定了應用名稱,命名空間必須指定 argo cd,添加 finalizers 字段可在删除應用時級聯删除相關 k8s 資源;
source 字段:指定了 yaml 檔案所在 git 倉庫 url,及要監測的 yaml 檔案存放目錄,該目錄下檔案有任何變更 argo cd 都會自動将其更新部署到 k8s 叢集;
destination 字段:指定監測的 yaml 檔案要部署到哪個 k8s 叢集及哪個命名空間下;
syncpolicy 字段:指定自動同步政策和頻率,不配置時需要手動觸發同步。
另外如果使用私有 git 倉庫,需要建立憑證,這裡的憑證是 argo cd 通路 yaml 檔案 git 倉庫的憑證:
等效的 argo cd cli 指令:
建立後 argo cd 會自動将 git 倉庫 javademo 目錄下的 yaml 檔案部署到 k8s 叢集,此時應用無法正常啟動,因為 yaml 檔案中的鏡像 tag 還不存在,拉取鏡像會失敗:
也可以使用 argo cd cli 檢視部署的應用:
在 kubesphere ui 檢視 pod 狀态,一直在重試拉取鏡像:
使用 kubectl 指令檢視,狀态為 imagepullbackoff :
建立 ci 流水線,使用 kubesphere devops 完成源碼編譯、鏡像建構并推送到 harbor 倉庫,最後以 git commit 方式更新 yaml 倉庫中 image 字段。
由于此時 argo cd 持續監測 yaml 倉庫配置檔案變動,當 ci 部分執行 git push 時便會觸發 argo cd 更新 yaml 檔案到 k8s 叢集。
在 kubesphere devops 工程下建立一條空流水線,命名為 javademo,進入流水線,選擇編輯 jenkinsfile,複制以下内容:
注意修改相關參數,流水線中引用了 2 個憑證:
git_credential_id 為内網 gogs git 倉庫賬号密碼
registry_credential_id 為 harbor 倉庫賬号密碼
運作流水線前需要在 devops 工程下提前建立好相關憑證,後續需要在 jenkinsfile 中引用。
最終流水線如下,點選運作,等待流水線執行完成,檢視狀态為成功:
檢視流水線建構日志,可以看到執行了以下過程,其中最後 update docker tag 步驟,執行了 2 個關鍵操作,sed 指令替換鏡像 tag,然後執行 git push 更新 yaml 倉庫。
檢視推送到 harbor 倉庫的鏡像:
argo cd 監測到 yaml 檔案變更後更新至 k8s 叢集:
argo cd ui 檢視使用的鏡像:
登入 kubesphere ui 檢視應用狀态為運作中:
在 git 倉庫直接修改 yaml 檔案配置,同樣能夠觸發 argo cd 同步,例如将 service 類型改為 nodeport:
等待 argo cd 自動同步配置更新到 k8s 叢集,浏覽器以 nodeport 方式通路 java web 應用:
上面示範了基于 git 倉庫變更作為應用部署的事實來源,下面示範另一種方式,以鏡像 tag 變更作為應用部署的事實來源。argo cd 提供了<code>argo cd image updater</code>小工具,用于實作該操作。
argo cd image updater 是一種自動更新由 argo cd 管理的 kubernetes 工作負載容器鏡像的工具。
該工具目前還在開發中,并且有以下特性和局限性:
隻能更新由 argo cd 管理并由helm或kustomize工具生成的應用程式的鏡像;
對廣泛使用的容器倉庫的預設支援:dockerhub、harbor 私有鏡像倉庫等;
能夠使用比對器功能過濾鏡像倉庫傳回的标簽清單;
鏡像拉取 secrets 必須存在于 argo cd image updater 在其中運作(或可以通路)的同一 kubernetes 群集中。目前不可能從其他叢集中擷取這些 secrets。
在目前版本中,argo cd image updater 不會将任何更改寫回到 git 存儲庫。
官方文檔:
https://argocd-image-updater.readthedocs.io/en/stable/
argo cd image updater 部署略顯繁瑣,部署操作如下:
1、在 argo cd 中建立本地使用者
建立 argo cd 鏡像更新程式需要通路 argo cd api server 的憑據,使用一個 image-updater 具有适當 api 權限的帳戶,将以下使用者定義添加到 argocd-cm:
為使用者建立通路令牌,将令牌的值複制到某個地方,稍後将需要它。
2、在 argo cd 中授予 rbac 權限
為<code>image-updater</code>使用者配置适當的 rbac 權限,argo cd image updater 需要應用程式的<code>update</code>和<code>get</code>權限。
3、 安裝 argo cd image updater
yaml 檔案下載下傳:https://github.com/argoproj-labs/argocd-image-updater/tree/master/manifests
4、 配置鏡像倉庫
即使您不打算使用私有鏡像倉庫,您也需要至少配置一個 empty <code>registries.conf</code>:
沒有此條目<code>argocd-image-updater</code> pod 将無法啟動。
如果使用私有鏡像倉庫可參考以下配置,以 harbor 鏡像倉庫為例:
5、 配置 api 通路令牌密鑰
當從清單安裝到 kubernetes 叢集時,argo cd image updater 将從名為<code>argo cd_token</code>的環境變量中讀取通路 argo cd api 所需的令牌,該環境變量是從名為 <code>argo cd.token</code> 的 secret 字段中設定的<code>argocd-image-updater-secret</code>。
<code>argo cd.token</code> 的值應設定為您上面生成的通路令牌的 base64 編碼值。作為一種捷徑,您可以使用 <code>kubectl</code> 生成密鑰,并将其應用于現有資源:
更改後,必須重新啟動 <code>argocd-image-updater</code> pod,即運作
建立 yaml 倉庫 kustomize 檔案
由于 image updater 僅支援 helm 或 kustomize 類型 yaml,這裡建立一個基于 kustomize 的 yaml 目錄,修改 yaml 中的參數不要與之前的沖突即可:
javademo-deployment.yaml
kustomization.yaml
登入 argo cd ui 建立一個 argo cd 應用,和之前相比增加了 annotations 參數,指定要監測的鏡像位址,更新政策為 latest,另外修改了 source path:
登入 kubesphere ui 重新建立一條 ci 流水線,删除 update docker tag 步驟即可,已經不需要基于 git push 來觸發應用部署了:
檢視流水線日志,鏡像成功推送到 harbor 倉庫:
harbor 倉庫鏡像 tag 更新,argo cd image updater 自動将最新 tag 更新到 k8s 叢集。
檢視鏡像 tag:
以後每次 harbor 倉庫生成最新鏡像,argo cd 都會自動将其更新到 k8s 叢集。