Kubernetes中Argo CD ApplicationSet Generators的艺术

360影视 欧美动漫 2025-03-21 23:16 3

摘要:解锁云原生新姿势!本文详解如何用 Argo CD ApplicationSet 和 Git Generator,基于 GitOps 轻松管理 Kubernetes 集群。通过 Helm chart 模板化部署,实现跨环境应用和组件的自动化配置与同步,告别手动部

解锁云原生新姿势!本文详解如何用 Argo CD ApplicationSet 和 Git Generator,基于 GitOps 轻松管理 Kubernetes 集群。通过 Helm chart 模板化部署,实现跨环境应用和组件的自动化配置与同步,告别手动部署烦恼!

译自:The Art of Argo CD ApplicationSet Generators with Kubernetes - Piotr's TechBlog

本文将教你如何使用 Argo CD ApplicationSet 生成器,通过 GitOps 方法来管理你的 Kubernetes 集群。Argo CD ApplicationSet 是一种 Kubernetes 资源,允许我们管理和部署多个 Argo CD 应用程序。它基于给定的模板动态生成多个 Argo CD 应用程序。因此,我们可以跨多个 Kubernetes 集群部署应用程序,为不同的环境(例如,开发、测试、生产)创建应用程序,并管理许多存储库或分支。通过最少的源代码工作,一切都可以轻松实现。

Argo CD ApplicationSet 支持几种不同的生成器。在本文中,我们将重点介绍 Git 生成器类型。它基于 Git 存储库中的目录结构或分支更改生成 Argo CD 应用程序。它包含两个子类型:Git 目录生成器和 Git 文件生成器。如果你对其他 Argo CD ApplicationSet 生成器感兴趣,你可以在我的博客上找到一些文章。例如,以下文章展示了如何使用 List Generator 在环境之间提升镜像。你还可以找到一篇关于集群决策资源生成器的文章,该文章展示了如何在多个 Kubernetes 集群之间动态传播应用程序。

如果你想自己尝试,请随时使用我的源代码。为此,你必须克隆我的示例 GitHub存储库。你必须转到 appset-helm-demo 目录,其中包含该练习所需的完整配置。然后,你只需按照我的说明进行操作即可。

Argo CD 是我们唯一需要在 Kubernetes 集群上安装的工具。我们可以使用官方 Helm chart 在 Kubernetes 上安装它。首先,让我们添加以下 Helm 存储库:

helm repo add argo https://argoproj.github.io/argo-helm

之后,我们可以使用以下命令在 argocd 命名空间中的当前 Kubernetes 集群中安装 ArgoCD:

helm install my-argo-cd argo/argo-cd -n argocd

我在本练习中使用 OpenShift。使用 OpenShift 控制台,我可以轻松地使用 OpenShift GitOps operator 在集群上安装 ArgoCD。

安装完成后,我们可以轻松访问 Argo CD 仪表板。

我们可以使用 OpenShift 凭据在那里登录。

在本练习中,我们的目标是在 Kubernetes 上部署和运行一些应用程序(一个简单的 Java 应用程序和 Postgres 数据库),并尽量减少源代码工作。这两个应用程序仅展示了如何创建一个标准,该标准可以轻松应用于部署在集群上的任何应用程序类型。在此标准中,目录结构决定了我们的应用程序在 Kubernetes 上的部署方式和位置。我的示例配置存储在单个 Git 存储库中。但是,我们可以使用多个存储库轻松地对其进行扩展,其中 Argoc CD 在中央存储库和其他包含具体应用程序配置的 Git 存储库之间切换。

这是用于部署我们的两个应用程序的目录结构和文件。自定义应用程序和 Postgres 数据库都部署在三个环境中:dev、test 和 prod。我们使用 Helm chart 来部署它们。每个环境目录都包含一个带有安装参数的 Helm values 文件。该配置区分了两种不同的安装类型:应用程序和组件。每个应用程序都使用专用于标准部署的相同 Helm chart 进行安装。每个组件都使用该组件提供的自定义 Helm chart 进行安装。例如,对于 Postgres,我们将使用以下 Bitnami chart。

.├── apps│ ├── aaa-1│ │ └── basic│ │ ├── prod│ │ │ └── values.YAML│ │ ├── test│ │ │ └── values.yaml│ │ ├── uat│ │ │ └── values.yaml│ │ └── values.yaml│ ├── aaa-2│ └── aaa-3└── components└── aaa-1└── postgresql├── prod│ ├── config.yaml│ └── values.yaml├── test│ ├── config.yaml│ └── values.yaml└── uat├── config.yaml└── values.yaml

