ArgoCD 实战:多集群同步别只会点同步,冲突才是真正的麻烦

简介: ArgoCD 实战:多集群同步别只会点同步,冲突才是真正的麻烦

ArgoCD 实战:多集群同步别只会点同步,冲突才是真正的麻烦

作者:Echo_Wish

做 Kubernetes 运维,集群数量少的时候,部署应用其实没什么复杂的。

写几个 YAML,执行一下 kubectl apply,应用就跑起来了。

但当业务慢慢发展,测试环境、预生产环境、生产环境,再加上不同地域的 Kubernetes 集群,部署这件事就开始变得麻烦了。

最初可能只是三个集群,后来变成十几个,甚至几十个。

这时候你会发现一个问题:同样的应用,要在多个集群部署,难道每次都手动修改 YAML,再挨个执行部署?

显然不现实。

于是 GitOps 工具开始发挥作用,ArgoCD 就是其中非常有代表性的一种。

不过,我发现很多团队在使用 ArgoCD 时,往往只关注一个问题:怎么让多个集群自动同步?

实际上,这只是第一步。

真正让人头疼的是:多个集群配置不一致怎么办?有人手动修改了资源怎么办?多个应用同时管理同一个资源怎么办?同步失败又该怎么定位?

今天就结合实际场景,聊聊 ArgoCD 多集群同步,以及那些容易踩坑的配置冲突问题。

一、为什么多集群部署不能继续靠手动操作?

先看一个比较常见的业务场景。

假设我们有三个 Kubernetes 集群:

集群 用途 部署环境
k8s-dev 开发环境 dev
k8s-test 测试环境 test
k8s-prod 生产环境 prod

现在有一个订单服务 order-service,需要同时部署到三个集群。

如果使用传统方式,可能是这样的:

kubectl --context=k8s-dev apply -f deployment.yaml

kubectl --context=k8s-test apply -f deployment.yaml

kubectl --context=k8s-prod apply -f deployment.yaml

看起来没什么问题。

但随着业务发展,问题就来了:

  1. 开发环境修改了副本数量,测试环境忘记同步。
  2. 测试环境升级了镜像,生产环境仍然使用旧版本。
  3. 某个运维人员直接修改了生产环境 Deployment。
  4. 多个人同时维护 YAML,最终配置出现偏差。

最麻烦的不是部署失败,而是你根本不知道哪个集群才是正确的配置。

这也是我比较认同 GitOps 的一个原因:

配置应该有唯一可信来源,而不是散落在不同集群和运维人员的电脑里。

ArgoCD 的核心思路就是:

Git 仓库保存期望状态,ArgoCD 负责比较 Kubernetes 集群的实际状态与期望状态,并根据策略执行同步。

简单理解:

          Git Repository
                |
                |
          ArgoCD Server
                |
       +--------+--------+
       |        |        |
       v        v        v
    k8s-dev  k8s-test  k8s-prod
       |        |        |
       v        v        v
    应用部署   应用部署   应用部署

以后修改配置,不需要挨个登录集群操作。

只需要提交 Git,ArgoCD 就可以根据配置完成同步。

当然,前提是多集群连接、权限和同步策略都配置正确。

二、ArgoCD 如何管理多个 Kubernetes 集群?

在正式配置之前,先理解一个概念:

ArgoCD 本身可以连接多个 Kubernetes 集群,但它并不是说每个集群都需要单独安装一套 ArgoCD。

一种常见架构是:

一个中心化 ArgoCD,管理多个远程 Kubernetes 集群。

例如:

ArgoCD
  |
  +---- k8s-dev
  |
  +---- k8s-test
  |
  +---- k8s-prod

这样做的好处是管理入口统一,应用版本、部署状态和同步情况都能集中查看。

1. 注册 Kubernetes 集群

首先确保本地已经配置好对应集群的 kubeconfig。

查看当前上下文:

kubectl config get-contexts

假设输出如下:

CURRENT   NAME
*         k8s-dev
          k8s-test
          k8s-prod

接下来通过 ArgoCD CLI 注册集群:

argocd cluster add k8s-dev

argocd cluster add k8s-test

argocd cluster add k8s-prod

注册完成后,可以查看:

argocd cluster list

需要注意的是,argocd cluster add 通常会在目标集群创建用于访问 Kubernetes API 的 ServiceAccount 和相关 RBAC 授权。

生产环境不要直接照搬默认权限。

