ArgoCD 多集群联邦管理实践:它是如何安全接管目标集群的?

在使用 ArgoCD 进行多集群 GitOps 部署时,经常会遇到一个核心架构问题:控制面(Hub)上的 ArgoCD,到底是如何安全、解耦地连接并管理数据面(Spoke)目标集群的?

很多刚接触 GitOps 的同学,在编写 ArgoCD Application 清单时,往往会面临一个困惑:目标集群的地址该怎么写?如果把公网 IP 和 Token 写进 Git 里,那简直是一场灾难。

本文将深入拆解 ArgoCD 的目标集群管理机制,看看它是如何通过引用和 Secret 实现优雅解耦的。

1. 架构解耦:只在 Git 中写别名

在标准的 ArgoCD 实践中,Git 仓库里的 YAML 图纸绝对不能包含目标集群的硬编码 IP 和认证 Token。

正确的做法是:在 Applicationdestination 字段中,仅仅引用一个"集群别名(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 会在后台进行一系列骚操作:

  1. 在目标集群上创建一个 ServiceAccount(通常叫 argocd-manager)。
  2. 给这个 ServiceAccount 绑定 cluster-admin 权限(ClusterRoleBinding)。
  3. 提取这个 ServiceAccount 的 Token 和目标集群 API Server 的 TLS 证书。
  4. 将这些机密信息打包,在控制面集群创建一个特殊的 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) 中,你通常会看到两类集群:

  1. https://kubernetes.default.svc (in-cluster)
    • 这是 ArgoCD 自身所在的宿主集群(控制面)。
    • ArgoCD 默认就具备管理自己的能力,所以这个是内置的。不需要外部 Token。
  2. 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 并在团队内推行这种纯净的解耦方式了。