Skip to content

Git 生成器

Git 生成器包含两个子类型:Git 目录生成器和 Git 文件生成器。

警告 Git 生成器通常用于方便(非管理员)开发人员创建应用程序。 如果 ApplicationSet 中的 project 字段是模板化的,开发人员可能会在权限过大的项目下创建应用程序。 对于带有模板化 project 字段的 ApplicationSet,真相来源 must 必须_由管理员控制 - 在 git 生成器的情况下,PR 必须需要管理员批准。

Git 生成器:目录

Git 目录生成器是 Git 生成器的两个子类型之一,它使用指定 Git 仓库的目录结构生成参数。

假设您有一个 Git 仓库,其目录结构如下:

├── argo-workflows
│   ├── kustomization.yaml
│   └── namespace-install.yaml
└── prometheus-operator
    ├── Chart.yaml
    ├── README.md
    ├── requirements.yaml
    └── values.yaml

该资源库包含两个目录,每个目录对应一个要部署的工作负载:

  • Argo 工作流程控制器 kustomize YAML 文件
  • 一个 Prometheus Operator Helm 图表

我们可以通过这个例子,部署这两种工作负载:

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: cluster-addons
  namespace: argocd
spec:
  goTemplate: true
  goTemplateOptions: ["missingkey=error"]
  generators:
  - git:
      repoURL: https://github.com/argoproj/argo-cd.git
      revision: HEAD
      directories:
      - path: applicationset/examples/git-generator-directory/cluster-addons/*
  template:
    metadata:
      name: '{{.path.basename}}'
    spec:
      project: "my-project"
      source:
        repoURL: https://github.com/argoproj/argo-cd.git
        targetRevision: HEAD
        path: '{{.path.path}}'
      destination:
        server: https://kubernetes.default.svc
        namespace: '{{.path.basename}}'
      syncPolicy:
        syncOptions:
        - CreateNamespace=true

完整示例见 此处

发电机参数为

  • {{.path.path}}:Git 仓库中与path` 通配符匹配的目录路径。
  • {{index .path.segments n}}:Git 仓库中与path通配符匹配的目录路径,分成数组元素(n - 数组索引)
  • {{.path.basename}}:对于 Git 仓库中任何与path通配符匹配的目录路径,将提取最右边的路径名(例如,/directory/directory2将产生directory2`)。
  • {{.path.basenameNormalized}}:该字段与path.basename相同,但会用-替换不支持的字符(例如,path/directory/directory_2path.basenamedirectory_2,则此处会生成directory-2`)。

注意:最右边的路径名总是变成"{{.path.basename}}"。 例如,对于"- path: /one/two/three/four","{{.path.basename}}"就是 "four"。

:如果指定了pathParamPrefix选项,则上述所有与path相关的参数名将以指定值和点号分隔符作为前缀。 例如,如果pathParamPrefixmyRepo,则生成的参数名将为.myRepo.path,而不是.path。 在两个子生成器均为 Git 生成器的矩阵生成器中,有必要引用该选项(以避免合并子生成器的项目时发生冲突)。

每当在 Git 仓库中添加新的 helm chart/Kustomize YAML/Application/plain 子目录时,ApplicationSet 控制器就会检测到这一变化,并自动在新的 Application 资源中配置由此产生的清单。

与其他生成器一样,集群必须已在 Argo CD 中定义,才能为其生成应用程序。

排除目录

Git 目录生成器会自动排除以.开头的目录(如.git)。

Git 目录生成器还支持 "exclude"(排除)选项,以便将版本库中的目录排除在 ApplicationSet 控制器的扫描范围之外:

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: cluster-addons
  namespace: argocd
spec:
  goTemplate: true
  goTemplateOptions: ["missingkey=error"]
  generators:
  - git:
      repoURL: https://github.com/argoproj/argo-cd.git
      revision: HEAD
      directories:
      - path: applicationset/examples/git-generator-directory/excludes/cluster-addons/*
      - path: applicationset/examples/git-generator-directory/excludes/cluster-addons/exclude-helm-guestbook
        exclude: true
  template:
    metadata:
      name: '{{.path.basename}}'
    spec:
      project: "my-project"
      source:
        repoURL: https://github.com/argoproj/argo-cd.git
        targetRevision: HEAD
        path: '{{.path.path}}'
      destination:
        server: https://kubernetes.default.svc
        namespace: '{{.path.basename}}'

完整示例见 此处

此示例从该 ApplicationSet 资源扫描的目录列表中排除了 exclude- helm-guestbook 目录。

注意 "排除规则的优先级高于包含规则"。

If a directory matches at least one `exclude` pattern, it will be excluded. Or, said another way, *exclude rules take precedence over include rules.*

As a corollary, which directories are included/excluded is not affected by the order of `path`s in the `directories` field list (because, as above, exclude rules always take precedence over include rules).

例如,这些目录

.
└── d
    ├── e
    ├── f
    └── g

假设您想包含 /d/e,但不包括 /d/f/d/g

- path: /d/e
  exclude: false
- path: /d/*
  exclude: true

因为 /d/* 排除规则优先于 /d/e 包括规则。 当 Git 仓库中的 /d/e 路径被 ApplicationSet 控制器处理时,控制器会检测到至少有一条排除规则匹配,因此不应扫描该目录。

您需要做的是

- path: /d/*
- path: /d/f
  exclude: true
- path: /d/g
  exclude: true

或者,更简短的方法(使用 path.Match 语法)是:

- path: /d/*
- path: /d/[fg]
  exclude: true

Git 仓库根目录

可以通过提供 '*' 作为 path 来配置 Git 目录生成器,以便从 git 仓库的根目录进行部署。

要排除目录,只需输入不想部署的目录的名称/path.Match

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: cluster-addons
  namespace: argocd
spec:
  goTemplate: true
  goTemplateOptions: ["missingkey=error"]
  generators:
  - git:
      repoURL: https://github.com/example/example-repo.git
      revision: HEAD
      directories:
      - path: '*'
      - path: donotdeploy
        exclude: true
  template:
    metadata:
      name: '{{.path.basename}}'
    spec:
      project: "my-project"
      source:
        repoURL: https://github.com/example/example-repo.git
        targetRevision: HEAD
        path: '{{.path.path}}'
      destination:
        server: https://kubernetes.default.svc
        namespace: '{{.path.basename}}'

通过 values 字段传递额外的键值对

您可以通过 git 目录生成器的 values 字段传递额外的任意字符串键值对。 通过 values 字段添加的值以 values.(field) 的形式添加。

在此示例中,传递了一个 cluster 参数值,它是从 branchpath 变量中插值出来的,然后被引用来确定目标名称空间。

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: cluster-addons
  namespace: argocd
spec:
  goTemplate: true
  goTemplateOptions: ["missingkey=error"]
  generators:
  - git:
      repoURL: https://github.com/example/example-repo.git
      revision: HEAD
      directories:
      - path: '*'
      values:
        cluster: '{{.branch}}-{{.path.basename}}'
  template:
    metadata:
      name: '{{.path.basename}}'
    spec:
      project: "my-project"
      source:
        repoURL: https://github.com/example/example-repo.git
        targetRevision: HEAD
        path: '{{.path.path}}'
      destination:
        server: https://kubernetes.default.svc
        namespace: '{{.values.cluster}}'

注意 values. 前缀总是被引用到通过 generators.git.values 字段提供的值中。 使用时请确保在 template 中的参数名称中包含此前缀。

values 中,我们还可以插值上述由 git 目录生成器设置的所有字段。

Git 生成器:文件

Git 文件生成器是 Git 生成器的第二个子类型。 Git 文件生成器使用在指定版本库中找到的 JSON/YAML 文件内容生成参数。

假设您有一个 Git 仓库,其目录结构如下:

├── apps
│   └── guestbook
│       ├── guestbook-ui-deployment.yaml
│       ├── guestbook-ui-svc.yaml
│       └── kustomization.yaml
├── cluster-config
│   └── engineering
│       ├── dev
│       │   └── config.json
│       └── prod
│           └── config.json
└── git-generator-files.yaml

这些目录是

  • guestbook "包含一个简单留言簿应用程序的 Kubernetes 资源
  • cluster-config 包含描述各个工程集群的 JSON/YAML 文件:一个用于dev,一个用于prod
  • git-generator-files.yaml是将guestbook部署到指定集群的示例ApplicationSet资源。

config.json 文件包含描述集群的信息(以及额外的示例数据):

{
  "aws_account": "123456",
  "asset_id": "11223344",
  "cluster": {
    "owner": "[email protected]",
    "name": "engineering-dev",
    "address": "https://1.2.3.4"
  }
}

Git 生成器会自动发现包含对 config.json 文件改动的 Git 提交,并解析这些文件的内容,将其转换为模板参数。 以下是为上述 JSON 生成的参数:

aws_account: 123456
asset_id: 11223344
cluster.owner: [email protected]
cluster.name: engineering-dev
cluster.address: https://1.2.3.4

所有发现的 config.json 文件的生成参数将被替换到 ApplicationSet 模板中:

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: guestbook
  namespace: argocd
spec:
  goTemplate: true
  goTemplateOptions: ["missingkey=error"]
  generators:
  - git:
      repoURL: https://github.com/argoproj/argo-cd.git
      revision: HEAD
      files:
      - path: "applicationset/examples/git-generator-files-discovery/cluster-config/**/config.json"
  template:
    metadata:
      name: '{{.cluster.name}}-guestbook'
    spec:
      project: default
      source:
        repoURL: https://github.com/argoproj/argo-cd.git
        targetRevision: HEAD
        path: "applicationset/examples/git-generator-files-discovery/apps/guestbook"
      destination:
        server: '{{.cluster.address}}'
        namespace: guestbook