建议根据实际需求限制访问范围,尤其要关注:

  • ServiceAccount 权限。
  • Kubernetes API 访问范围。
  • 集群网络连通性。
  • 凭据的存储和轮换。
  • ArgoCD 所在集群的安全边界。

毕竟,一个 ArgoCD 如果拥有所有生产集群的高权限,那么它本身就成了非常重要的安全入口。

2. 创建多集群配置仓库

我个人比较推荐按照环境拆分目录,而不是把所有环境的 YAML 混在一起。

例如:

k8s-gitops/
│
├── apps/
│   └── order-service/
│       ├── base/
│       │   ├── deployment.yaml
│       │   ├── service.yaml
│       │   └── kustomization.yaml
│       │
│       └── overlays/
│           ├── dev/
│           │   └── kustomization.yaml
│           │
│           ├── test/
│           │   └── kustomization.yaml
│           │
│           └── prod/
│               └── kustomization.yaml
│
└── argocd/
    ├── dev-app.yaml
    ├── test-app.yaml
    └── prod-app.yaml

这种结构的好处很直接:

公共配置放在 base,环境差异放在 overlays。

比如开发环境只需要一个副本:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-service
spec:
  replicas: 1

生产环境则需要三个副本:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-service
spec:
  replicas: 3

当然,实际项目中不需要把整个 Deployment 重复写一遍,可以通过 Kustomize 的 patch 机制覆盖差异配置。

这样既能复用公共配置,也不会因为不同环境的需求而互相影响。

3. 创建 ArgoCD Application

下面以生产环境为例:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: order-service-prod
  namespace: argocd
spec:
  project: default

  source:
    repoURL: https://github.com/example/k8s-gitops.git
    targetRevision: main
    path: apps/order-service/overlays/prod

  destination:
    server: https://prod-api.example.com:6443
    namespace: production

  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true

这里有几个配置值得重点关注:

第一,destination.server。

它决定应用最终部署到哪个 Kubernetes 集群。

开发、测试和生产环境可以使用不同的 API Server 地址,也可以使用 ArgoCD 已注册集群对应的名称。

第二,targetRevision。

它决定 ArgoCD 从 Git 的哪个分支、标签或者提交版本读取配置。

第三,prune。

开启后,Git 中已经删除、但仍由该 Application 管理的资源,可以在同步时被清理。

第四,selfHeal。

如果有人直接修改 Kubernetes 集群中的资源,导致实际状态偏离 Git 中的期望状态,ArgoCD 会尝试自动纠正。

这里我要特别提醒一句:

生产环境开启 prune 和 selfHeal 并不是越积极越好。

如果有人误提交了配置,自动同步可能会把错误配置迅速传播到生产环境。

所以,自动化不是没有边界的自动化,发布审批和变更控制依然很重要。

三、多集群同步,真正推荐使用什么方式?

如果只有两个应用、三个集群,分别创建 Application 还可以接受。

但如果应用数量达到几十个,集群数量达到十几个呢?

一个个手动维护 Application,很快就会变成新的运维负担。

这时候可以考虑 ArgoCD ApplicationSet。

它可以根据 Git 目录、集群列表等信息,自动生成多个 Application。

例如,我们希望同一个应用自动部署到三个集群。

可以使用 List Generator:

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: order-service
  namespace: argocd

spec:
  generators:
    - list:
        elements:
          - cluster: dev
            url: https://dev-api.example.com:6443
            namespace: development

          - cluster: test
            url: https://test-api.example.com:6443
            namespace: testing

          - cluster: prod
            url: https://prod-api.example.com:6443
            namespace: production

  template:
    metadata:
      name: 'order-service-{
  {cluster}}'

    spec:
      project: default

      source:
        repoURL: https://github.com/example/k8s-gitops.git
        targetRevision: main
        path: apps/order-service/overlays/{
  {cluster}}

      destination:
        server: '{
  {url}}'
        namespace: '{
  {namespace}}'

      syncPolicy:
        automated:
          prune: true
          selfHeal: true

这段配置做了什么?

其实很简单。

通过 elements 定义集群列表,然后使用模板自动生成 Application。

最终生成:

order-service-dev
order-service-test
order-service-prod

以后增加一个集群,只需要增加一条元素配置。

不需要再复制一份完整的 Application YAML。

当然,如果集群数量非常多,也可以考虑使用 Cluster Generator,让 ApplicationSet 根据 ArgoCD 已注册的集群自动生成应用。

不过这里有个细节:

自动发现集群,不代表所有集群都应该自动部署所有应用。

生产环境、测试环境和临时环境往往有不同的发布要求。

