一起学习使用 Argo CD 实现 GitOps

云计算 云原生
Argo CD 是通过 Kubernetes 控制器来实现的,它持续 watch 正在运行的应用程序并将当前的实时状态与所需的目标状态( Git 存储库中指定的)进行比较。

Argo CD 是一个为 Kubernetes 而生的,遵循声明式 GitOps 理念的持续部署工具。Argo CD 可在 Git 存储库更改时自动同步和部署应用程序。

Argo CD 遵循 GitOps 模式,使用 Git 仓库作为定义所需应用程序状态的真实来源,Argo CD 支持多种 Kubernetes 清单:

  • kustomize
  • helm charts
  • ksonnet applications
  • jsonnet files
  • Plain directory of YAML/json manifests
  • Any custom config management tool configured as a config management plugin

Argo CD 可在指定的目标环境中自动部署所需的应用程序状态,应用程序部署可以在 Git 提交时跟踪对分支、标签的更新,或固定到清单的指定版本。

架构

ArgoCD架构

Argo CD 是通过 Kubernetes 控制器来实现的,它持续 watch 正在运行的应用程序并将当前的实时状态与所需的目标状态( Git 存储库中指定的)进行比较。已经部署的应用程序的实际状态与目标状态有差异,则被认为是 OutOfSync 状态,Argo CD 会报告显示这些差异,同时提供工具来自动或手动将状态同步到期望的目标状态。在 Git 仓库中对期望目标状态所做的任何修改都可以自动应用反馈到指定的目标环境中去。

下面简单介绍下 Argo CD 中的几个主要组件:

API 服务:API 服务是一个 gRPC/REST 服务,它暴露了 Web UI、CLI 和 CI/CD 系统使用的接口,主要有以下几个功能:

  • 应用程序管理和状态报告
  • 执行应用程序操作(例如同步、回滚、用户定义的操作)
  • 存储仓库和集群凭据管理(存储为 K8s Secrets 对象)
  • 认证和授权给外部身份提供者
  • RBAC
  • Git webhook 事件的侦听器/转发器

仓库服务:存储仓库服务是一个内部服务,负责维护保存应用程序清单 Git 仓库的本地缓存。当提供以下输入时,它负责生成并返回 Kubernetes 清单:

  • 存储 URL
  • revision 版本(commit、tag、branch)
  • 应用路径
  • 模板配置:参数、ksonnet 环境、helm values.yaml 等

应用控制器:应用控制器是一个 Kubernetes 控制器,它持续 watch 正在运行的应用程序并将当前的实时状态与所期望的目标状态(repo 中指定的)进行比较。它检测应用程序的 OutOfSync 状态,并采取一些措施来同步状态,它负责调用任何用户定义的生命周期事件的钩子(PreSync、Sync、PostSync)。

功能

  • 自动部署应用程序到指定的目标环境
  • 支持多种配置管理/模板工具(Kustomize、Helm、Ksonnet、Jsonnet、plain-YAML)
  • 能够管理和部署到多个集群
  • SSO 集成(OIDC、OAuth2、LDAP、SAML 2.0、GitHub、GitLab、Microsoft、LinkedIn)
  • 用于授权的多租户和 RBAC 策略
  • 回滚/随时回滚到 Git 存储库中提交的任何应用配置
  • 应用资源的健康状况分析
  • 自动配置检测和可视化
  • 自动或手动将应用程序同步到所需状态
  • 提供应用程序活动实时视图的 Web UI
  • 用于自动化和 CI 集成的 CLI
  • Webhook 集成(GitHub、BitBucket、GitLab)
  • 用于自动化的 AccessTokens
  • PreSync、Sync、PostSync Hooks,以支持复杂的应用程序部署(例如蓝/绿和金丝雀发布)
  • 应用程序事件和 API 调用的审计
  • Prometheus 监控指标
  • 用于覆盖 Git 中的 ksonnet/helm 参数