完整示例见 此处

cluster-config 目录下找到的任何 config.json 文件都将根据指定的 path 通配符模式进行参数化。 每个文件中的 JSON 字段都会被扁平化为键/值对,本 ApplicationSet 示例在模板中使用了 cluster.addresscluster.name 参数。

与其他生成器一样,集群必须已在 Argo CD 中定义,才能为其生成应用程序。

除了配置文件中的扁平化键/值对,还提供了以下生成器参数:

  • {{.path.path}}:Git 仓库中包含匹配配置文件的目录的路径。例如:/clusters/clusterA,如果配置文件是/clusters/clusterA/config.json
  • {{索引 .路径 n}}:Git 仓库中匹配配置文件的路径,分为数组元素(n- 数组索引)。例如:index .path 0: 集群,index .path 1: 集群A`。
  • {{.path.basename}}:包含配置文件的目录的路径基名(如上例中的clusterA)。
  • {{.path.basenameNormalized}}:该字段与.path.basename相同,但会用-替换不支持的字符(例如,path/directory/directory_2.path.basenamedirectory_2,则此处会产生directory-2`)。
  • {{.path.filename}}:匹配的文件名。例如,上例中的config.json`。
  • {{.path.filenameNormalized}}:匹配的文件名,其中不支持的字符用-` 替换。

