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 模式的缺陷很明顯:

下面以 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,提供了一個無狀態的可視化界面,用於展示調諧階段的結果。同時還提供了以下這些功能:

部署 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

多租戶模式提供了兩種不同的配置清單:

非高可用

推薦用於測試和演示環境,不推薦在生產環境下使用。有兩種部署清單可供選擇:

⚠️注意:namespace-install.yaml 配置清單中並不包含 Argo CD 的 CRD,需要自己提前單獨部署:kubectl apply -k https://github.com/argoproj/argo-cd/manifests/crds\?ref\=stable

高可用

與非高可用部署清單包含的組件相同,但增強了高可用能力和彈性能力,推薦在生產環境中使用。

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 進行分組,不同的團隊使用不同的項目,這樣就實現了多租戶環境。項目還支持更細粒度的訪問權限控制:

Demo 演示

最後通過一個簡單的示例來展示 Argo CD 的工作流程。

準備 Git 倉庫

在 GitHub 上創建一個項目,取名爲 argocd-lab[13],爲了方便實驗將倉庫設置爲公共倉庫。在倉庫中新建 dev 目錄,在目錄中創建兩個 YAML 配置清單,分別是 deployment.yamlservice.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

參數解釋:

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