核心概念

  • Application:应用,一组由资源清单定义的 Kubernetes 资源,这是一个 CRD 资源对象
  • ApplicationSet:应用集,一组应用的集合,可以用来批量创建应用
  • Application source type:用来构建应用的工具
  • Target state:目标状态,指应用程序所需的期望状态,由 Git 存储库中的文件表示
  • Live state:实时状态,指应用程序实时的状态,比如部署了哪些 Pods 等真实状态
  • Sync status:同步状态表示实时状态是否与目标状态一致,部署的应用是否与 Git 所描述的一样?
  • Sync:同步指将应用程序迁移到其目标状态的过程,比如通过对 Kubernetes 集群应用变更
  • Sync operation status:同步操作状态指的是同步是否成功
  • Refresh:刷新是指将 Git 中的最新代码与实时状态进行比较,弄清楚有什么不同
  • Health:应用程序的健康状况,它是否正常运行?能否为请求提供服务?
  • Tool:工具指从文件目录创建清单的工具,例如 Kustomize 或 Ksonnet 等
  • Configuration management tool:配置管理工具
  • Configuration management plugin:配置管理插件

安装

当然前提是需要有一个 kubectl 可访问的 Kubernetes 的集群,直接使用下面的命令即可,这里我们安装最新的 v2.8.4 版本:

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

如果你要用在生产环境,则可以使用下面的命令部署一个 HA 高可用的版本:

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

这将创建一个新的命名空间 argocd,Argo CD 的服务和应用资源都将部署到该命名空间。

$ kubectl get pods -n argocd
NAME                                                READY   STATUS    RESTARTS   AGE
argocd-application-controller-0                     1/1     Running   0          103s
argocd-applicationset-controller-68b9bdbd8b-jzcpf   1/1     Running   0          103s
argocd-dex-server-6b7745757-6mxwk                   1/1     Running   0          103s
argocd-notifications-controller-5b56f6f7bb-jqpng    1/1     Running   0          103s
argocd-redis-f4cdbff57-dr8jc                        1/1     Running   0          103s
argocd-repo-server-c4f79b4d6-7nh6n                  1/1     Running   0          103s
argocd-server-895675597-fr42g                       1/1     Running   0          103s

如果你对 UI、SSO、多集群管理这些特性不感兴趣,只想把应用变更同步到集群中,那么可以直接安装核心组件即可:kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/v2.12.3/manifests/core-install.yaml。

然后我们可以在本地(选择对应的版本)安装 CLI 工具方便操作 Argo CD:

$ curl -sSL -o /usr/local/bin/argocd https://github.com/argoproj/argo-cd/releases/download/v2.12.3/argocd-linux-amd64

为 argocd CLI 赋予可执行权限:

$ chmod +x /usr/local/bin/argocd

现在我们就可以使用 argocd 命令了。如果你是 Mac,则可以直接使用 brew install argocd 进行安装。

Argo CD 会运行一个 gRPC 服务(由 CLI 使用)和 HTTP/HTTPS 服务(由 UI 使用),这两种协议都由 argocd-server 服务在以下端口进行暴露:

  • 443 - gRPC/HTTPS
  • 80 - HTTP(重定向到 HTTPS)

我们可以通过配置 Ingress 的方式来对外暴露服务,其他 Ingress 控制器的配置可以参考官方文档 https://argo-cd.readthedocs.io/en/stable/operator-manual/ingress/ 进行配置。

Argo CD 在同一端口 (443) 上提供多个协议 (gRPC/HTTPS),所以当我们为 argocd 服务定义单个 nginx ingress 对象和规则的时候有点麻烦,因为 nginx.ingress.kubernetes.io/backend-protocol 这个 annotation 只能接受一个后端协议(例如 HTTP、HTTPS、GRPC、GRPCS)。

为了使用单个 ingress 规则和主机名来暴露 Argo CD APIServer,必须使用 nginx.ingress.kubernetes.io/ssl-passthrough 这个 annotation 来传递 TLS 连接并校验 Argo CD APIServer 上的 TLS。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: argocd-server-ingress
  namespace: argocd
  annotations:
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/ssl-passthrough: "true"
spec:
  ingressClassName: nginx
  rules:
    - host: argocd.k8s.local
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: argocd-server
                port:
                  name: https

