跳到主要内容

使用 Argo CD 管理

Argo CD 是面向 Kubernetes 的声明式 GitOps 持续交付工具。Argo CD Application 用于指定源仓库及版本、期望的 Kubernetes 配置和目标集群。Application Controller 会比较实际资源与期望状态,并手动或自动同步变更。

对于 APISIX 或 API7 Ingress Controller,Application 使用 Helm 根据 Git 中保存的配置渲染 Controller Chart。Argo CD 会协调渲染出的 Kubernetes 资源,但不会创建 Helm Release。该差异会影响 Chart 中准入 Webhook 证书和 CRD 的管理方式。

本指南介绍如何准备稳定的 Webhook 证书、创建 Controller Application、配置 CRD 所有权,以及协调 Gateway 和应用资源;还包括验证、OpenShift 和 ROSA 要求、升级与回滚。

前置条件

开始前,请确保满足以下要求:

  • 已完成为 GitOps 做准备中所述的仓库、资源所有权、CRD 和凭证准备。
  • 安装 Argo CD,并配置已认证的 argocd CLI。
  • 已有一个 AppProject,并将其限制到所选 Chart 仓库、目标命名空间和所需资源类型。除非 Argo CD 管理员另有限制,否则内置 default 项目的权限范围很宽。

示例使用 aic 作为目标命名空间。如果使用其他命名空间,请替换所有清单、命令和 Webhook Service DNS 名称中的 aic

示例 values 侧重 GitOps 所有权与协调,副本数、资源请求和 Pod 调度仍使用 Chart 默认值。用于生产前,请按工作负载配置容量、运行多个 Controller 副本,并将其分布到不同故障域。请参阅 AIC 高可用,并在目标集群中测试故障转移。当前固定版本 Chart 的 podDisruptionBudget.enabled 选项无法成功渲染;除非确认后续 Chart Release 已修复,否则不要启用。

提供稳定的 Webhook 证书

在 Argo CD 渲染并同步 Controller Chart 前,配置内容确定的证书。

当前 Chart 与 Argo CD 的限制

使用默认值 webhook.certificate.provided: false 时,示例中的 APISIX 和 API7 Chart 会在每次离线 Helm 渲染时生成新的准入 Webhook CA 和证书。Argo CD 渲染 Chart 时,Helm lookup 调用无法获取已有 Secret,因此 Secret 与 Webhook caBundle 可能长期处于 OutOfSync,或在自动同步期间发生轮换。

创建 Application 资源前,请选择 Argo CD 处理准入 Webhook 的方式:

方式结果建议
提供外部管理的证书保留准入验证并生成稳定的清单。推荐用于 Argo CD。平台必须管理证书及其轮换。
设置 webhook.enabled: false阻止 Chart 渲染 Webhook 资源,但会移除 Controller 的准入验证。仅当可以接受验证能力降低且已单独测试时使用。
保持启用 Chart 生成的证书Argo CD 重复渲染时会产生不同的期望清单。对于使用这些 Chart 版本且持续协调的 Application,请勿使用。

Application 示例保持启用 Webhook,并使用外部管理的证书。使用示例 Release 名称和 aic 命名空间时,请采用以下值:

产品证书 DNS 名称Secret 名称
APISIX Ingress Controllerapisix-ingress-controller-webhook-svc.aic.svcapisix-ingress-controller-webhook-cert
API7 Ingress Controllerapi7-ingress-controller-webhook-svc.aic.svcapi7-ingress-controller-webhook-cert

准备证书和 Secret:

  1. 签发可用于服务器身份验证的证书,并把证书 DNS 名称作为主题备用名称(SAN)。

  2. 配置目标集群的 Secret 管理器,在目标命名空间中创建对应 Secret。

  3. 把服务器证书和私钥分别存为 tls.crttls.key。不要在 Git 中存储私钥。

  4. 对签发 CA 证书进行编码:

    openssl base64 -A -in ca.crt
  5. 把 Application 中的 webhook.certificate.caBundle 设置为编码后的输出。示例使用 REPLACE_WITH_BASE64_CA_CERTIFICATE 占位符。