因此,我更建议通过集群标签、Git 目录或者明确的环境清单控制部署范围,而不是简单地让所有集群无差别同步。

四、重点来了:ArgoCD 多集群配置冲突怎么解决?

前面讲的都是正常部署。

但实际运维中,最让人头疼的往往不是部署,而是冲突。

这里列举几个我认为非常典型的问题。

1. 人工修改了集群资源,导致配置漂移

例如,Git 中定义的副本数量是 3:

spec:
  replicas: 3

某天业务出现流量高峰,运维人员直接执行:

kubectl scale deployment order-service \
  --replicas=10 \
  -n production

此时会发生什么?

Git 中期望副本数是 3,Kubernetes 实际副本数是 10。

两边出现了差异。

如果 Application 开启了:

syncPolicy:
  automated:
    selfHeal: true

ArgoCD 就会尝试将实际状态恢复到 Git 中定义的状态。

这时候就有人会问:

我明明是为了扩容,为什么 ArgoCD 又把副本数改回去了?

其实不是 ArgoCD 出错了,而是它在忠实执行 Git 中的期望状态。

我的建议是:

不要把生产环境的临时变更长期建立在手动修改 Kubernetes 资源的基础上。

如果确实需要扩容,应该考虑把变更同步回 Git。

例如:

# 修改生产环境配置
replicas: 10

# 提交变更
git add .
git commit -m "scale order-service to 10 replicas"

git push

这样 Git 才是真正的配置来源。

另外,如果业务使用 HPA 自动扩缩容,就不能简单地让 ArgoCD 和 HPA 同时争夺 spec.replicas。

可以使用:

spec:
  ignoreDifferences:
    - group: apps
      kind: Deployment
      jsonPointers:
        - /spec/replicas

这表示 ArgoCD 在差异比较时忽略 Deployment 的副本数量字段。

但要注意,忽略差异和忽略同步是两个不同概念。

如果希望同步时也不覆盖这个字段,还需要结合:

syncPolicy:
  syncOptions:
    - RespectIgnoreDifferences=true

这类配置应该只用于明确由 HPA 等其他控制器负责管理的字段,不要随意忽略整个资源的差异。

2. 多个 Application 同时管理同一个资源

这是一个非常容易被忽略的问题。

假设有两个 Application:

app-order-prod
app-platform-prod

结果两个 Application 的 Git 路径中,都包含了:

apiVersion: v1
kind: ConfigMap
metadata:
  name: global-config
  namespace: production

那么问题就来了:

两个 Application 都认为自己应该管理这个 ConfigMap。

一个修改了配置:

data:
  TIMEOUT: "30"

另一个却定义成:

data:
  TIMEOUT: "60"

这时候就容易出现资源归属和同步冲突。

我的观点很明确:

一个 Kubernetes 资源,原则上应该只有一个 GitOps 管理入口。

不要让多个 Application 重复管理同一个资源。

可以按照业务边界拆分:

app-platform
  └── global-config

app-order
  └── order-service

app-payment
  └── payment-service

公共资源交给平台级 Application 管理,业务应用只管理自己的资源。

如果确实存在资源共享需求,就应该提前设计清楚资源所有权,而不是等到同步冲突后再补救。

3. 多环境配置互相覆盖

这个问题在多集群部署中也很常见。

例如:

开发环境使用:

image: registry.example.com/order-service:dev

生产环境使用:

image: registry.example.com/order-service:v1.0.0

如果多个环境直接共用同一个 Deployment YAML,然后又在不同地方修改镜像,很容易造成环境配置混乱。

这也是为什么我比较推荐 Kustomize。

通过公共配置和环境覆盖来管理差异。

生产环境:

# overlays/prod/kustomization.yaml

resources:
  - ../../base

images:
  - name: order-service
    newName: registry.example.com/order-service
    newTag: v1.0.0

测试环境:

# overlays/test/kustomization.yaml

resources:
  - ../../base

images:
  - name: order-service
    newName: registry.example.com/order-service
    newTag: v1.1.0-rc1

这样每个环境拥有自己的版本控制,不会因为修改一个环境而影响其他环境。

另外,生产环境最好使用明确的版本标签,甚至使用镜像 digest,而不是直接使用 latest。

否则同样的 YAML,在不同时间拉取到的镜像可能完全不同。

4. 同步失败,不要一上来就重新 Sync

我见过一些运维人员遇到 ArgoCD 同步失败,第一反应就是:

再点一次 Sync。

如果还不行,再点一次。

说实话,这种处理方式并不值得推荐。