上述规则在 Argo CD APIServer 上校验 TLS,该服务器检测到正在使用的协议,并做出适当的响应。请注意,nginx.ingress.kubernetes.io/ssl-passthrough 注解要求将 --enable-ssl-passthrough 标志添加到 nginx-ingress-controller 的命令行参数中。

由于 ingress-nginx 的每个 Ingress 对象仅支持一个协议,因此另一种方法是定义两个 Ingress 对象。一个用于 HTTP/HTTPS,另一个用于 gRPC。

如下所示为 HTTP/HTTPS 的 Ingress 对象:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: argocd-server-http-ingress
  namespace: argocd
  annotations:
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
spec:
  ingressClassName: nginx
  rules:
    - http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: argocd-server
                port:
                  name: http
      host: argocd.k8s.local
  tls:
    - hosts:
        - argocd.k8s.local
      secretName: argocd-secret # do not change, this is provided by Argo CD

gRPC 协议对应的 Ingress 对象如下所示:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: argocd-server-grpc-ingress
  namespace: argocd
  annotations:
    nginx.ingress.kubernetes.io/backend-protocol: "GRPC"
spec:
  ingressClassName: nginx
  rules:
    - http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: argocd-server
                port:
                  name: https
      host: grpc.argocd.k8s.local
  tls:
    - hosts:
        - grpc.argocd.k8s.local
      secretName: argocd-secret # do not change, this is provided by Argo CD

然后我们需要在禁用 TLS 的情况下运行 APIServer。编辑 argocd-server 这个 Deployment 以将 --insecure 标志添加到 argocd-server 命令,或者简单地在 argocd-cmd-params-cm ConfigMap 中设置 server.insecure: "true" 即可。

创建完成后,我们就可以通过 argocd.k8s.local 来访问 Argo CD 服务了,不过需要注意我们这里配置的证书是自签名的,所以在第一次访问的时候会提示不安全,强制跳转即可。

安全提示

默认情况下 admin 帐号的初始密码是自动生成的,会以明文的形式存储在 Argo CD 安装的命名空间中名为 argocd-initial-admin-secret 的 Secret 对象下的 password 字段下,我们可以用下面的命令来获取:

$ kubectl -n argocd get secret argocd-initial-admin-secret -o jsnotallow="{.data.password}" | base64 -d && echo

使用用户名 admin 和上面输出的密码即可登录 Dashboard。

argocd ui

默认的首页如下所示:

argocd 首页

同样我们也可以通过 ArgoCD CLI 命令行工具进行登录:

$ argocd login grpc.argocd.k8s.local
WARNING: server certificate had error: tls: failed to verify certificate: x509: certificate signed by unknown authority. Proceed insecurely (y/n)? y
Username: admin
Password:
'admin:login' logged in successfully
Context 'grpc.argocd.k8s.local' updated

需要注意的是这里登录的地址为 gRPC 暴露的服务地址。

CLI 登录成功后,可以使用如下所示命令更改密码:

$ argocd account update-password
*** Enter current password:
*** Enter new password:
*** Confirm new password:
Password updated
Context 'argocd.k8s.local' updated
$ argocd version
argocd: v2.12.3+6b9cd82
  BuildDate: 2024-08-27T15:31:43Z
  GitCommit: 6b9cd828c6e9807398869ad5ac44efd2c28422d6
  GitTreeState: clean
  GoVersion: go1.23.0
  Compiler: gc
  Platform: darwin/arm64
argocd-server: v2.12.3+6b9cd82
  BuildDate: 2024-08-27T11:57:48Z
  GitCommit: 6b9cd828c6e9807398869ad5ac44efd2c28422d6
  GitTreeState: clean
  GoVersion: go1.22.4
  Compiler: gc
  Platform: linux/amd64
  Kustomize Version: v5.4.2 2024-05-22T15:19:38Z
  Helm Version: v3.15.2+g1a500d5
  Kubectl Version: v0.29.6
  Jsonnet Version: v0.20.0