如果更改 releaseNamenameOverridefullnameOverride 或目标命名空间,请先渲染 Chart。检查 Deployment 的 webhook-certs Volume 以确定所需 Secret 名称,并检查 Webhook Service 以确定所需 DNS 名称。

这些 Chart 不使用 webhook.certificate.secretName,也不会从外部 Secret 读取 ca.crt;它们使用 webhook.certificate.caBundle 配置客户端对 Webhook 的信任。

如果续期证书仍由同一 CA 签发,请在证书过期前更新外部 Secret。Controller 会监视挂载的证书文件,并重新加载更新后的密钥对。

如果签发 CA 发生变化,请分阶段轮换信任。首先,把 caBundle 设置为旧 CA 与新 CA 的 PEM 证书拼接后经 Base64 编码的内容,然后同步 Application。接着,用新 CA 签发的服务器证书更新外部 Secret,并验证准入请求。只有所有 Controller Pod 都开始提供新证书后,才能从 caBundle 中移除旧 CA。两种轮换路径都应先在非生产集群中测试。

不要把宽泛的 Argo CD ignoreDifferences 规则作为常规解决方案。它们会隐藏真实的证书变化,并可能使 Webhook 配置与挂载的 Secret 使用不同的信任链。

如果决定接受较弱的验证,请把示例的整个 webhook 配置块替换为 webhook.enabled: false。在平台仓库中记录该决策,并把无效资源测试纳入不依赖准入机制的验证流程。

创建 Application

为所选 Controller 创建 Application。示例采用 Controller 管理 CRD 的模型,并使用前面准备的外部管理 Webhook 证书。

配置 Application 时,请应用为 GitOps 做准备中确定的 CRD 所有权策略:

  • 如果由 Controller Application 管理 Chart 自带 CRD,请保持 source.helm.skipCrds: false,对体积较大的 HTTPRoute CRD 使用 Server-Side Apply,并禁用 Prune。Argo CD 会把渲染出的 CRD 当作普通受跟踪资源;执行 Prune,或以级联删除方式删除 Application,可能会删除 CRD 及其自定义资源。
  • 如果由平台管理 CRD,请通过独立且固定版本的 Application 协调所需 Gateway API 与 APISIX CRD。等待它们报告 Established 状态后,把 Controller Application 的 source.helm.skipCrds 设为 true。应先协调并验证 CRD Application。不要使用 Sync Wave 为相互独立的 Application 排序;如果一个 Application 必须明确控制顺序,请采用 App of Apps 模式。

清单使用 valuesObject。应用前请确认当前 Argo CD 版本支持该字段。

目标命名空间(示例中为 aic)必须已经存在 APISIX Admin API Service、apisix-admin-key Secret 和 apisix-ingress-controller-webhook-cert Secret。

apisix-ingress-controller-application.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: apisix-ingress-controller
namespace: argocd
spec:
project: <app-project>
source:
repoURL: https://apache.github.io/apisix-helm-chart
chart: apisix-ingress-controller
targetRevision: 1.2.2
helm:
releaseName: apisix-ingress-controller
skipCrds: false
valuesObject:
webhook:
enabled: true
certificate:
provided: true
caBundle: REPLACE_WITH_BASE64_CA_CERTIFICATE
config:
provider:
type: apisix-standalone
gatewayProxy:
createDefault: true
provider:
type: ControlPlane
controlPlane:
service:
name: apisix-admin
port: 9180
auth:
type: AdminKey
adminKey:
valueFrom:
secretKeyRef:
name: apisix-admin-key
key: admin-key
destination:
server: https://kubernetes.default.svc
namespace: aic
syncPolicy:
retry:
limit: 5
backoff:
duration: 5s
factor: 2
maxDuration: 3m
syncOptions:
- ServerSideApply=true

有限重试策略用于处理首次安装时 Chart 在同一次同步中创建 CRD 和默认 GatewayProxy 的情况。Argo CD 只有在应用 CRD 后才能发现该自定义资源,因此重试可以在 Discovery 刷新后完成期望状态操作。

如果平台 Application 会先于 Controller Application 安装并验证 CRD,且没有其他临时依赖需要重试,请移除此策略。