因为同步失败的原因可能完全不同:

  • Kubernetes RBAC 权限不足。
  • CRD 尚未安装。
  • 资源字段不符合 API Schema。
  • Namespace 不存在。
  • Webhook 校验失败。
  • 资源之间存在依赖关系。
  • 目标集群无法访问镜像仓库。

正确的做法是先定位问题。

查看 Application:

argocd app get order-service-prod

查看同步历史:

argocd app history order-service-prod

查看资源状态:

argocd app resources order-service-prod

也可以直接查看 Kubernetes 资源事件:

kubectl get events -n production \
  --sort-by=.metadata.creationTimestamp

如果是资源依赖问题,比如先创建 Deployment,后创建 CRD,那么就应该考虑调整同步顺序。

ArgoCD 支持通过 Sync Wave 控制资源同步顺序:

apiVersion: v1
kind: ConfigMap
metadata:
  name: order-config
  annotations:
    argocd.argoproj.io/sync-wave: "-1"
apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-service
  annotations:
    argocd.argoproj.io/sync-wave: "1"

这里 -1 会先于 1 执行。

对于需要先创建基础资源、再部署业务组件的场景,这个功能非常实用。

不过要记住,Sync Wave 主要解决 ArgoCD 同步过程中的资源排序问题,并不能替代应用自身的启动依赖和健康检查。

五、生产环境应该如何设计同步策略?

讲到这里,我们已经知道如何注册集群、创建 ApplicationSet,以及处理常见冲突。

但如果真正要在生产环境落地,我认为还需要考虑一个问题:

是不是所有集群都应该开启自动同步?

我的答案是:不应该。

不同环境的发布风险不同,应该使用不同策略。

可以参考下面这种设计:

环境 自动同步 自动清理 自愈 发布方式
开发 开启 开启 开启 Git 提交自动部署
测试 开启 开启 开启 合并代码后部署
预生产 按需开启 谨慎开启 开启 审核后部署
生产 按需开启 谨慎开启 按需开启 审批后发布

这里需要强调:

生产环境并不是不能自动化,而是应该把自动化和变更审批结合起来。

例如,可以通过 Git 分支保护规则控制生产配置的修改权限。

开发人员
   |
   v
提交代码
   |
   v
Pull Request
   |
   v
代码审查
   |
   v
生产变更审批
   |
   v
合并生产配置
   |
   v
ArgoCD 同步
   |
   v
生产集群

这样即使有人提交了错误配置,也不会未经审核就直接进入生产环境。

另外,还可以通过 ArgoCD 的 AppProject 限制 Application 能访问哪些 Git 仓库、目标集群和 Namespace。

例如:

apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: production
  namespace: argocd

spec:
  sourceRepos:
    - https://github.com/example/k8s-gitops.git

  destinations:
    - namespace: production
      server: https://prod-api.example.com:6443

  clusterResourceWhitelist:
    - group: ""
      kind: Namespace

这里通过 sourceRepos 和 destinations 限制项目的来源和部署目标。

需要根据实际资源范围进一步配置集群级资源白名单、命名空间级资源白名单和角色权限。

不要为了省事直接给所有项目开放全部权限。

六、最后聊聊:多集群 GitOps,最重要的其实不是同步

写到这里,我想说一个自己的看法。

很多团队刚接触 ArgoCD 时,特别关注同步速度、自动化程度,甚至会把自动同步率当成 GitOps 建设是否成功的标准。

但我觉得这有点本末倒置。

多集群管理真正难的地方,不是让十个集群同时部署一个应用,而是让十个集群在长期运行中保持可控。

举个例子:

假设有十个 Kubernetes 集群,每个集群部署了二十个业务应用。

那么总共就是两百个 Application。

如果没有统一的配置管理、版本规范、权限控制和资源归属设计,即使 ArgoCD 能够把所有应用部署成功,后续维护也可能非常痛苦。

因此,我认为一个相对成熟的 ArgoCD 多集群方案,至少应该做好下面几件事:

第一,Git 必须成为可信配置来源。

不要今天改 Git,明天改 Kubernetes,后天又从某个同事电脑上找 YAML。

第二,明确资源归属。

一个资源尽量只由一个 Application 管理,避免多个 Application 相互覆盖。

第三,环境配置必须隔离。

开发、测试、生产可以共享基础配置,但镜像版本、副本数、资源限制等环境差异必须独立管理。

第四,自动同步必须有边界。

开发环境可以大胆自动化,生产环境必须结合审批、回滚和风险控制。