配置集群

由于 Argo CD 支持部署应用到多集群,所以如果你要将应用部署到外部集群的时候,需要先将外部集群的认证信息注册到 Argo CD 中,如果是在内部部署(运行 Argo CD 的同一个集群,默认不需要配置),直接使用 https://kubernetes.default.svc 作为应用的 K8S APIServer 地址即可。

首先列出当前 kubeconfig 中的所有集群上下文:

$ kubectl config get-contexts -o name
kubernetes-admin@kubernetes
orbstack

从列表中选择一个上下文名称并将其提供给 argocd cluster add CONTEXTNAME,比如对于 orbstack 上下文,运行:

$ argocd cluster list
SERVER                          NAME        VERSION  STATUS      MESSAGE  PROJECT
https://kubernetes.default.svc  in-cluster  1.28     Successful
$ argocd cluster add orbstack

创建应用

Git 仓库 https://github.com/argoproj/argocd-example-apps.git 是一个包含留言簿应用程序的示例库,我们可以用该应用来演示 Argo CD 的工作原理。

通过 CLI 创建应用

我们可以通过 argocd app create xxx 命令来创建一个应用:

$ argocd app create --help
Create an application

Usage:
  argocd app create APPNAME [flags]

Examples:

        # Create a directory app
        argocd app create guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path guestbook --dest-namespace default --dest-server https://kubernetes.default.svc --directory-recurse

        # Create a Jsonnet app
        argocd app create jsonnet-guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path jsonnet-guestbook --dest-namespace default --dest-server https://kubernetes.default.svc --jsonnet-ext-str replicas=2

        # Create a Helm app
        argocd app create helm-guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path helm-guestbook --dest-namespace default --dest-server https://kubernetes.default.svc --helm-set replicaCount=2

        # Create a Helm app from a Helm repo
        argocd app create nginx-ingress --repo https://charts.helm.sh/stable --helm-chart nginx-ingress --revision 1.24.3 --dest-namespace default --dest-server https://kubernetes.default.svc

        # Create a Kustomize app
        argocd app create kustomize-guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path kustomize-guestbook --dest-namespace default --dest-server https://kubernetes.default.svc --kustomize-image gcr.io/heptio-images/ks-guestbook-demo:0.1

        # Create a app using a custom tool:
        argocd app create kasane --repo https://github.com/argoproj/argocd-example-apps.git --path plugins/kasane --dest-namespace default --dest-server https://kubernetes.default.svc --config-management-plugin kasane


Flags:
......

直接执行如下所示命令即可:

$ argocd app create guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path guestbook --dest-server https://kubernetes.default.svc --dest-namespace default
application 'guestbook' created

通过 UI 创建应用

除了可以通过 CLI 工具来创建应用,我们也可以通过 UI 界面来创建,定位到 argocd.k8s.local 页面,登录后,点击 +New App 新建应用按钮。将应用命名为 guestbook,使用 default project,并将同步策略设置为 Manual:

配置应用

然后在下面配置 Repository URL 为 https://github.com/argoproj/argocd-example-apps.git,由于某些原因我们这里使用的是 Gitee 仓库地址 https://gitee.com/cnych/argocd-example-apps,将 Revision 设置为 HEAD,并将路径设置为 guestbook。然后下面的 Destination 部分,将 cluster 设置为 inCluster 和 namespace 为 default:

配置集群

填写完以上信息后,点击页面上方的 Create 安装,即可创建 guestbook 应用,创建完成后可以看到当前应用的处于 OutOfSync 状态:

guestbook application

Argo CD 默认情况下每 3 分钟会检测 Git 仓库一次,用于判断应用实际状态是否和 Git 中声明的期望状态一致,如果不一致,状态就转换为 OutOfSync。默认情况下并不会触发更新,除非通过 syncPolicy 配置了自动同步。