ServerSideApply=true 允许 Application 创建 Chart 自带的大型 CRD。Server-Side Apply 会作用于 Application 中的所有资源,而不只是 CRD。如果其他协调器会修改相同对象,启用前请审查字段所有权。若要缩小所有权范围,请把 CRD 移到专用平台 Application,并在 Controller Application 上设置 skipCrds: true

如果禁用 Webhook,且同步前命名空间中不需要存在其他资源,可以在 syncOptions 中添加 CreateNamespace=true,让 Application 创建命名空间。

为 OpenShift 或 ROSA 调整工作流

Red Hat OpenShift GitOps 集成了 Argo CD,因此上述证书指南同样适用于 OpenShift 和 ROSA。同步 Application 前,请应用以下平台专用变更。把每个 Application 的 metadata.namespace 设置为 Argo CD 实例所在命名空间,通常为 openshift-gitops

确定 Gateway API CRD 所有权

根据 OpenShift 版本处理 Gateway API CRD:

  • 在 OpenShift 4.18 及更早版本中,默认不安装 Gateway API CRD。请由平台团队安装兼容的 CRD 包,或指定一个 GitOps Application 负责管理。
  • 从 OpenShift 4.19 开始,Ingress Operator 负责 Gateway API CRD 生命周期。请设置 skipCrds: true,不要应用 Chart 自带的 Gateway API CRD。OpenShift 4.19 引入平台管理的 Gateway API 1.2.1,而这些 Chart 包含 1.3.0 实验通道。请确认计划使用的资源类型和版本在集群中存在。

有关版本边界和所有权行为,请参阅 OpenShift 4.19 Release NotesRed Hat Gateway API 安装指南

必须设置 skipCrds: true 时,请通过集群基础设施 Application,只协调相同固定 Chart 版本中的 APISIX CRD 文件。APISIX Chart 中的文件为 crds/apisixic-crds.yaml,API7 Chart 中为 crds/apisix-crds.yaml。如果 Gateway API CRD 由 Ingress Operator 管理,不要包含 gwapi-crds.yaml

授予 SCC 访问权限

Chart 会创建名称与 helm.releaseName 一致的 ServiceAccount。请把以下资源保存在平台仓库中,并替换占位符:

ingress-controller-scc.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: <release-name>-nonroot-v2
namespace: <controller-namespace>
rules:
- apiGroups:
- security.openshift.io
resourceNames:
- nonroot-v2
resources:
- securitycontextconstraints
verbs:
- use
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: <release-name>-nonroot-v2
namespace: <controller-namespace>
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: <release-name>-nonroot-v2
subjects:
- kind: ServiceAccount
name: <release-name>
namespace: <controller-namespace>

对于 API7 Ingress Controller,还需要把以下值与 Dashboard 生成的 values 合并:

values-openshift.yaml
adc:
securityContext:
runAsUser: 65532

把 Controller 视为集群基础设施。Argo CD 实例需要有权管理目标命名空间、ClusterRole、IngressClass 和 Webhook 配置。CRD 与 SCC 策略决策应由集群管理员负责。不要对 Argo CD 管理的安装运行生成的命令式 Helm 命令。

网关组与网关实例工作流请参阅在 OpenShift 上安装 API7 Ingress Controller。启用自动同步前,请在目标 OpenShift 或 ROSA 版本上测试准确的 values 和权限。

同步 Application

在平台仓库中保存并提交 Application 清单。生产部署应由父 Application、ApplicationSet 或等效的引导流程协调该目录。

初次评估时,也可以直接创建 Controller Application:

kubectl apply -f <application-file>

直接应用文件并不会让 Application 清单之后的 Git 变更自动协调。用于生产前,请把它放入父级协调路径,而不是依赖重复执行 kubectl apply

检查首次差异、执行同步,并等待 Application:

argocd app diff <application-name>
argocd app sync <application-name>
argocd app wait <application-name> --health --sync --timeout 300

首次同步成功后执行 Hard Refresh,并确认没有出现证书或其他非预期变化:

argocd app get <application-name> --hard-refresh
argocd app diff <application-name>

只有第二次比较结果稳定后,才能启用自动同步。请把 automated 合并到现有 syncPolicy,不要替换整个配置。由于示例 Application 管理 CRD,以下设置启用 Self-Heal 并保持禁用 Prune:

