在使用 ArgoCD 进行多集群 GitOps 部署时,经常会遇到一个核心架构问题:控制面(Hub)上的 ArgoCD,到底是如何安全、解耦地连接并管理数据面(Spoke)目标集群的?
很多刚接触 GitOps 的同学,在编写 ArgoCD Application 清单时,往往会面临一个困惑:目标集群的地址该怎么写?如果把公网 IP 和 Token 写进 Git 里,那简直是一场灾难。
本文将深入拆解 ArgoCD 的目标集群管理机制,看看它是如何通过引用和 Secret 实现优雅解耦的。
1. 架构解耦:只在 Git 中写别名
在标准的 ArgoCD 实践中,Git 仓库里的 YAML 图纸绝对不能包含目标集群的硬编码 IP 和认证 Token。
正确的做法是:在Application的destination字段中,仅仅引用一个“集群别名(name)”。
apiVersion:argoproj.io/v1alpha1kind:Applicationmetadata:name:quarkus-svc-appnamespace:argocdspec:project:defaultsource:repoURL:'https://github.com/my-org/my-shared-helm-charts.git'targetRevision:mainpath:charts/my-quarkus-appdestination:# 🎯 极客解耦:使用在 ArgoCD 中注册的集群别名,而不是硬编码公网 IP!name:'tencent-dp1-cluster'namespace:my-namespacesyncPolicy:automated:prune:trueselfHeal:true当 ArgoCD 同步这个 Application 时,它会看到name: tencent-dp1-cluster,然后转身去自己的“保险箱”里寻找这个别名对应的真实连接信息。
2. 实体存储:Kubernetes Secret 才是“保险箱”
真实的集群连接凭证(公网 IP、TLS 证书、Bearer Token),作为Kubernetes Secret,被加密保存在 ArgoCD 所在的控制面集群(in-cluster)的argocd命名空间下。
ArgoCD 是如何把外部集群信息变成 Secret 的?我们通常使用 ArgoCD CLI 来完成这个动作:
# 1. 确保本地 kubeconfig 已经配置好目标集群的 contextkubectl config get-contexts# 2. 将目标集群添加到 ArgoCD,并指定一个别名(这个别名就是 Git 里引用的 name)argocd clusteradd<target-cluster-context-name>--nametencent-dp1-cluster执行这条命令后,CLI 会在后台进行一系列骚操作:
- 在目标集群上创建一个 ServiceAccount(通常叫
argocd-manager)。 - 给这个 ServiceAccount 绑定
cluster-admin权限(ClusterRoleBinding)。 - 提取这个 ServiceAccount 的 Token 和目标集群 API Server 的 TLS 证书。
- 将这些机密信息打包,在控制面集群创建一个特殊的 Secret。
我们可以去控制面集群扒出这个 Secret 看看它的真面目:
kubectl get secret-nargocd-largocd.argoproj.io/secret-type=cluster你会看到类似这样的输出:
apiVersion:v1kind:Secretmetadata:name:cluster-tencent-dp1-cluster-xxxxxnamespace:argocdlabels:# 💡 核心:ArgoCD 靠这个 Label 来识别这是一个集群配置文件argocd.argoproj.io/secret-type:clustertype:Opaquedata:# Base64 编码的敏感信息name:dGVuY2VudC1kcDEtY2x1c3Rlcg==# 对应 tencent-dp1-clusterserver:aHR0cHM6Ly80My4xMzkuMjE0LjIzMTo2NDQz# 对应 https://43.139.214.231:6443config:<加密的 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并在团队内推行这种纯净的解耦方式了。