通过 CRD 创建

除了可以通过 CLI 和 Dashboard 可以创建 Application 之外,其实也可以直接通过声明一个 Application 的资源对象来创建一个应用,如下所示:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: guestbook
spec:
  destination:
    namespace: default
    server: "https://kubernetes.default.svc"
  source:
    path: guestbook
    repoURL: "https://github.com/cnych/argocd-example-apps"
    targetRevision: HEAD
  project: default
  syncPolicy:
    automated: null

部署应用

由于上面我们在创建应用的时候使用的同步策略为 Manual,所以应用创建完成后没有自动部署,需要我们手动去部署应用。同样可以通过 CLI 和 UI 界面两种同步方式。

使用 CLI 同步

应用创建完成后,我们可以通过如下所示命令查看其状态:

$ argocd app get argocd/guestbook
Name:               argocd/guestbook
Project:            default
Server:             https://kubernetes.default.svc
Namespace:          default
URL:                https://grpc.argocd.k8s.local/applications/guestbook
Source:
- Repo:             https://gitee.com/cnych/argocd-example-apps
  Target:           HEAD
  Path:             guestbook
SyncWindow:         Sync Allowed
Sync Policy:        Manual
Sync Status:        OutOfSync from HEAD (3b08dd4)
Health Status:      Missing

GROUP  KIND        NAMESPACE  NAME          STATUS     HEALTH   HOOK  MESSAGE
       Service     default    guestbook-ui  OutOfSync  Missing
apps   Deployment  default    guestbook-ui  OutOfSync  Missing

应用程序状态为初始 OutOfSync 状态,因为应用程序尚未部署,并且尚未创建任何 Kubernetes 资源。要同步(部署)应用程序,可以执行如下所示命令:

$ argocd app sync argocd/guestbook
TIMESTAMP                  GROUP        KIND   NAMESPACE                  NAME    STATUS    HEALTH        HOOK  MESSAGE
2024-09-08T10:42:02+08:00            Service     default          guestbook-ui  OutOfSync  Missing
2024-09-08T10:42:02+08:00   apps  Deployment     default          guestbook-ui  OutOfSync  Missing
2024-09-08T10:42:03+08:00            Service     default          guestbook-ui  OutOfSync  Missing              service/guestbook-ui created
2024-09-08T10:42:03+08:00   apps  Deployment     default          guestbook-ui  OutOfSync  Missing              deployment.apps/guestbook-ui created
2024-09-08T10:42:03+08:00            Service     default          guestbook-ui    Synced  Healthy                  service/guestbook-ui created
2024-09-08T10:42:03+08:00   apps  Deployment     default          guestbook-ui    Synced  Progressing              deployment.apps/guestbook-ui created

Name:               argocd/guestbook
Project:            default
Server:             https://kubernetes.default.svc
Namespace:          default
URL:                https://grpc.argocd.k8s.local/applications/argocd/guestbook
Source:
- Repo:             https://gitee.com/cnych/argocd-example-apps
  Target:           HEAD
  Path:             guestbook
SyncWindow:         Sync Allowed
Sync Policy:        Manual
Sync Status:        Synced to HEAD (3b08dd4)
Health Status:      Progressing

Operation:          Sync
Sync Revision:      3b08dd4969319e053d9cab2a02f949abc9f4aa45
Phase:              Succeeded
Start:              2024-09-08 10:42:02 +0800 CST
Finished:           2024-09-08 10:42:03 +0800 CST
Duration:           1s
Message:            successfully synced (all tasks run)

GROUP  KIND        NAMESPACE  NAME          STATUS  HEALTH       HOOK  MESSAGE
       Service     default    guestbook-ui  Synced  Healthy            service/guestbook-ui created
apps   Deployment  default    guestbook-ui  Synced  Progressing        deployment.apps/guestbook-ui created

此命令从 Git 仓库中检索资源清单并执行 kubectl apply 部署应用,执行上面命令后 guestbook 应用便会运行在集群中了,现在我们就可以查看其资源组件、日志、事件和评估其健康状态了。