注意:最右边的_目录名总是变成{{.path.basename}}。 例如,从- path: /one/two/three/four/config.json开始,{{.path.basename}}将变成four。 文件名总是可以被{{.path.filename}}引用。

:如果指定了pathParamPrefix选项,则上述所有与path相关的参数名将以指定值和点号分隔符作为前缀。 例如,如果pathParamPrefixmyRepo,则生成的参数名将为myRepo.path,而不是path。 在两个子生成器均为 Git 生成器的矩阵生成器中,有必要引用该选项(以避免合并子生成器的项目时发生冲突)。

:Git 文件生成器的默认行为非常贪婪,请参阅 Git File Generator Globbing,了解更多信息。

通过 values 字段传递额外的键值对

您可以通过 git 文件生成器的 values 字段传递额外的任意字符串键值对。 通过 values 字段添加的值以 values.(field) 的形式添加。

在此示例中,传递了一个 base_dir 参数值,它是从 path 片段中插值出来的,然后用来确定源路径。

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: guestbook
  namespace: argocd
spec:
  goTemplate: true
  goTemplateOptions: ["missingkey=error"]
  generators:
  - git:
      repoURL: https://github.com/argoproj/argo-cd.git
      revision: HEAD
      files:
      - path: "applicationset/examples/git-generator-files-discovery/cluster-config/**/config.json"
      values:
        base_dir: "{{index .path 0}}/{{index .path 1}}/{{index .path 2}}"
  template:
    metadata:
      name: '{{.cluster.name}}-guestbook'
    spec:
      project: default
      source:
        repoURL: https://github.com/argoproj/argo-cd.git
        targetRevision: HEAD
        path: "{{.values.base_dir}}/apps/guestbook"
      destination:
        server: '{{.cluster.address}}'
        namespace: guestbook