syncPolicy:
automated:
prune: false
selfHeal: true
retry:
limit: 5
backoff:
duration: 5s
factor: 2
maxDuration: 3m
syncOptions:
- ServerSideApply=true

只有把 CRD、共享命名空间或 Class 资源移交给受独立保护的所有者后,才能启用 prune: true。更改该设置前,请审查 Argo CD 将删除的资源。

协调 Gateway 与应用资源

Controller Application 管理 Controller Release。请使用独立 Application 管理共享 Gateway 资源和应用路由,使其所有权与生命周期互相独立。这些 Application 可以直接读取普通 Kubernetes YAML,不要求使用 Kustomize。

把产品专用 GatewayProxy、GatewayClass、共享 Gateway、应用命名空间和授权标签存放在之前准备且由平台管理的 infrastructure/gateway-resources/ 目录。对于 APISIX,如果 Controller Chart 会创建默认 GatewayProxy,请不要在该目录中重复保存。对于 API7,请使用 API7 Dashboard 生成的非敏感资源,并保留其名称和引用。

为该目录创建 Application:

gateway-resources-application.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: ingress-gateway-resources
namespace: argocd
spec:
project: <platform-project>
source:
repoURL: https://github.com/example/platform-config.git
targetRevision: main
path: clusters/production/infrastructure/gateway-resources
destination:
server: https://kubernetes.default.svc
namespace: aic
syncPolicy:
automated:
prune: false
selfHeal: true

AppProject 必须允许源仓库、目标命名空间、Gateway API 与 APISIX 资源类型,以及集群级 GatewayClass。在确认该 Application 是目录中所有资源的唯一所有者前,请保持禁用 Prune。同步后,等待 GatewayClass 和 Gateway 报告 Accepted=True,再协调应用路由。

把每个应用的 Deployment、Service、HTTPRoute 和策略与该应用存放在一起。可以直接使用配置示例中的清单,无需转换为 Overlay。提交示例前,把显式的 metadata.namespace: aic 替换为应用命名空间,或删除该字段,让 Argo CD 使用 destination.namespace。为应用目录创建第二个 Application:

httpbin-application.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: httpbin-production
namespace: argocd
spec:
project: <app-project>
source:
repoURL: https://github.com/example/platform-config.git
targetRevision: main
path: clusters/production/applications/httpbin
destination:
server: https://kubernetes.default.svc
namespace: <application-namespace>
syncPolicy:
automated:
prune: true
selfHeal: true

把两个 Application 都提交到父级协调路径。将应用 AppProject 限制到其仓库、目标命名空间和所需命名空间级资源类型。如果源目录不包含其他受支持的配置来源,Argo CD 会自动识别普通 YAML。

验证

把安装推广到其他环境前,请验证 Controller Deployment、CRD、Gateway 连接和端到端路由。

确认 Deployment 可用且 CRD 已建立:

kubectl rollout status deployment \
-l app.kubernetes.io/instance=<release-name> \
-n aic \
--timeout=300s
kubectl get pods,services -n aic
kubectl get crd gatewayproxies.apisix.apache.org
kubectl wait --for=condition=Established \
crd/gatewayproxies.apisix.apache.org \
--timeout=60s

Controller Pod 应报告 Controller 与 ADC 两个容器都已就绪。检查渲染出的 Controller 配置和预期 GatewayProxy:

kubectl get configmap -n aic
kubectl get configmap <configmap-name> -n aic \
-o jsonpath='{.data.config\.yaml}{"\n"}'
kubectl get gatewayproxy -n aic
kubectl describe gatewayproxy <gatewayproxy-name> -n aic

当前版本的 GatewayProxy 不公开接受状态。启用准入 Webhook 后,无效对象可能在创建时被拒绝。请通过 Controller 日志,以及相关 Gateway 与 HTTPRoute 资源上的 AcceptedProgrammedResolvedRefs 状态验证运行时连接。

使用 Git 管理的 Gateway 与 Class 完成代理请求到服务,然后执行最终的无变更比较:

argocd app get <application-name> --hard-refresh
argocd app diff <application-name>

升级与回滚