通过 UI 同步

直接添加 UI 界面上应用的 Sync 按钮即可开始同步:

sync 操作

同步完成后可以看到我们的资源状态,甚至还可以直接查看应用的日志信息:

Sync 完成

也可以通过 kubectl 查看到我们部署的资源:

$ kubectl get pods
NAME                                 READY   STATUS      RESTARTS       AGE
guestbook-ui-6c96fb4bdc-bdwh9        1/1     Running     0              3m3s
➜  ~ kubectl get svc
NAME                 TYPE           CLUSTER-IP       EXTERNAL-IP    PORT(S)                      AGE
guestbook-ui         ClusterIP      10.100.170.117   <none>         80/TCP                       3m16s
kubernetes           ClusterIP      10.96.0.1        <none>         443/TCP                      42d

和我们从 Git 仓库中同步 guestbook 目录下面的资源状态也是同步的,证明同步成功了。

Helm 项目

如果有多个团队,每个团队都要维护大量的应用,就需要用到 Argo CD 的另一个概念:项目(Project)。Argo CD 中的项目(Project)可以用来对 Application 进行分组,不同的团队使用不同的项目,这样就实现了多租户环境。项目还支持更细粒度的访问权限控制:

  • 限制部署内容(受信任的 Git 仓库);
  • 限制目标部署环境(目标集群和 namespace);
  • 限制部署的资源类型(例如 RBAC、CRD、DaemonSets、NetworkPolicy 等);
  • 定义项目角色,为 Application 提供 RBAC(例如 OIDC group 或者 JWT 令牌绑定)。

比如我们这里创建一个名为 demo 的项目,将该应用创建到该项目下,只需创建一个如下所示的 AppProject 对象即可:

apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  # 项目名
  name: demo
  namespace: argocd
spec:
  # 目标
  destinations:
    # 此项目的服务允许部署的 namespace,这里为全部
    - namespace: "*"
      # 此项目允许部署的集群,这里为默认集群,即为Argo CD部署的当前集群
      server: https://kubernetes.default.svc
  # 允许的数据源
  sourceRepos:
    - https://gitee.com/cnych/argocd-example-apps

该对象中有几个核心的属性:

  • sourceRepos:项目中的应用程序可以从中获取清单的仓库引用
  • destinations:项目中的应用可以部署到的集群和命名空间
  • roles:项目内资源访问定义的角色

直接创建该对象即可:

$ kubectl get appproject -n argocd
NAME      AGE
default   47h
demo      6s

更多配置信息可以前往文档 https://argo-cd.readthedocs.io/en/stable/operator-manual/declarative-setup/ 查看,项目创建完成后,在该项目下创建一个 Application,代表环境中部署的应用程序实例。

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: gitops-demo
  namespace: argocd
spec:
  destination:
    namespace: default
    server: "https://kubernetes.default.svc"
  project: demo
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
  source:
    path: helm-guestbook # 从 Helm 存储库创建应用程序时,chart 必须指定 path
    repoURL: "https://gitee.com/cnych/argocd-example-apps.git"
    targetRevision: HEAD
    helm:
      parameters:
        - name: replicaCount
          value: "2"
      valueFiles:
        - values.yaml

这里我们定义了一个名为 gitop-demo 的应用,应用源来自于 helm 路径,使用的是 values.yaml 文件,此外还可以通过 source.helm.parameters 来配置参数。

同步策略可以选择使用自动的方式,该策略下面还有两个属性可以配置:

  • PRUNE RESOURCES:开启后 Git Repo 中删除资源会自动在环境中删除对应的资源。

删除资源

  • SELF HEAL:自动痊愈,强制以 Git Repo 状态为准,手动在环境中修改不会生效。

自动痊愈

正常创建后这个应用就会自动部署了,根据我们配置会生成两个副本。

app status

由于 Argo CD 默认并不是实时去监测 Config Repo 的变化的,如果要更快的检测到变化我们可以使用 Git Webhook 的方式。

