Argo CD 保姆級入門教程
Argo CD 是以 Kubernetes 作爲基礎設施,遵循聲明式 GitOps 理念的持續交付(continuous delivery, CD)工具,支持多種配置管理工具,包括 ksonnet/jsonnet、kustomize 和 Helm 等。它的配置和使用非常簡單,並且自帶一個簡單易用的可視化界面。
按照官方定義,Argo CD 被實現爲一個 Kubernetes 控制器,它會持續監控正在運行的應用,並將當前的實際狀態與 Git 倉庫中聲明的期望狀態進行比較,如果實際狀態不符合期望狀態,就會更新應用的實際狀態以匹配期望狀態。
在正式開始解讀和使用 Argo CD 之前,我們需要先搞清楚爲什麼需要 Argo CD?它能給我們帶來什麼價值?
傳統 CD 工作流
從上篇文章『👉GitOps 介紹 [2]』可以知道,目前大多數 CI/CD 工具都使用基於 Push 的部署模式,例如 Jenkins、CircleCI 等。這種模式一般都會在 CI 流水線運行完成後執行一個命令(比如 kubectl)將應用部署到目標環境中。
這種 CD 模式的缺陷很明顯:
-
需要安裝配置額外工具(比如 kubectl);
-
需要 Kubernetes 對其進行授權;
-
需要雲平臺授權;
-
無法感知部署狀態。也就無法感知期望狀態與實際狀態的偏差,需要藉助額外的方案來保障一致性。
下面以 Argo CD 爲例,來看看遵循聲明式 GitOps 理念的 CD 工具是怎麼實現的。
使用 Argo CD 的 CD 工作流
和傳統 CI/CD 工具一樣,CI 部分並沒有什麼區別,無非就是測試、構建鏡像、推送鏡像、修改部署清單等等。重點在於 CD 部分。
Argo CD 會被部署在 Kubernetes 集羣中,使用的是基於 Pull 的部署模式,它會週期性地監控應用的實際狀態,也會週期性地拉取 Git 倉庫中的配置清單,並將實際狀態與期望狀態進行比較,如果實際狀態不符合期望狀態,就會更新應用的實際狀態以匹配期望狀態。
無論是通過 CI 流水線觸發更新 K8s 編排文件,還是 DevOps 工程師直接修改 K8s 編排文件,Argo CD 都會自動拉取最新的配置並應用到 K8s 集羣中。
最終會得到一個相互隔離的 CI 與 CD 流水線,CI 流水線通常由研發人員(或者 DevOps 團隊)控制,CD 流水線通常由集羣管理員(或者 DevOps 團隊)控制。
Argo CD 的優勢
下面我們來看看 Argo CD 相較於傳統 CD 工具有哪些比較明顯的優勢。
Git 作爲應用的唯一真實來源
所有 K8s 的聲明式配置都保存在 Git 中,並把 Git 作爲應用的唯一事實來源,我們不再需要手動更新應用(比如執行腳本,執行 kubectl apply 或者 helm install 命令),只需要通過統一的接口(Git)來更新應用。
此外,Argo CD 不僅會監控 Git 倉庫中聲明的期望狀態,還會監控集羣中應用的實際狀態,並將兩種狀態進行對比,只要實際狀態不符合期望狀態,實際狀態就會被修正與期望狀態一致。所以即使有人修改了集羣中應用的狀態(比如修改了副本數量),Argo CD 還是會將其恢復到之前的狀態。這就真正確保了 Git 倉庫中的編排文件可以作爲集羣狀態的唯一真實來源。
當然,有時候我們需要快速更新應用並進行調試,通過 Git 來觸發更新還是慢了點,這也不是沒有辦法,我們可以修改 Argo CD 的配置,使其不對手動修改的部分進行覆蓋或者回退,而是直接發送告警,提醒管理員不要忘了將更新提交到 Git 倉庫中。
快速回滾
Argo CD 會定期拉取最新配置並應用到集羣中,一旦最新的配置導致應用出現了故障(比如應用啓動失敗),我們可以通過 Git History 將應用狀態快速恢復到上一個可用的狀態。
如果你有多個 Kubernetes 集羣使用同一個 Git 倉庫,這個優勢會更明顯,因爲你不需要分別在不同的集羣中通過 kubectl delete
或者 helm uninstall
等手動方式進行回滾,只需要將 Git 倉庫回滾到上一個可用的版本,Argo CD 便會自動同步。
集羣災備
如果你在青雲 [3] 北京 3 區中的 KubeSphere[4] 集羣出現故障,且短期內不可恢復,可以直接創建一個新集羣,然後將 Argo CD 連接到 Git 倉庫,這個倉庫包含了整個集羣的所有配置聲明。最終新集羣的狀態會與之前舊集羣的狀態一致,完全不需要人工干預。
使用 Git 實現訪問控制
通常在生產環境中是不允許所有人訪問 Kubernetes 集羣的,如果直接在 Kubernetes 集羣中控制訪問權限,必須要使用複雜的 RBAC 規則。在 Git 倉庫中控制權限就比較簡單了,例如所有人(DevOps 團隊,運維團隊,研發團隊,等等)都可以向倉庫中提交 Pull Request,但只有高級工程師可以合併 Pull Request。
這樣做的好處是,除了集羣管理員和少數人員之外,其他人不再需要直接訪問 Kubernetes 集羣,只需訪問 Git 倉庫即可。對於程序而言也是如此,類似於 Jenkins 這樣的 CI 工具也不再需要訪問 Kubernetes 的權限,因爲只有 Argo CD 纔可以 apply 配置清單,而且 Argo CD 已經部署在 Kubernetes 集羣中,必要的訪問權限已經配置妥當,這樣就不需要給集羣外的任意人或工具提供訪問的證書,可以提供更強大的安全保障。
擴展 Kubernetes
雖然 Argo CD 可以部署在 Kubernetes 集羣中,享受 Kubernetes 帶來的好處,但這不是 Argo CD 專屬的呀!Jenkins 不是也可以部署在 Kubernetes 中嗎?Argo CD 有啥特殊的嗎?
那當然有了,沒這金剛鑽也不敢攬這瓷器活啊,Argo CD 巧妙地利用了 Kubernetes 集羣中的很多功能來實現自己的目的,例如所有的資源都存儲在 Etcd 集羣中,利用 Kubernetes 的控制器來監控應用的實際狀態並與期望狀態進行對比,等等。
這樣做最直觀的好處就是可以實時感知應用的部署狀態。例如,當你在 Git 倉庫中更新配置清單中的鏡像版本後,Argo CD 會將集羣中的應用更新到最新版本,你可以在 Argo CD 的可視化界面中實時查看更新狀態(比如 Pod 創建成功,應用成功運行並且處於健康狀態,或者應用運行失敗需要進行回滾操作)。
Argo CD 架構
從功能架構來看,Argo CD 主要有三個組件:API Server、Repository Server 和 Application Controller。從 GitOps 工作流的角度來看,總共分爲 3 個階段:檢索、調諧和呈現。
檢索 -- Repository Server
檢索階段會克隆應用聲明式配置清單所在的 Git 倉庫,並將其緩存到本地存儲。包含 Kubernetes 原生的配置清單、Helm Chart 以及 Kustomize 配置清單。履行這些職責的組件就是 Repository Server。
調諧 -- Application Controller
調諧(Reconcile)階段是最複雜的,這個階段會將 Repository Server 獲得的配置清單與反映集羣當前狀態的實時配置清單進行對比,一旦檢測到應用處於 OutOfSync
狀態,Application Controller 就會採取修正措施,使集羣的實際狀態與期望狀態保持一致。
呈現 -- API Server
最後一個階段是呈現階段,由 Argo CD 的 API Server 負責,它本質上是一個 gRPC/REST Server,提供了一個無狀態的可視化界面,用於展示調諧階段的結果。同時還提供了以下這些功能:
-
應用管理和狀態報告;
-
調用與應用相關的操作(例如同步、回滾、以及用戶自定義的操作);
-
Git 倉庫與集羣憑證管理(以 Kubernetes Secret 的形式存儲);
-
爲外部身份驗證組件提供身份驗證和授權委託;
-
RBAC 增強;
-
Git Webhook 事件的監聽器 / 轉發器。
部署 Argo CD
Argo CD 有兩種不同的部署模式:
多租戶
Argo CD 最常用的部署模式是多租戶,一般如果組織內部包含多個應用研發團隊,就會採用這種部署模式。用戶可以使用可視化界面或者 argocd CLI 來訪問 Argo CD。argocd CLI 必須先通過 argocd login <server-host>
來獲取 Argo CD 的訪問授權。
$ argocd login SERVER [flags]
## Login to Argo CD using a username and password
$ argocd login cd.argoproj.io
## Login to Argo CD using SSO
$ argocd login cd.argoproj.io --sso
## Configure direct access using Kubernetes API server
$ argocd login cd.argoproj.io --core
多租戶模式提供了兩種不同的配置清單:
非高可用
推薦用於測試和演示環境,不推薦在生產環境下使用。有兩種部署清單可供選擇:
-
install.yaml[5] - 標準的 Argo CD 部署清單,擁有集羣管理員權限。可以使用 Argo CD 在其運行的集羣內部署應用程序,也可以通過接入外部集羣的憑證將應用部署到外部集羣中。
-
namespace-install.yaml[6] - 這個部署清單隻需要 namespace 級別的權限。如果你不需要在 Argo CD 運行的集羣中部署應用,只需通過接入外部集羣的憑證將應用部署到外部集羣中,推薦使用此部署清單。還有一種花式玩法,你可以爲每個團隊分別部署單獨的 Argo CD 實例,但是每個 Argo CD 實例都可以使用特殊的憑證(例如
argocd cluster add <CONTEXT> --in-cluster --namespace <YOUR NAMESPACE>
)將應用部署到同一個集羣中(即kubernetes.svc.default
,也就是內部集羣)。
❝
⚠️注意:namespace-install.yaml 配置清單中並不包含 Argo CD 的 CRD,需要自己提前單獨部署:
kubectl apply -k https://github.com/argoproj/argo-cd/manifests/crds\?ref\=stable
。
高可用
與非高可用部署清單包含的組件相同,但增強了高可用能力和彈性能力,推薦在生產環境中使用。
-
ha/install.yaml[7] - 與上文提到的 install.yaml 的內容相同,但配置了相關組件的多個副本。
-
ha/namespace-install.yaml[8] - 與上文提到的 namespace-install.yaml 相同,但配置了相關組件的多個副本。
Core
Core 模式也就是最精簡的部署模式,不包含 API Server 和可視化界面,只部署了每個組件的輕量級(非高可用)版本。
用戶需要 Kubernetes 訪問權限來管理 Argo CD,因此必須使用下面的命令來配置 argocd CLI:
$ kubectl config set-context --current --namespace=argocd # change current kube context to argocd namespace
$ argocd login --core
也可以使用命令 argocd admin dashboard
手動啓用可視化界面。
具體的配置清單位於 Git 倉庫中的 core-install.yaml[9]。
除了直接通過原生的配置清單進行部署,Argo CD 還支持額外的配置清單管理工具。
Kustomize
Argo CD 配置清單也可以使用 Kustomize 來部署,建議通過遠程的 URL 來調用配置清單,使用 patch 來配置自定義選項。
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: argocd
resources:
- https://raw.githubusercontent.com/argoproj/argo-cd/v2.0.4/manifests/ha/install.yaml
Helm
Argo CD 的 Helm Chart 目前由社區維護,地址:https://github.com/argoproj/argo-helm/tree/master/charts/argo-cd[10]。
下面演示一下部署過程。如果沒有現成的 Kubernetes 環境,可以通過 KubeSphere Cloud 託管集羣服務 [11] 快速創建一個,免費體驗時間爲 2 小時,到期後集羣會自動刪除,可不限次重建。
創建 Kubernetes 集羣的過程很簡單,首先註冊登錄 https://kubesphere.cloud[12] 控制檯,然後點擊 託管集羣服務 打開 新建 Kubernetes 集羣 頁面,填寫集羣名稱,選擇運行環境,點擊 新建 菜單即可創建集羣。
幾秒鐘之後便會創建完畢,並顯示集羣基本信息。下載 kubeconfig,便可使用 kubectl 來訪問集羣。
接下來開始部署 Argo CD:
$ kubectl create namespace argocd
$ kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
查看部署結果:
$ kubectl -n argocd get pod
argocd-applicationset-controller-69879c47c-pcbkg 1/1 Running 0 26m
argocd-notifications-controller-6b4b74d8d8-s7mrz 1/1 Running 0 26m
argocd-redis-65596bf87-2hzcv 1/1 Running 0 26m
argocd-dex-server-78c9764884-6lcww 1/1 Running 0 26m
argocd-repo-server-657d46f8b-87rzq 1/1 Running 0 26m
argocd-application-controller-0 1/1 Running 0 26m
argocd-server-6b48df79dd-b7bkw 1/1 Running 0 26m
訪問 Argo CD
部署完成後,可以通過 Service argocd-server
來訪問可視化界面。
$ kubectl -n argocd get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
argocd-applicationset-controller ClusterIP 10.105.250.212 <none> 7000/TCP,8080/TCP 5m10s
argocd-dex-server ClusterIP 10.108.88.97 <none> 5556/TCP,5557/TCP,5558/TCP 5m10s
argocd-metrics ClusterIP 10.103.11.245 <none> 8082/TCP 5m10s
argocd-notifications-controller-metrics ClusterIP 10.98.136.200 <none> 9001/TCP 5m9s
argocd-redis ClusterIP 10.110.151.108 <none> 6379/TCP 5m9s
argocd-repo-server ClusterIP 10.109.131.197 <none> 8081/TCP,8084/TCP 5m9s
argocd-server ClusterIP 10.98.23.255 <none> 80/TCP,443/TCP 5m9s
argocd-server-metrics ClusterIP 10.103.184.121 <none> 8083/TCP 5m8s
如果你的客戶端可以直連 Service IP,那就直接可以通過 argocd-server 的 Cluster IP 來訪問。或者可以直接通過本地端口轉發來訪問:
$ kubectl port-forward svc/argocd-server -n argocd 8080:443
Forwarding from 127.0.0.1:8080 -> 8080
Forwarding from [::1]:8080 -> 8080
初始密碼以明文形式存儲在 Secret argocd-initial-admin-secret
中,可以通過以下命令獲取:
$ kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo
也可以通過以下命令來修改登錄密碼:
$ argocd account update-password --account admin --current-password xxxx --new-password xxxx
登錄後的界面:
Argo CD 核心概念
在正式開始使用 Argo CD 之前,需要先了解兩個基本概念。
Argo CD Application
Argo CD 中的 Application 定義了 Kubernetes 資源的來源(Source)和目標(Destination)。來源指的是 Git 倉庫中 Kubernetes 資源配置清單所在的位置,而目標是指資源在 Kubernetes 集羣中的部署位置。
來源可以是原生的 Kubernetes 配置清單,也可以是 Helm Chart 或者 Kustomize 部署清單。
目標指定了 Kubernetes 集羣中 API Server 的 URL 和相關的 namespace,這樣 Argo CD 就知道將應用部署到哪個集羣的哪個 namespace 中。
簡而言之,Application 的職責就是將目標 Kubernetes 集羣中的 namespace 與 Git 倉庫中聲明的期望狀態連接起來。
Application 的配置清單示例:
如果有多個團隊,每個團隊都要維護大量的應用,就需要用到 Argo CD 的另一個概念:項目(Project)。
Argo CD Project
Argo CD 中的項目(Project)可以用來對 Application 進行分組,不同的團隊使用不同的項目,這樣就實現了多租戶環境。項目還支持更細粒度的訪問權限控制:
-
限制部署內容(受信任的 Git 倉庫);
-
限制目標部署環境(目標集羣和 namespace);
-
限制部署的資源類型(例如 RBAC、CRD、DaemonSets、NetworkPolicy 等);
-
定義項目角色,爲 Application 提供 RBAC(與 OIDC group 或者 JWT 令牌綁定)。
Demo 演示
最後通過一個簡單的示例來展示 Argo CD 的工作流程。
準備 Git 倉庫
在 GitHub 上創建一個項目,取名爲 argocd-lab[13],爲了方便實驗將倉庫設置爲公共倉庫。在倉庫中新建 dev 目錄,在目錄中創建兩個 YAML 配置清單,分別是 deployment.yaml
和 service.yaml
。
配置清單內容如下:
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
selector:
matchLabels:
app: myapp
replicas: 2
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: nginx:latest
ports:
- containerPort: 80
# service.yaml
apiVersion: v1
kind: Service
metadata:
name: myapp-service
spec:
selector:
app: myapp
ports:
- port: 80
protocol: TCP
targetPort: 80
接下來在倉庫根目錄中創建一個 Application 的配置清單:
# application.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: myapp-argo-application
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/yangchuansheng/argocd-lab.git
targetRevision: HEAD
path: dev
destination:
server: https://kubernetes.default.svc
namespace: myapp
syncPolicy:
syncOptions:
- CreateNamespace=true
automated:
selfHeal: true
prune: true
參數解釋:
-
syncPolicy : 指定自動同步策略和頻率,不配置時需要手動觸發同步。
-
syncOptions : 定義同步方式。
-
CreateNamespace=true : 如果不存在這個 namespace,就會自動創建它。
-
automated : 檢測到實際狀態與期望狀態不一致時,採取的同步措施。
-
selfHeal : 當集羣世紀狀態不符合期望狀態時,自動同步。
-
prune : 自動同步時,刪除 Git 中不存在的資源。
Argo CD 默認情況下每 3 分鐘會檢測 Git 倉庫一次,用於判斷應用實際狀態是否和 Git 中聲明的期望狀態一致,如果不一致,狀態就轉換爲 OutOfSync
。默認情況下並不會觸發更新,除非通過 syncPolicy
配置了自動同步。
如果嫌週期性同步太慢了,也可以通過設置 Webhook 來使 Git 倉庫更新時立即觸發同步。具體的使用方式會放到後續的教程中,本文不再贅述。
創建 Application
現在萬事具備,只需要通過 application.yaml 創建 Application 即可。
$ kubectl apply -f application.yaml
application.argoproj.io/myapp-argo-application created
在 Argo CD 可視化界面中可以看到應用已經創建成功了。
點進去可以看到應用的同步詳情和各個資源的健康狀況。
如果你更新了 deployment.yaml 中的鏡像,Argo CD 會自動檢測到 Git 倉庫中的更新,並且將集羣中 Deployment 的鏡像更新爲 Git 倉庫中最新設置的鏡像版本。
KubeSphere 從 3.3.0 開始 [14] 也提供了基於 GitOps 的 CD 方案,引入 Argo CD 作爲 CD 的後端,而且可視化界面更加炫酷,感興趣的小夥伴可以試試使用 KubeSphere 來創建管理 Application。
總結
本文介紹了 Argo CD 的優勢、架構和工作原理,並通過一個簡單的示例對其功能進行演示,比如修改 Git 倉庫內容後,可以自動觸發更新。還可以通過 Event Source 和 Trigger 實現更多自動化部署的需求。
在部署 Kubernetes 資源時,Argo CD 還支持 Kustomize、Helm、Ksonnet 等資源描述方式,包括其他更高級的使用方式都會在後續的教程中爲大家一一道來,敬請期待。
引用鏈接
[1]
GitOps 介紹: https://icloudnative.io/
[2]
GitOps 介紹: https://icloudnative.io/
[3]
青雲: https://www.qingcloud.com/
[4]
KubeSphere: https://kubesphere.com.cn
[5]
install.yaml: https://github.com/argoproj/argo-cd/blob/master/manifests/install.yaml
[6]
namespace-install.yaml: https://github.com/argoproj/argo-cd/blob/master/manifests/namespace-install.yaml
[7]
ha/install.yaml: https://github.com/argoproj/argo-cd/blob/master/manifests/ha/install.yaml
[8]
ha/namespace-install.yaml: https://github.com/argoproj/argo-cd/blob/master/manifests/ha/namespace-install.yaml
[9]
core-install.yaml: https://github.com/argoproj/argo-cd/blob/master/manifests/core-install.yaml
[10]
https://github.com/argoproj/argo-helm/tree/master/charts/argo-cd: https://github.com/argoproj/argo-helm/tree/master/charts/argo-cd
[11]
KubeSphere Cloud 託管集羣服務: https://kubesphere.cloud/console/resource/
[12]
https://kubesphere.cloud: https://kubesphere.cloud/
[13]
argocd-lab: https://github.com/yangchuansheng/argocd-lab
[14]
KubeSphere 從 3.3.0 開始: https://kubesphere.com.cn/news/kubesphere-3.3.0-ga-announcement/
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/r1DnnHptOTaS_Gp8tpPWdg