通过 Git 管理升级和回滚,确保 Argo CD 始终是 Controller 资源的唯一协调器。

升级 Controller:

  1. 审查 Controller 和 Chart Release Notes,包括 CRD 变更。
  2. 在 Git 中更改固定的 Chart 版本和所需 values。
  3. 同步前检查差异,包括新 Chart 不再渲染的资源。
  4. 同步一个环境,并重复 Deployment、路由和无变更验证。
  5. 把相同 Git 变更推广到下一个环境。

示例 Application 因管理 Chart 自带 CRD 而禁用自动 Prune。不执行 Prune 时,后续 Chart 删除或重命名的资源可能在升级后继续留在集群中。对于持续的生产升级,建议把 CRD 移交给平台 Application、设置 skipCrds: true,并在审查删除预览后启用 Prune。如果 Controller Application 继续管理 CRD,请保持禁用自动 Prune。每次升级都应审查标记为待 Prune 的资源;只有确认其中不包含 Chart 自带 CRD 及其自定义资源后,才能手动同步并执行 Prune。

回滚前,请确认已安装 CRD 与旧版 Controller 兼容。确保 Controller Application 使用 skipCrds: true,避免回滚时应用旧版 CRD Schema,并由独立且固定版本的平台 Application 管理已安装 CRD。如果当前由 Controller Application 管理,请先按照安全转移 CRD 所有权操作,再在 Git 中恢复 Chart 版本和 Controller values。

如果 Controller Application 仍管理 CRD,恢复 Chart 版本可能会应用旧版 CRD Schema,而不只是回滚 Controller。不要对 Argo CD 管理的部署运行 helm rollbackhelm upgrade

安全转移 CRD 所有权

Argo CD 会把渲染出的 CRD 当作普通受跟踪资源。禁用 Prune 能在同步期间保护 CRD,但无法防止以级联删除方式删除 Application 时连带删除 CRD。

如果由 Controller Application 管理 CRD,之后需要启用 prune: true 或删除 Application,请先转移所有权:

  1. 备份自定义资源,禁用自动同步,并保持 Controller Application 禁用 Prune。
  2. 把与当前安装版本相同的 CRD 加入平台 Application,并使用 Server-Side Apply 同步。此次同步会接管现有 CRD,并更新其 Argo CD 跟踪元数据。
  3. 在 Controller Application 上设置 skipCrds: true,并刷新两个 Application。
  4. 确认 Controller Application 不再跟踪 CRD,且平台 Application 报告它们已同步。
  5. 重新启用 Controller Application 自动同步或 Prune 前,检查删除预览。

跟踪元数据变更期间,两个 Application 会短暂同时关联这些 CRD。请把移交作为受控的平台操作执行,并在完成前不要启用 FailOnSharedResource=true。如有可能,应在首次安装 Controller 前就把 CRD 所有权分配给平台。

如果需要停止管理 Application 但保留所有资源,请验证将保留的资源,并以非级联方式删除:

argocd app delete <application-name> --cascade=false

故障排查

使用以下检查诊断常见协调和平台故障:

现象检查解决方案
Application 的 Webhook Secret 或 caBundle 一直处于 OutOfSync比较两次渲染的清单,检查证书数据是否变化。按照提供稳定的 Webhook 证书操作。
应用 CRD 时出现 Annotation 过大错误检查 Argo CD 是否对 Chart 自带 Gateway API CRD 使用 Client-Side Apply。使用 Server-Side Apply,或把 CRD 移到专用平台 Application。
APISIX 首次同步无法解析 GatewayProxy确认有限重试策略存在。保留重试策略,使 Argo CD 在 REST Discovery 刷新后重试。
GatewayProxy 创建被拒绝,或 Controller 日志报告连接错误确认其 Secret、端点或 Service、网络访问和 CRD 在协调前已经存在。修正 Secret 引用、连接或依赖顺序,然后重新同步。
手动删除或编辑后 Controller 资源重新出现检查是否启用 Self-Heal。在 Git 中完成预期变更,不要编辑实际对象。
OpenShift 拒绝 Pod 或集群级资源审查 SCC 准入、目标命名空间管理和 AppProject 权限。应用已验证的 OpenShift values,并只授予必要的平台权限。