默认情况下 Argo CD 每三分钟轮询一次 Git 存储库,以检测清单的更改。为了消除轮询延迟,可以将 API 服务器配置为接收 Webhook 事件。Argo CD 支持来自 GitHub、GitLab、Bitbucket、Bitbucket Server 和 Gogs 的 Git webhook 通知。

然后在 argocd-secret 这个 Kubernetes Secret 中,使用上面配置的 Git 提供商的 Webhook 密钥配置以下密钥之一。

gitlab token

$ kubectl edit secret argocd-secret -n argocd
apiVersion: v1
kind: Secret
metadata:
  name: argocd-secret
  namespace: argocd
type: Opaque
data:
...

stringData:
  # github webhook secret
  webhook.github.secret: shhhh! it's a GitHub secret

  # gitlab webhook secret
  webhook.gitlab.secret: shhhh! it's a GitLab secret

  # bitbucket webhook secret
  webhook.bitbucket.uuid: your-bitbucket-uuid

  # bitbucket server webhook secret
  webhook.bitbucketserver.secret: shhhh! it's a Bitbucket server secret

  # gogs server webhook secret
  webhook.gogs.secret: shhhh! it's a gogs server secret

可以直接使用 stringData 来配置 secret,这样就不用去手动编码了。

因为 GitOps 的核心是 Git,所以我们一定要将部署到集群中的资源清单文件全都托管到 Git 仓库中,这样才能实现 GitOps 的自动同步部署。上面我们是在 CI 流水线中去修改 Git 仓库中的资源清单文件,其实我们也可以通过其他方式去修改,比如 Argo CD 也提供了一个新的工具 Argo CD Image Updater。

ApplicationSet

ApplicationSet 用于简化多集群应用编排,它可以基于单一应用编排并根据用户的编排内容自动生成一个或多个 Application。

比如现在我们创建一个如下所示的 ApplicationSet 资源对象:

# applicationset.yaml
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: guestbook
spec:
  goTemplate: true # 使用 go template 模板
  goTemplateOptions: ["missingkey=error"] # 当模板中缺少键时,抛出错误
  generators: # 生成器,用于生成参数
    - list: # 列表生成器
        elements: # 元素
          - cluster: dev
            url: https://1.2.3.4
          - cluster: staging
            url: https://9.8.7.6
          - cluster: prod
            url: https://kubernetes.default.svc
  template:
    metadata:
      name: "{{.cluster}}-guestbook"
    spec:
      project: demo
      source:
        repoURL: https://gitee.com/cnych/argocd-example-apps
        targetRevision: HEAD
        path: helm-guestbook
        helm:
          valueFiles:
            - "{{.cluster}}.yaml"
      syncPolicy:
        syncOptions:
          - CreateNamespace=true
      destination:
        server: "{{.url}}"
        namespace: guestbook

在上面的资源对象中,我们定义了一个 ApplicationSet 资源对象,其中使用了模板和生成器:

  • goTemplate: true:表示使用 go template 的模板
  • goTemplateOptions: ["missingkey=error"]:当模板中缺少键时,抛出错误
  • generators:生成器,用于生成参数,ApplicationSet 控制器当前支持多种生成器:
  • 包含 JSON 值的文件将被解析并转换为模板参数。
  • Git 存储库中的各个目录路径也可以用作参数值。
  • 列表生成器:根据集群名称/URL 值的固定列表生成参数,如上例所示。
  • 集群生成器:集群生成器不是基于 clusters 的字面列表(与列表生成器一样),而是根据 Argo CD 中定义的集群自动生成集群参数。
  • Git 生成器:Git 生成器根据生成器资源中定义的 Git 存储库中包含的文件或文件夹生成参数。
  • 矩阵生成器:矩阵生成器结合了其他两个生成器生成的参数。
  • template:模板,用于生成 Application 资源对象

这里我们通过列表生成器定义了多个生成器元素,里面包含 cluster 和 url 两个参数,ApplicationSet 控制器会根据这些参数生成多个 Application 资源对象,每个 Application 资源对象都会部署到对应的集群和命名空间中,每个 Application 资源就是通过这些参数将模板中的内容渲染生成。

