ArgoCD ApplicationSet v0.2.0 和 v0.3.0 的变更点是什么?

考虑到最新版本的发布以及在上一篇文章中简要介绍过的功能的增加,我打算整理并一并介绍出来。关于ApplicationSet本身的内容,请参阅上一篇文章。

版本号为v0.2.0。

发布说明:https://github.com/argoproj-labs/applicationset/releases/tag/v0.2.0
发布日期:2021/8/10

全新的功能

生成矩阵

矩阵生成器将两个生成器组合在一起,利用每个生成器检测到的内容来生成应用程序。

Spec的描述如下。

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: cluster-git
spec:
  generators:
    - matrix: # 'Parent' Matrix Generator
        generators:
          - git: # 'Child' generator A
              repoURL: https://github.com/argoproj-labs/applicationset.git
              revision: HEAD
              directories:
                - path: examples/matrix/cluster-addons/*
          - clusters: # 'Child' generator B
              selector:
                matchLabels:
                  argocd.argoproj.io/secret-type: cluster
  template:
  # (...)

样本可从https://github.com/argoproj-labs/applicationset/releases/tag/v0.2.0提取。

通过此生成器,可以实现将多个应用程序在多个集群上以一个ApplicationSet进行部署的功能。

供应链管理提供商生成器

SCM Provider generator 是一个新的生成器,利用 GitHub/GitLab 的 API 来自动发现组织内的仓库,并使得生成的 Argo CD 应用的目标可以使用仓库的值。它非常适用于将微服务分解为多个仓库的 GitOps 布局模式,并比固守于单个仓库的模式更加合适(后者可以由其他 ApplicationSet 生成器处理)。

Spec的描述如下。

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: myapps
spec:
  generators:
  - scmProvider:
      github:
        organization: myorg         # The GitHub organization to scan.
        tokenRef: { } # Reference to a Secret containing an access token. (optional)
  template:
  # ...

样本是从https://github.com/argoproj-labs/applicationset/releases/tag/v0.2.0 中提取的。

如果我们能够在团队内制定好规则,看起来我们应该可以很好地管理应用程序。
虽然在发布说明中没有写,但似乎可以按分支或存储库标签进行筛选。
我个人有些事情想按拉取请求的单元来处理,但这样做无法解决问题,让我很困扰。

聚类决策资源生成器

Cluster Decision Resource generator是一个新的生成器,它基于外部自定义资源(CR)的内容来生成Argo CD集群列表,这些自定义资源由外部控制器进行管理。该生成器可以将决定哪个集群作为目标的逻辑“外包”给第三方控制器/CR,类似于Open Cluster Management的Placements。

这是一个使用鸭子类型来无缝处理不需要完全了解被引用的Kubernetes资源形状的知识的例子。以下是基于cluster-decision-resource的ApplicationSet生成器的示例。

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
 name: guestbook
spec:
 generators:
 - clusterDecisionResource:
    # ConfigMap with GVK information for the duck type resource
    configMapRef: my-configmap      
    name: quak  # Choose either "name" of the resource or "labelSelector"
apiVersion: mallard.io/v1beta1
kind: Duck
metadata:
  name: quak
spec: {}
status:
  decisions:   # Duck-typing ignores all other aspects of the resource except the "decisions" list
  - clusterName: cluster-01
  - clusterName: cluster-02
apiVersion: v1
kind: ConfigMap
metadata:
  name: my-configmap
data:
  # apiVersion of the target resource
  apiVersion: mallard.io/v1beta1  
  # kind of the target resource
  kind: ducks
  # status key name that holds the list of Argo CD clusters
  statusListKey: decisions
  # The key in the status list whose value is the cluster name found in Argo CD
  matchKey: clusterName

抽取样本请访问以下链接:https://github.com/argoproj-labs/applicationset/releases/tag/v0.2.0

Open Cluster Management的Placements似乎是指https://open-cluster-management.io/concepts/placement/,看起来是用于管理多集群的机制。我个人认为它有一些有趣的用途,但目前还没有发现有用的使用案例。

删除父级 ApplicationSet 时,保留 Application 子资源。

默认情况下,Argo CD应用程序集控制器会创建和管理应用程序,并包含资源删除finalizer。换句话说,当应用程序集被删除时,其子应用程序也会被删除,并且子应用程序的集群资源也会被删除。这与Argo CD的级联删除行为相同。

然而,这种行为并不一定是理想的。即使父应用程序被删除,也可能希望保留子应用程序的资源。要实现这一点,可以在父级的 ApplicationSet 中使用.spec.syncPolicy.prespreserveResourcesOnDeletion值。

kind: ApplicationSet
spec:
  generators:
    - clusters: {}
  template:
    # (...)
  syncPolicy:
    # Don't delete Application's child resources, on parent deletion:
    preserveResourcesOnDeletion: true

当在进行ApplicationSet的迁移时,如果缺少了我想要的功能,那么在部署Application资源时会导致已经部署的资源被删除,从而造成应用程序的停机时间,这让我很困扰。但是,由于添加了这个功能,现在我们可以无需删除而进行迁移。

给Git文件生成器添加YAML配置文件支持

在 ApplicationSet 的之前版本中,只有 JSON 格式的配置文件才受 Git 文件生成器支持。而在本次发布中,JSON 和 YAML 格式的文件都得到了支持,并且可以兼容性地使用。

允许列表生成器中的任意键/值对。

列表生成器以前仅支持簇名称/URL值的固定列表,但提供了用于用户自定义值的值字段选项。现在,可以指定任意键/值的配对。

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
spec:
 generators:
 - list:
     elements:
     # current form, still supported:
     - cluster: engineering-dev
       url: https://kubernetes.default.svc
       values:
         additional: value
     # new form, does not require cluster/URL keys:
     - staging: true
       gitRepo: https://kubernetes.default.svc   
 template:
   # (...)

我在这个链接(https://qiita.com/shmurata/items/a6ee4193e2d2c8a2d34c#list-generator)中说的事情,现在已经可以进行指定了。

在Git文件生成器中添加了额外的路径参数

Git File generator现在可以生成{{ path }}和{{ path.basename }}参数。这与Git Directory生成器生成的参数相同,包含了配置文件的路径。

给Git目录添加排除路径支持

Git Directory Generator是用于扫描Git仓库内的目录并查找符合特定条件的目录的工具。然而,在之前的ApplicationSet发布中,我们无法排除扫描目标中的文件夹。

在本次发布中,现在可以将个别路径排除在扫描范围之外。

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: cluster-addons
spec:
  generators:
  - git:
      repoURL: https://github.com/argoproj-labs/applicationset.git
      revision: HEAD
      directories:
      # Include this first path 
      - path: examples/git-generator-directory/excludes/cluster-addons/* 
      # But, exclude this second path:
      - path: examples/git-generator-directory/excludes/cluster-addons/exclude-helm-guestbook
        exclude: true

提高生活质量

    • Gitディレクトリジェネレータが’.’で始まるすべてのフォルダを無視するようになりました

 

    • アプリケーションのテンプレートにカスタムの’finalizer’をサポートするようになりました

 

    • ApplicationSetコントローラの起動時にログレベルを設定する機能を有効になりました

 

    • ApplicationSetのCRDに’appset/appsets’のショートネームを追加されました

 

    コントローラ起動時のログにappsetのバージョンを記録するようになりました

除了其他一些细微的bug修复,还有一些其他变化,请参考发布说明。

版本号为v0.3.0。

发布说明:https://github.com/argoproj-labs/applicationset/releases/tag/v0.3.0
发布日期:2021/12/16

新功能

生成拉取请求

在ApplicationSet v0.3.0中,我们添加了一个新的Pull Request生成器,它利用SCMaaS提供商(例如:GitHub)的API来自动检测仓库中的公开Pull Request。这对于希望基于已发布的Pull Request来构建测试环境的用户非常适用。

在这个示例中,我们会为每个开放的拉取请求创建一个 Argo CD 应用资源。

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: myapps
spec:
  generators:
  - pullRequest:
      github:
        # The GitHub organization or user.
        owner: myorg
        # The Github repository
        repo: myrepository
        # For GitHub Enterprise (optional)
        api: https://git.example.com/
        # Reference to a Secret containing an access token. (optional)
        tokenRef:
          secretName: github-token
          key: token
        # Labels is used to filter the PRs that you want to target. (optional)
        labels:
        - preview
  template:
  # ...

我在我的团队中,当有PR被提出时,我会自动创建预览环境。但是由于在ApplicationSet中无法实现这个复制,所以我贡献了一个生成器并加以补充。

合并发电机

如果想要选择性地用一个生成器生成的参数来覆盖另一个生成器生成的参数,这个生成器会非常方便。

在这个例子中,首先从Argo CD收集集群列表,然后仅对具有use-kakfa: false标签的集群进行“补丁”,最后在特定集群上启用redis。

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: cluster-git
spec:
  generators:
    # merge 'parent' generator
    - merge:
        mergeKeys:
          - server
        generators:
          # Generate parameters for all Argo CD clusters
          - clusters:
              values:
                kafka: 'true'
                redis: 'false'
          # For clusters with a specific label, enable Kafka.
          - clusters:
              selector:
                matchLabels:
                  use-kafka: 'false'
              values:
                kafka: 'false'
          # For a specific cluster, enable Redis.
          - list:
              elements: 
                - server: https://2.4.6.8
                  values.redis: 'true'

这个功能很难仅仅通过查看规范就能预测其操作,但建议您查看文档中的详细说明。简单来说,它会按照从上到下的顺序,对与mergeKeys指定的键值相匹配的目标进行覆盖其他键值的操作。(结果是下面所列值的优先级较高)

应用集CR的错误条件/状态的报告

如果用户使用提供的生成器或模板生成了无效的Argo CD应用程序,则会在ApplicationSet资源的状态字段中显示错误。例如,如下所示。

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: myapps
spec:
  generators: # (...)
  template: # (...)
status:
  conditions:
  - lastTransitionTime: "2021-11-23T05:47:08Z"
    type: ErrorOccurred
    status: "False"
    reason: ApplicationSetUpToDate
    message: Successfully generated parameters for all Applications
  - lastTransitionTime: "2021-11-23T05:47:08Z"
    type: ParametersGenerated
    message: Successfully generated parameters for all Applications
    reason: ParametersGenerated
    status: "True"
  - lastTransitionTime: "2021-11-23T05:47:08Z"
    type: ResourcesUpToDate
    status: "True"
    reason: ApplicationSetUpToDate
    message: ApplicationSet up to date

Git生成器:使用webhook刷新应用集资源的Git生成器。

这个功能支持通过GitHub/GitLab webhook触发更新ApplicationSet。此功能公开一个服务来监听接收的Webhook payload,一旦收到,就会触发ApplicationSet控制器重新生成资源。而在之前的发布版本中,ApplicationSet控制器只支持每3分钟轮询Git生成器使用的Git仓库(但至少这是可定制的)。

这是关于向Webhook中添加功能以便检测仓库差异,以前是通过轮询来进行检测的对话。

拉取请求生成器:支持 Webhooks

如果使用Pull Request Generator,在应用集控制器将会通过requeueAfterSeconds间隔(默认为每30分钟)进行轮询以检测变更。为了消除这种轮询带来的延迟,可以设置ApplicationSet的Webhook服务器来接收Webhook事件,这也是Pull Request Generator支持的功能。

与git generator类似,pull requests generator也通过webhook添加了差异检测功能。

支持将-logformat=json作为应用程序集控制器的参数。

增加了一个选项,可以将applicationset-controller的日志输出更改为json格式。

SCM生成器:在变量中提供分支上最新提交的SHA。

SCM生成器中已添加了最新提交哈希(SHA)参数。

提高Git文件生成器的性能

由于 Git 文件生成功能在存储库中发现的每个文件上不加思索地执行 git fetch/git checkout,所以花费的时间过长(增加了 Git 请求)。在 ApplicationSet v0.3.0 中,这个问题得到了改进,现在每次更新只会发出一次 Git checkout/fetch 请求。

升级说明

如果从0.1.0/0.2.0升级到0.3.0,有两个行为变化。

集群生成器的 {{name}} 参数的值不再被规范化。

聚类生成器的{{name}}参数已恢复到原始操作。Argo CD中的集群名称不再被规范化。ApplicationSet中由聚类生成器生成的{{name}}参数将直接传递到ApplicationSet模板中。

引入了新的参数{{nameNormalized}}来维持0.2.0版本的功能。这使得您可以选择在定义参数后直接使用它,或者以规范化的形式使用(在Application资源的name字段中可用),根据情况选择在ApplicationSet中使用。

如果 Argo CD 的集群名称已经有效,就不需要进行更改。但是,为了保持应用程序集的 v0.2.0 版本的运行,您需要在应用程序集模板中将 {{name}} 替换为 {{nameNormalized}}。

正规化指的是对此代码进行处理,调整字符和字符数量,以便可以将其作为域名使用。请参阅代码以获取更多详细信息。

即使在ApplicationSet中包含无效的生成应用,有效的生成应用也会被处理。

ApplicationSet控制器的职责是将一个或多个ApplicationSet资源转换为一个或多个Application资源。但是,在之前的发布版本中,如果生成的应用资源中至少有一个无效(例如,内部验证逻辑失败),那么生成的应用程序将不会被处理(也不会被创建或修改)。

在最新的ApplicationSet发布中,如果生成器生成了无效的Application,那么这些无效的生成的Application仍然会被跳过,但是有效的生成的Application会被处理(创建/修改)。

因此,在本次升级中,不需要更改ApplicationSet的资源,但需要记住由于失败的应用程序而被阻止的ApplicationSet可能不再被阻止。这个变更可能使之前未处理的有效应用程序得以创建/更改。

我之前没有意识到,但是如果在一个 ApplicationSet 资源下生成的 Application 中存在任何不合法的情况,生成所有从该 ApplicationSet 生成的 Application 的过程都会被停止。这个修正将使得只有有问题的 Application 不再被生成。

请查阅发布说明以获取其他细微错误修复等信息。

最终

我总结了关于 ArgoCD ApplicationSet v0.2.0/0.3.0 的变更内容。由于 ApplicationSet 还处于初期阶段,所以尽管是一个小工具,但有很多重大的变更,因此很难理解这些变更点。但与此同时,如果您想添加新功能,似乎可以轻松地接受更改,所以如果有改进的地方,可以创建一个 issue 或者进行贡献,我觉得会很不错。

bannerAds