在使用 ArgoCD 进行多集群 GitOps 部署时,经常会遇到一个核心架构问题:控制面(Hub)上的 ArgoCD,到底是如何安全、解耦地连接并管理数据面(Spoke)目标集群的?
很多刚接触 GitOps 的同学,在编写 ArgoCD Application 清单时,往往会面临一个困惑:目标集群的地址该怎么写?如果把公网 IP 和 Token 写进 Git 里,那简直是一场灾难。
本文将深入拆解 ArgoCD 的目标集群管理机制,看看它是如何通过引用和 Secret 实现优雅解耦的。
1. 架构解耦:只在 Git 中写别名
在标准的 ArgoCD 实践中,Git 仓库里的 YAML 图纸绝对不能包含目标集群的硬编码 IP 和认证 Token。
正确的做法是:在 Application 的 destination 字段中,仅仅引用一个"集群别名(name)"。
yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: quarkus-svc-app
namespace: argocd
spec:
project: default
source:
repoURL: 'https://github.com/my-org/my-shared-helm-charts.git'
targetRevision: main
path: charts/my-quarkus-app
destination:
# 🎯 极客解耦:使用在 ArgoCD 中注册的集群别名,而不是硬编码公网 IP!
name: 'tencent-dp1-cluster'
namespace: my-namespace
syncPolicy:
automated:
prune: true
selfHeal: true
当 ArgoCD 同步这个 Application 时,它会看到 name: tencent-dp1-cluster,然后转身去自己的"保险箱"里寻找这个别名对应的真实连接信息。
2. 实体存储:Kubernetes Secret 才是"保险箱"
真实的集群连接凭证(公网 IP、TLS 证书、Bearer Token),作为 Kubernetes Secret ,被加密保存在 ArgoCD 所在的控制面集群(in-cluster)的 argocd 命名空间下。
ArgoCD 是如何把外部集群信息变成 Secret 的?我们通常使用 ArgoCD CLI 来完成这个动作:
bash
# 1. 确保本地 kubeconfig 已经配置好目标集群的 context
kubectl config get-contexts
# 2. 将目标集群添加到 ArgoCD,并指定一个别名(这个别名就是 Git 里引用的 name)
argocd cluster add <target-cluster-context-name> --name tencent-dp1-cluster
执行这条命令后,CLI 会在后台进行一系列骚操作:
- 在目标集群上创建一个 ServiceAccount(通常叫
argocd-manager)。 - 给这个 ServiceAccount 绑定
cluster-admin权限(ClusterRoleBinding)。 - 提取这个 ServiceAccount 的 Token 和目标集群 API Server 的 TLS 证书。
- 将这些机密信息打包,在控制面集群创建一个特殊的 Secret。
我们可以去控制面集群扒出这个 Secret 看看它的真面目:
bash
kubectl get secret -n argocd -l argocd.argoproj.io/secret-type=cluster
你会看到类似这样的输出:
yaml
apiVersion: v1
kind: Secret
metadata:
name: cluster-tencent-dp1-cluster-xxxxx
namespace: argocd
labels:
# 💡 核心:ArgoCD 靠这个 Label 来识别这是一个集群配置文件
argocd.argoproj.io/secret-type: cluster
type: Opaque
data:
# Base64 编码的敏感信息
name: dGVuY2VudC1kcDEtY2x1c3Rlcg== # 对应 tencent-dp1-cluster
server: aHR0cHM6Ly80My4xMzkuMjE0LjIzMTo2NDQz # 对应 https://43.139.214.231:6443
config: <加密的 TLS 证书和 Bearer Token>
3. 两种集群视角的区分:in-cluster vs 外部集群
在 ArgoCD 的 Web UI (Settings -> Clusters) 中,你通常会看到两类集群:
https://kubernetes.default.svc(in-cluster)- 这是 ArgoCD 自身所在的宿主集群(控制面)。
- ArgoCD 默认就具备管理自己的能力,所以这个是内置的。不需要外部 Token。
https://<公网IP>:6443(tencent-dp1-cluster)- 这是通过上述 Secret 方式接入的数据面集群。
- ArgoCD 通过读取 Secret 中的 Token 和 IP,跨云发起 API 调用来部署应用。

总结
ArgoCD 的集群管理机制完美诠释了 GitOps 的安全理念:
- Git 仓库 只做"意图声明"(我要部署到名为
tencent-dp1-cluster的地方)。 - **控制面(Hub)**负责"状态保密"(通过 K8s Secret 保存
tencent-dp1-cluster的真实凭证)。 - 两者通过
name这个别名进行解耦缝合,彻底杜绝了凭证硬编码导致的安全事故。
下次在写 ArgoCD Manifest 时,可以放心地使用 destination.name 并在团队内推行这种纯净的解耦方式了。