无论使用哪个生成器,生成器生成的参数都会替换为 ApplicationSet 资源的 template: 部分中的 {{parameter name}} 值。我们这里列表生成器定义了 cluster 和 url 参数,然后将它们分别替换为模板的 {{cluster}} 和 {{url}} 值。

我们可以直接使用 argocd appset 命令来创建:

$ argocd appset create applicationset.yaml
ApplicationSet 'guestbook' created
$ argocd appset list
NAME              PROJECT  SYNCPOLICY  CONDITIONS                                                                                                                                                                                                                                     REPO                                         PATH            TARGET
argocd/guestbook  demo     nil         [{ParametersGenerated Successfully generated parameters for all Applications 2024-09-08 11:48:52 +0800 CST True ParametersGenerated} {ResourcesUpToDate ApplicationSet up to date 2024-09-08 11:48:52 +0800 CST True ApplicationSetUpToDate}]  https://gitee.com/cnych/argocd-example-apps  helm-guestbook  HEAD

创建完成后可以通过 argocd appset list 查看 ApplicationSet 资源对象的状态,从上面输出可以看到 ApplicationSet 资源对象的状态为 ParametersGenerated,表示参数已经生成成功,也就是已经将 ApplicationSet 资源对象中的内容渲染生成多个 Application 资源对象了。查看下 Application 资源对象的状态即可:

$ argocd argocd app list
NAME                      CLUSTER                         NAMESPACE  PROJECT  STATUS     HEALTH   SYNCPOLICY  CONDITIONS           REPO                                             PATH            TARGET
argocd/dev-guestbook      https://1.2.3.4                 guestbook  demo     Unknown    Unknown  Manual      InvalidSpecError(2)  https://gitee.com/cnych/argocd-example-apps      helm-guestbook  HEAD
argocd/prod-guestbook     https://kubernetes.default.svc  guestbook  demo     OutOfSync  Missing  Manual      <none>               https://gitee.com/cnych/argocd-example-apps      helm-guestbook  HEAD
argocd/staging-guestbook  https://9.8.7.6                 guestbook  demo     Unknown    Unknown  Manual      InvalidSpecError(2)  https://gitee.com/cnych/argocd-example-apps      helm-guestbook  HEAD

可以看到现在渲染了 3 个 Application 资源对象,和我们前面在 ApplicationSet 资源对象中定义的集群和 URL 是一一对应的,当然我们也可以在 Dashboard 界面中查看:

app list status

更多关于生成器的详细信息可以前往 https://argo-cd.readthedocs.io/en/latest/operator-manual/applicationset/Generators/ 查看。

责任编辑:姜华 来源: k8s技术圈
相关推荐

2021-07-09 06:40:59

TektonArgo CD GitOps

2022-08-16 22:39:01

Argo CDKubernetes

2024-05-22 08:03:15

2023-09-27 08:24:49

2021-07-04 07:24:48

GitOps 工具 Argo CD

2022-08-18 17:07:00

sopsGitOps

2021-06-24 07:20:21

Linked GitOps Argo CD

2021-12-08 12:20:55

KubernetesGitOpsLinux

2024-08-07 10:14:35

2021-09-07 08:23:45

GitOpsCICD

2021-02-10 08:24:47

微服务CICD

2023-10-07 07:51:55

FluxCDKubernetes

2021-07-12 06:36:08

钉钉Argo CDPrometheus

2021-05-19 10:37:16

WebFlux 前置工具

2023-06-26 15:14:19

WebGL纹理对象学习

2022-02-14 10:16:22

Axios接口HTTP

2023-04-11 07:43:32

PostmanGraphQL查询。

2022-02-17 11:52:05

​Argo CD漏洞Kubernetes

2021-11-26 09:44:42

链表节点定位

2022-12-01 09:59:57

内核观测性方法
点赞
收藏

51CTO技术栈公众号