注意 values. 前缀总是被引用到通过 generators.git.values 字段提供的值中。 使用时请确保在 template 中的参数名称中包含此前缀。

values 中,我们还可以插值上述由 git 文件生成器设置的所有字段。

Webhook 配置

使用 Git 生成器时,ApplicationSet 会每隔三分钟轮询一次 Git 仓库以检测更改。 为了消除轮询带来的延迟,可以配置 ApplicationSet webhook 服务器以接收 webhook 事件。 ApplicationSet 支持来自 GitHub 和 GitLab 的 Git webhook 通知。 下面将说明如何为 GitHub 配置 Git webhook,但相同的过程应适用于其他 Provider。

注意 ApplicationSet 控制器 webhook 使用的 webhook 与此处定义的 API 服务器不同。 ApplicationSet 将 webhook 服务器作为 ClusterIP 类型的服务公开。 需要创建一个 ApplicationSet 专用 ingress 资源,以便将此服务公开给 webhook 源。

1.在 Git Providers 中创建 webhook

在 Git Provider 中,导航至可配置 webhook 的设置页面。 在 Git Provider 中配置的有效载荷 URL 应使用 ApplicationSet 实例的 /api/webhook 端点(如 https://applicationset.example.com/api/webhook)。如果希望使用共享秘密,请在秘密中输入任意值。该值将在下一步配置 webhook 时被引用。

添加 Webhook

注意 在 GitHub 中创建 webhook 时,需要将 "内容类型 "设置为 "application/json"。 用于处理钩子的库不支持默认值 "application/x-www-form-urlencoded"。

2. 使用网络钩子秘密配置 ApplicationSet(可选)

配置 webhook 共享秘密是可选的,因为即使有未经验证的 webhook 事件,ApplicationSet 仍会刷新 Git 生成器生成的应用程序。 这样做是安全的,因为 webhook 有效载荷的内容被认为是不可信任的,只会导致应用程序的刷新(这个过程已经每隔三分钟发生一次)。 如果 ApplicationSet 可被公开访问,则建议配置 webhook 秘密,以防止 DDoS 攻击。

argocd-secret Kubernetes secret 中,包含步骤 1 中配置的 Git Provider 的 webhook secret。

编辑 Argo CD Kubernetes secret:

kubectl edit secret argocd-secret -n argocd

提示:为了方便输入秘密,Kubernetes 支持在 stringData 字段中输入秘密,这样就省去了对值进行 base64 编码并复制到 data 字段的麻烦。 只需将步骤 1 中创建的共享 webhook 秘密复制到 stringData 字段下相应的 GitHub/GitLab/BitBucket 密钥中即可:

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

保存后,请重新启动 ApplicationSet pod 使更改生效。