在部署应用程序之前,我们应该准备带有配额的命名空间、Argo CD 项目和 ApplicationSet 生成器,以管理应用程序部署。以下是全局配置仓库的结构。它还使用 Helm chart 将清单的该部分应用于 Kubernetes 集群。projects 目录中的每个目录都决定了我们的项目名称。另一方面,一个项目包含多个 Kubernetes 命名空间。每个项目可能包含几个不同的 Kubernetes 部署。

.└── projects├── aaa-1│ └── values.yaml├── aaa-2│ └── values.yaml└── aaa-3└── values.yaml

以下是用于为每个命名空间创建命名空间和配额的 Helm 模板。我们将为每个环境(阶段)创建一个项目命名空间。

{{- range .Values.stages }}---apiVersion: v1kind: Namespacemetadata:name: {{ $.Values.projectName }}-{{ .name }}---apiVersion: v1kind: ResourceQuotametadata:name: default-quotanamespace: {{ $.Values.projectName }}-{{ .name }}spec:hard:{{- if .config }}{{- with .config.quotas }}pods: {{ .pods | default "10" }}Requests.CPU: {{ .cpuRequest | default "2" }}requests.memory: {{ .memoryRequest | default "2Gi" }}limits.cpu: {{ .cpuLimit | default "8" }}limits.memory: {{ .memoryLimit | default "8Gi" }}{{- end }}{{- else }}pods: "10"requests.cpu: "2"requests.memory: "2Gi"limits.cpu: "8"limits.memory: "8Gi"{{- end }}{{- end }}

chart/templates/namespace.yaml

Helm chart 还会为我们的每个项目创建一个专用的 Argo CD AppProject 对象。

apiVersion: argoproj.io/v1alpha1kind: AppProjectmetadata:name: {{ .Values.projectName }}namespace: {{ .Values.argoNamespace | default "argocd" }}spec:clusterResourceWhitelist:- group: '*'kind: '*'destinations:- namespace: '*'server: '*'sourceRepos:- '*'

chart/templates/appproject.yaml

之后,我们可以继续进行我们练习中最棘手的部分。Helm chart 还定义了一个用于创建 Argo CD ApplicationSet 的模板。此 ApplicationSet 必须分析存储库结构,其中包含应用程序和组件的配置。我们为每个项目定义两个 ApplicationSet。第一个使用 Git Directory 生成器来确定 apps 目录的结构,并使用我的自定义 spring-boot-api-app chart 在所有环境中部署应用程序。可以使用放置在每个应用程序目录中的 Helm 值覆盖 chart 参数。

第二个 ApplicationSet 使用 Git Files 生成器来确定 components 目录的结构。它读取每个目录中 config.yaml 文件的内容。config.yaml 文件设置 Helm chart 的存储库、名称和版本,该 chart 必须用于在 Kubernetes 上安装组件。

apiVersion: argoproj.io/v1alpha1kind: ApplicationSetmetadata:name: '{{ .Values.projectName }}-apps-config'namespace: {{ .Values.argoNamespace | default "argocd" }}spec:goTemplate: truegenerators:- git:repoURL: https://github.com/piomin/argocd-showcase.gitrevision: HEADdirectories:{{- range .Values.stages }}- path: appset-helm-demo/apps/{{ $.Values.projectName }}/*/{{ .name }}{{- end }}template:metadata:name: '{{`{{ index .path.segments 3 }}`}}-{{`{{ index .path.segments 4 }}`}}'spec:destination:namespace: '{{`{{ index .path.segments 2 }}`}}-{{`{{ index .path.segments 4 }}`}}'server: 'https://kubernetes.default.svc'project: '{{ .Values.projectName }}'sources:- chart: spring-boot-api-apprepoURL: 'https://piomin.github.io/helm-charts/'targetRevision: 0.3.8helm:valueFiles:- $values/appset-helm-demo/apps/{{ .Values.projectName }}/{{`{{ index .path.segments 3 }}`}}/{{`{{ index .path.segments 4 }}`}}/values.yamlparameters:- name: appNamevalue: '{{ .Values.projectName }}'- repoURL: 'https://github.com/piomin/argocd-showcase.git'targetRevision: HEADref: valuessyncPolicy:automated:prune: trueselfHeal: true---apiVersion: argoproj.io/v1alpha1kind: ApplicationSetmetadata:name: '{{ .Values.projectName }}-components-config'namespace: {{ .Values.argoNamespace | default "argocd" }}spec:goTemplate: truegenerators:- git:repoURL: https://github.com/piomin/argocd-showcase.gitrevision: HEADfiles:{{- range .Values.stages }}- path: appset-helm-demo/components/{{ $.Values.projectName }}/*/{{ .name }}/config.yaml{{- end }}template:metadata:name: '{{`{{ index .path.segments 3 }}`}}-{{`{{ index .path.segments 4 }}`}}'spec:destination:namespace: '{{`{{ index .path.segments 2 }}`}}-{{`{{ index .path.segments 4 }}`}}'server: 'https://kubernetes.default.svc'project: '{{ .Values.projectName }}'sources:- chart: '{{`{{ .chart.name }}`}}'repoURL: '{{`{{ .chart.repository }}`}}'targetRevision: '{{`{{ .chart.version }}`}}'helm:valueFiles:- $values/appset-helm-demo/components/{{ .Values.projectName }}/{{`{{ index .path.segments 3 }}`}}/{{`{{ index .path.segments 4 }}`}}/values.yamlparameters:- name: appNamevalue: '{{ .Values.projectName }}'- repoURL: 'https://github.com/piomin/argocd-showcase.git'targetRevision: HEADref: valuessyncPolicy:automated:prune: trueselfHeal: true