第五,建立可观测性。

不能只知道应用有没有部署成功,还要知道同步失败的原因、配置漂移的情况,以及哪些集群长时间没有完成同步。

例如,可以定期检查:

argocd app list

argocd app get order-service-prod

argocd app diff order-service-prod

配合 Prometheus、Grafana 和告警系统,把 OutOfSync、Degraded、同步失败等状态纳入监控。

这样才能真正做到问题提前发现,而不是等业务人员反馈服务异常后才开始排查。

写在最后

ArgoCD 确实能够大幅降低 Kubernetes 多集群部署的维护成本,但它不是一个安装完成就能解决所有问题的工具。

Application 解决应用管理,ApplicationSet 解决批量生成,Kustomize 解决环境差异,Sync Wave 解决资源顺序,AppProject 解决权限边界。

这些功能组合起来,才能形成一套比较完整的 GitOps 管理体系。

我一直觉得,运维自动化最有价值的地方,不是让我们少敲几条命令,而是让原本依赖个人经验的操作,逐渐变成可追踪、可审计、可重复执行的标准流程。

多集群同步只是开始,真正值得追求的是:无论集群有多少、环境有多复杂,我们都能清楚地知道每个资源应该是什么状态,以及为什么会变成现在这个状态。

这才是 ArgoCD 在生产环境中真正的价值。

—— Echo_Wish

目录
相关文章
|
5天前
|
JavaScript API iOS开发
DeepSeek Harness下载、安装、配置一篇搞定(2026整理,送常用插件)
DeepSeek Harness(DSH)是DeepSeek于2026年开源的MIT协议AI Agent框架,支持插件化组装模型、工具、沙箱与UI,兼容主流大模型。本文提供免Node.js的桌面端安装包(Win/macOS),含详细图文教程及热门插件推荐。
2294 13
|
云安全 安全 网络安全
|
5天前
|
iOS开发 Docker MacOS
【2026实测】Docker Desktop下载、安装、汉化、配置教程(附官网安装包)
Docker Desktop 是 Docker 官方推出的桌面容器管理工具,集成引擎、CLI、图形界面与 Kubernetes,支持 Win/macOS/Linux。2026 最新版 4.88.1 强化 ARM 原生运行、镜像加速及资源可视化,附中文汉化与国内镜像配置指南。
1021 3
|
18天前
|
人工智能 API 开发工具
DeepSeek Harness 神插件:白嫖 13 家大厂模型
`dsh-our-free-model` 是 DeepSeek Harness 神级插件:零配置、零API Key、零账号,聚合13家大厂免费模型(含DeepSeek V4.1 Flash、Kimi K3等),支持本地网关、用量看板与自动降级,真正实现“白嫖即用”。
3170 49
|
12天前
|
JavaScript 安全 前端开发
Nodejs Brotli decoder 代码执行漏洞 (CVE-2026-111497)10629
Node.js发布安全更新修复Brotli解码器高危RCE漏洞(CVE-2026-111497),建议受影响版本用户立即升级。
2115 2
|
6天前
|
安全 算法 定位技术
《高性价比人生指南》完整原版:普通人用最少的资源,过好这一生的底层逻辑~How To Live Better
📖《高性价比人生指南》是一份基于实证、拒绝焦虑的生存手册,倡导以“人生时薪”为视角,重新计算时间、金钱与精力的成本与收益。它不承诺逆袭,只教人算清账:省下的钱若耗掉时间便亏;买体验比买物品更值;睡眠是最高杠杆的健康投资;关系贵在情绪价值而非表面热络;学习重在改变行为而非自我安慰。核心理念:用低成本、高回报的微小行动,换取长期的选择权——不是成为谁,而是掌控自己人生的主动权。
|
10天前
|
人工智能 JSON Linux
【保姆级】ComfyUI部署教程(下载+安装+配置+工作流,2026最新)
ComfyUI 是一款开源节点式AI生成工具,支持图像、视频、音频及3D内容创作。通过拖拽连线组合模型加载、提示词、采样等节点,构建可复用、易修改的工作流,兼容SD1.5、SDXL、Flux、Qwen Image等主流模型。
|
4天前
|
Linux 开发工具 iOS开发
Codex保姆级教程(下载+安装+登录+使用,含所有版本,2026最新)
Codex是OpenAI推出的开源AI编程智能体,本地运行,可理解整个代码库,支持自然语言指令改代码、执行命令、跑测试、修Bug,兼容Win/macOS/Linux。(239字)

热门文章

最新文章