chart/templates/applicationsets.yaml 在此配置中有几个重要的元素,我们应该注意。Helm 和 ApplicationSet 都使用基于 {{ ... }} 占位符的模板引擎。因此,为了避免冲突,我们应该从 Helm 模板元素中转义 Argo CD ApplicationSet 模板元素。模板中负责生成 Argo CD 应用程序名称的以下部分是该方法的一个很好的例子: '{{{{ index .path.segments 3 }}}}-{{{{ index .path.segments 4 }}}}'。首先,我们使用 AppliocationSet Git 生成器参数 index .path.segments 3,它返回目录路径的第三部分的名称。这些元素使用 ``` 字符进行转义,因此 Helm 不会尝试分析它。

我们的 ApplicationSets 使用“应用程序的多个来源”功能从 Helm values 文件中读取参数,并将它们从远程存储库注入到 Helm chart 中。因此,我们的应用程序和组件的配置存储库仅包含标准化目录结构中的 values.yaml 文件。我们存储在示例存储库中的唯一 chart 已在上面描述,它负责创建在集群上运行应用程序部署所需的配置。

.└── chart├── Chart.yaml├── templates│ ├── additional.yaml│ ├── applicationsets.yaml│ ├── appproject.yaml│ └── namespaces.yaml└── values.yaml

ShellSession 默认情况下,每个项目定义三个环境(阶段):test、uat 和 prod。

stages:- name: testadditionalObjects: {}- name: uatadditionalObjects: {}- name: prodadditionalObjects: {}

chart/values.yml 我们可以覆盖 Helm values 中特定项目的默认行为。每个项目目录都包含 values.yaml 文件。以下是 aaa-3 项目的 Helm 参数,它仅针对 test 环境将 CPU 请求配额从 2 个 CPU 覆盖为 4 个 CPU。

stages:- name: testconfig:quotas:cpuRequest: 4additionalObjects: {}- name: uatadditionalObjects: {}- name: prodadditionalObjects: {}

projects/aaa-3/values.yaml

要启动一个过程,我们必须创建读取项目目录结构的 ApplicationSet。projects 目录中的每个子目录都指示我们项目的名称。我们的 ApplicationSet 使用 Git 目录生成器为每个项目创建一个 Argo CD 应用程序。它的名称包含子目录的名称和 config 后缀。每个生成的应用程序都使用先前描述的 Helm chart 来创建项目请求的所有命名空间、配额和其他资源。它还利用“应用程序的多个来源”功能,允许我们覆盖默认的 Helm chart 设置。它从目录名称读取项目名称,并将其作为参数传递给生成的 Argo CD 应用程序。

apiVersion: argoproj.io/v1alpha1kind: ApplicationSetmetadata:name: global-confignamespace: openshift-gitopsspec:goTemplate: truegenerators:- git:repoURL: https://github.com/piomin/argocd-showcase.gitrevision: HEADdirectories:- path: appset-helm-demo/projects/*template:metadata:name: '{{.path.basename}}-config'spec:destination:namespace: '{{.path.basename}}'server: 'https://kubernetes.default.svc'project: defaultsources:- path: appset-helm-demo/chartrepoURL: 'https://github.com/piomin/argocd-showcase.git'targetRevision: HEADhelm:valueFiles:- $values/appset-helm-demo/projects/{{.path.basename}}/values.yamlparameters:- name: projectNamevalue: '{{.path.basename}}'- name: argoNamespacevalue: openshift-gitops- repoURL: 'https://github.com/piomin/argocd-showcase.git'targetRevision: HEADref: valuessyncPolicy:automated:prune: trueselfHeal: true

YAML 一旦我们创建了 global-configApplicationSet 对象,奇迹就会发生。以下是从 Git 配置存储库中的目录生成的 Argo CD 应用程序的列表。

argo-cd-applicationset-all-apps

首先,有三个带有项目配置的 Argo CD 应用程序。这是因为我们在 projects 目录中定义了 3 个子目录,名称为 aaa-1、aaa-2 和 aaa-3。


那些 Argo CD 应用程序所应用的配置非常相似,因为它们使用的是同一个 Helm chart。我们可以查看由 aaa-3-configApplication 管理的资源列表。这里有三个命名空间(aaa-3-test、aaa-3-uat、aaa-3-prod),它们带有资源配额,一个单独的 Argo CD AppProject,以及两个 ApplicationSet 对象,负责为 apps 和 components 目录生成 Argo CD 应用程序。

argo-cd-applicationset-global-config

在这个配置中,我们可以验证 request.cpuResourceQuota 对象的值是否已从 2 个 CPU 覆盖为 4 个 CPU。

让我们分析一下发生了什么。以下是 Argo CD ApplicationSets 的列表。global-configApplicationSet 为 projects 目录中检测到的每个项目生成 Argo CD 应用程序。然后,这些应用程序中的每一个都使用 Helm 模板将两个 ApplicationSet 对象应用到集群。

$ kubectl get applicationsetNAME AGEaaa-1-components-config 29maaa-1-apps-config 29maaa-2-components-config 29maaa-2-apps-config 29maaa-3-components-config 29maaa-3-apps-config 29mglobal-config 29m

以下是已创建的命名空间的列表:

$ kubectl get nsNAME STATUS AGEaaa-1-prod Active 34maaa-1-test Active 34maaa-1-uat Active 34maaa-2-prod Active 34maaa-2-test Active 34maaa-2-uat Active 34maaa-3-prod Active 34maaa-3-test Active 34maaa-3-uat Active 34m生成和应用部署

我们的示例配置仅包含两个 Deployment。我们在 aaa-1 项目中的 apps 目录中定义了 basic 子目录,在 components 目录中定义了 postgres 子目录。为了简化,aaa-2 和 aaa-3 项目不包含任何 Deployment。但是,我们在其中创建的带有 values.yaml 文件的子目录越多,部署在集群上的应用程序就越多。以下是使用标准 Helm chart 部署的简单应用程序的典型 values.yaml 文件。它定义了镜像仓库、名称和标签。它还设置了 Deployment 名称和环境。

image:repository: piomin/basictag: 1.0.0app:name: basicenvironment: prod

对于 postgres 组件,我们必须在 Helm values 中设置更多参数。以下是最终列表:

global:compatibility:openshift:adaptSecurityContext: forceimage:tag: 1-54registry: registry.redhat.iorepository: rhel9/postgresql-15primary:containerSecurityContext:readOnlyRootFilesystem: falsepersistence:mountPath: /var/lib/pgsqlextraEnvVars:- name: POSTGRESQL_ADMIN_PASSWORDvalue: postgresql123postgresqlDataDir: /var/lib/pgsql/data

以下 Argo CD 应用程序由 aaa-1-apps-configApplicationSet 生成。它检测到 apps 目录中的 basic 子目录。basic 子目录包含 3 个子目录:带有 values.yaml 文件的 test、uat 和 prod。因此,我们有每个环境的 Argo CD 负责在目标命名空间中部署 basic 应用程序。

以下是由 basic-prodApplication 管理的资源列表。它使用我的自定义 Helm chart 并将 Deployment 和 Service 对象应用到集群。

以下 Argo CD 应用程序由 aaa-1-components-configApplicationSet 生成。它检测到 components 目录中的 basic 子目录。postgres 子目录包含 3 个子目录:带有 values.yaml 和 config.yaml 文件的 test、uat 和 prod。ApplicationSet Files 生成器从 config.yaml 文件中的配置读取仓库、名称和版本。

以下是带有 Bitnami Postgres chart 设置的 config.yaml 文件。我们可以将我们想要在集群上安装的其他任何 chart 放在这里。

chart:repository: https://charts.bitnami.com/bitnaminame: postgresqlversion: 15.5.38

以下是由生成的 Argo CD 应用程序使用的 Bitnami Helm chart 安装的资源列表。

argo-cd-applicationset-postgres

本文证明了 Argo CD ApplicationSet 和 Helm 模板可以一起使用来创建高级配置结构。它展示了如何使用 ApplicationSet Git Directory 和 Files generators 来分析 Git config 仓库中目录和文件的结构。通过这种方法,我们可以提出整个组织中配置结构的标准化,并将其类似地传播到 Kubernetes 集群中部署的所有应用程序。一切都可以在集群管理员级别轻松管理,只需使用访问许多不同配置仓库的单个全局 Argo CD ApplicationSet。

来源:勇往直前加油

相关推荐