端到端 GitOps + 金丝雀流程测评报告

1. 总体结论

架构方向一致,核心机制不一致。

现有体系已经具备目标流程的大部分"行为":ArgoCD 管理、Rollout 金丝雀、Traefik 权重运行时管理、业务完全隔离、基础设施独立 Application。但驱动方式是 Jenkins CLI 直连 + 运行时注入参数命令式(imperative)模式 ,而非目标描述的"gitops 仓库声明式 + ApplicationSet 元管理"的声明式(declarative)模式

两者都能正常运行,但声明式是目标架构的要求。迁移的核心工作就是把命令式路径改造成声明式路径------即新建 GitOps 仓库(推荐公共单仓库,见第 9 节)、引入 ApplicationSet、让镜像 tag 成为 git 中的真实提交

一句话可执行概述:现状能跑通目标流程的所有"行为",但"事实来源"在集群运行时而非 git;按目标改造 = 把事实来源迁移回 git。


2. 目标端到端流程(原样引用)

2.1 整体架构概览

基础设施层(Helm + Kustomize)

  • Traefik、argo-rollouts-controller 使用 helm 安装,用 kustomize 做 values 覆写;
  • 单独 1 个 ArgoCD Application 管理基础设施,不进 ApplicationSet

业务层(7 个业务完全独立)

每个业务两套仓库:

  • 业务代码仓库:开发写业务代码,Jenkins 在这里触发 CI
  • 独立 GitOps 仓库:存放 Kustomize base + overlays/prod,包含 Rollout、两组 service、TraefikService、IngressRoute;Git 里的 TraefikService 不写流量权重

ArgoCD 元管理

  • 1 个 ApplicationSet,list 列表维护 7 个业务信息,每个指向各自独立 GitOps 仓库;
  • ApplicationSet 自动生成 7 个业务 Application;template 内置忽略规则,保护 TraefikService 运行时的权重,防止 ArgoCD 回滚。

重要:ApplicationSet 只管生成 Application 对象,不处理金丝雀发布逻辑;金丝雀由 argo-rollouts controller 独立完成。

2.2 日常发布流程(只更新其中一个业务,例:app1)

全程不改动 ApplicationSet。

  1. 开发提交代码 → Jenkins CI 阶段

    ① 开发向 app1 业务代码仓库提交代码,触发 Jenkins 流水线

    ② Jenkins 编译、打包,生成新版本镜像推镜像仓库

    ③ Jenkins 只修改 app1 自己独立的 GitOps 仓库 的 overlays/prod 里的镜像 tag

    ④ commit 并 push 到 app1-gitops 仓库

    只操作 app1 的 gitops 仓库,其他 6 个业务仓库、ApplicationSet 完全不动。

  2. ArgoCD 同步阶段

    ① ApplicationSet 生成出来的 app1 这个 Application,检测到自己对应的 git 源发生变更

    ② ArgoCD 执行 kustomize 渲染,把 Rollout、service、TraefikService、IngressRoute 同步到 k8s 集群对应命名空间

    ③ ApplicationSet 模板自带的忽略规则生效:告诉 ArgoCD 不要干涉 TraefikService 运行时的 weight 字段,不要 selfHeal 覆盖。

  3. Argo-Rollouts 金丝雀执行阶段

    ① argo-rollouts controller 监听到集群内 Rollout CR 的 pod 模板(镜像)发生变化,启动 canary 发布流程

    ② 拉起 canary 版本 Pod;控制器在集群运行时修改 TraefikService 的流量权重(例如 20%)

    ③ Traefik 网关读取 TraefikService 配置,把 20% 外部入口流量切到新版本

    ④ 进入 pause 暂停状态,等待人工确认。

    此时 Git 仓库里 TraefikService 依旧没有 weight,权重只存在集群内存中。

  4. 人工介入

    • 查看发布状态,验证新版本业务功能
    • ✅ 验证正常:执行 promote,argo-rollouts 继续提升流量权重直到 100%,旧版本副本逐步缩容,发布完成。
    • ❌ 发现问题:执行 abort,流量切回旧版本,销毁 canary 副本。
    • 如果要永久回滚版本:再次走 Jenkins 流程,把 gitops 仓库镜像 tag 改回旧版本,完整重走一遍流程。

2.3 什么时候才要操作 ApplicationSet(元数据变更)

只有下面场景才修改 ApplicationSet:

  1. 新增业务:在 list 列表增加一条业务配置,apply;自动生成新的 Application。
  2. 删除业务:list 列表删掉对应业务条目,apply;自动删除对应 Application。
  3. 全局策略修改:所有业务统一改 syncPolicy、权限、忽略规则等。

修改 ApplicationSet CR 本身,会 reconcile 全部 7 个业务 Application。

业务版本迭代发布,禁止修改 ApplicationSet。

2.4 关键约束(必须遵守)

  1. 基础设施和业务分开,基础设施独立 Application,不要放到 ApplicationSet 中。
  2. 不要手动 edit 集群内 ApplicationSet 生成出来的子 Application,会被 AppSet 控制器覆盖。
  3. 只有经过 Traefik IngressRoute 的外部访问,才会走金丝雀流量切分;Pod 内部直连 service 不走网关,不会切流量。
  4. ArgoCD 要配置好所有 7 个业务 git 仓库的访问凭证,否则拉取不到资源。
  5. Traefik 的 apiGroup 版本要和 argo-rollouts 控制器配置匹配。

3. 现状详细分析

3.1 共享库能力地图

共享库位于 jenkins-configuration 仓库,vars → src 委托 com.pipeline.shared.PipelineEntry,对外暴露 6 个步骤:automatedPipelinemultiEnvPipelinerollbackPipelinedockerDigestGatepipelineStepssupplyChainEvidence

部署层支持 3 条路径 ,由 RuntimeDeploymentExecutor.deploy()plan.method 分发:

路径 实现 说明
kubernetes DeploySteps.k8sImageDeploy 传统 kubectl set image 直接改 Deployment
argocd deployWithArgoCD() 7 个业务当前实际使用 :创建/更新 ArgoCD Application + argocd app sync
argo-rollouts deployWithArgoRollouts() 生成 Rollout YAML 后 kubectl apply + argo rollouts promote/abort

argocd 路径相关类:

  • ArgocdApplicationYamlBuilder --- 生成 Application YAML(helm source、helm.parameters、syncPolicy)
  • ArgocdCommandBuilder --- 组装 argocd CLI 命令;固定服务地址 ARGO_SERVER = argocd-server.argocd.svc.cluster.local:30080(本环境 argocd-server 非默认 443 端口,需 --insecure --grpc-web
  • ArgocdCommandRunner --- 执行 create/update/sync/wait
  • ArgocdValidator / ArgocdSyncPolicy --- 校验与同步策略

3.2 ArgoCD 现有 Application 构成(实测)

集群当前 30 个 Application无 ApplicationSet

复制代码
api-dev      api-test     api-uat     api-prod
core-dev     core-test    core-uat    core-prod
edge-dev     edge-test    edge-uat    edge-prod
gateway-dev  gateway-test gateway-uat gateway-prod
notify-dev   notify-test  notify-uat  notify-prod
web-dev      web-test     web-uat     web-prod
worker-dev   worker-test  worker-uat  worker-prod
(以上 7 业务 × 4 环境 = 28 个)
jenkins-configuration   ← 基础设施(指向 jenkins-configuration-fixtures.git, path=helm, rev=master)
jsl-mb-go               ← 基础设施(jsl-mb-go.git, path=helm, rev=master)

业务 Application 示例(api-dev):

复制代码
repo= https://gitee.com/cao-weiguang_admin/api.git
path= helm
rev= dev
syncPolicy= automated { enabled: true, prune: false, selfHeal: false }

3.3 业务仓库结构(单仓库)

业务代码与 helm/ 目录(Chart + values.yaml + templates)在同一个仓库 ,如 api.git

api 仓库 Jenkinsfile 关键配置:

groovy 复制代码
@Library('jenkins-shared-library@production-ready') _

def envName(String branch) { return branch == 'master' ? 'prod' : branch }
def deployEnv = envName(env.BRANCH_NAME)

def config = [
    projectName: 'api',
    projectType: 'python',
    deployEnv: deployEnv,
    deployMethod: 'argocd',
    deploy: [
        appName: "api-${deployEnv}",
        repoUrl: 'https://gitee.com/cao-weiguang_admin/api.git',  // 业务仓库自己,不是独立 gitops 仓库
        path: 'helm',
        targetRevision: env.BRANCH_NAME,
        imageRepository: '172.18.0.1:5000/api',
        automated: false,
        prune: false,
        selfHeal: false
    ],
    ...
]

分支映射:master=prod,其余分支同名;多分支 job 按分支自动触发对应环境部署。

3.4 镜像 tag 注入机制(核心事实)

RuntimeDeploymentExecutor.deployWithArgoCD() 的流程:

  1. 构建完成后,把 image.repositoryimage.tag(来自 DOCKER_IMAGE_TAG)拼成 helm parameters
  2. ArgocdApplicationYamlBuilder 生成 Application YAML,其中 spec.source.helm.parameters 携带本次镜像 tag;
  3. kubectl apply 更新 Application → argocd app sync 触发同步。

关键后果:

  • 镜像 tag 是运行时写入 Application 的 helm 参数,业务 git 仓库里没有对应变更记录(git 中 values.yaml 仍是旧 tag);
  • 因此所有业务 App 都是 selfHeal: false------目的是防止 ArgoCD 把运行时 tag 覆盖回 git 声明值。这是命令式模式的必然结果,与目标架构(声明式、可开 selfHeal)相反。

3.5 金丝雀现状

  • rollout.yaml 位于 helm/templates 中,由 ArgoCD 渲染后同步进集群;
  • TraefikService 在 git 模板中不写 weight(符合目标约束③),权重由 Rollout 控制器运行时修改,Traefik 网关切外部流量;
  • 每个业务 Application 已配置 ignoreDifferences,保护 TraefikService 权重与 Service selector;
  • Rollout steps 为自动推进ArgoRolloutsYamlBuilder 默认生成 setWeight 20 → pause 30s → 40 → pause 30s → 60 → pause 30s → 80 → pause 30s没有人工确认点
  • 实测中曾出现 canary 处于 Suspended(金丝雀暂停)状态,正是自动 pause 的体现------暂停后会自动继续,而非等待人工决策。

3.6 CI 触发机制现状(Multibranch + 轮询)与 Webhook 改造

现状(实测)

  • Job 形态:每业务仓库 1 个 Multibranch Pipeline ,按分支自动创建子 Job(分支映射 master=prod,其余分支同名),分支内 Jenkinsfile 调用 automatedPipeline
  • 触发方式:轮询扫描 ------Scan Multibranch Pipeline Triggers 设置扫描间隔(如 H/5 * * * *,每 5 分钟一次),提交代码后自动但非实时,最长延迟一个扫描周期;
  • git → Jenkins 的 webhook 触发未配置 :共享库/文档中无 Gitee webhook 触发实现,现有 webhook 配置均为飞书通知(notifyWebhookId),与流水线触发无关。

结论:"提交代码自动触发"成立,但依赖轮询,非"提交即触发"。实时触发需引入 Webhook。

改造方案(推荐:Webhook 实时触发)

  1. Jenkins 安装 Gitee Plugin (码云官方,对 Multibranch 触发支持好)或 Generic Webhook Trigger(通用,任意 Git 平台);
  2. Multibranch Job 开启 webhook 触发入口;
  3. 每个 Gitee 仓库添加 WebHooks(推送事件),回调 Jenkins:
    • Gitee Plugin:http://<jenkins-host>/gitee-project/webhook(或插件端点);
    • GWT:http://<jenkins-host>/generic-webhook-trigger/invoke?token=<job-token>
  4. 网络要求:Gitee 服务器需能回调 Jenkins(公网/反代 + HTTPS),token 鉴权防刷。

备选方案(仅过渡) :轮询间隔调小(H/1 * * * *)。缺点:仍非实时;1000 个 Job 时每个周期全量 git 扫描,开销爆炸,不可作为终态。

1000 业务规模注意点

  • webhook 配置本身也要批量:1000 个仓库手点不现实,建议脚本/CMDB 批量创建(与 ApplicationSet list 用脚本生成同一套路);
  • 触发粒度:webhook 回调携带仓库标识,只触发对应 Multibranch Job(Gitee 插件按仓库路由),避免全量扫描;
  • 与目标架构配合:webhook 触发只解决"CI 实时性";CD 侧(ArgoCD)的实时性靠 GitOps 仓库 webhook,两者独立配置。

4. 现状 vs 目标逐项对比

# 维度 现状(实测) 目标 差距
1 仓库结构 业务代码 + helm/ 单仓库 代码仓库 + GitOps 仓库(Kustomize,公共单仓库或独立仓库) ❌ 需新建(推荐 1 个公共仓库,见第 9 节)
2 渲染引擎 Helm(values.yaml + templates) Kustomize(base + overlays) ❌ 需转译
3 镜像 tag Jenkins 运行时注入 Application 的 helm 参数,git 无记录 gitops 仓库 overlays/prod 中改 tag,push 即声明 ❌ 核心差异
4 Application 管理 30 个独立 App(28 业务 + 2 基础设施),无 ApplicationSet 1 个 ApplicationSet 生成业务 App,基础设施不进 ❌ 需迁移
5 忽略规则 28 个 App 逐个配置 ignoreDifferences ApplicationSet template 内置 ⚠️ 有,但分散
6 同步触发 Jenkins CLI 触发 argocd app sync git 变更自动检测(webhook/轮询)
7 金丝雀人工确认 自动 pause: duration: 45s,无人确认 pause(无 duration)等人 promote/abort ❌ 缺人工确认
8 TraefikService git 不写 weight ✅ 模板无 weight,运行时控制器写 ✅ 同左 ✅ 已符合
9 业务隔离 ✅ 发布只 sync 自己应用 ✅ 同左 ✅ 已符合
10 基础设施独立 Application ✅ 2 个独立 App 与业务分开 ✅ 同左,不进 ApplicationSet ✅ 已符合

5. 5 处核心差距详述

差距 1:无 ApplicationSet(元管理缺失)

现状 :28 个业务 App 由 Jenkins 用 argocd app create CLI 逐环境创建和维护(共享库 ArgocdCommandBuilder.createApp / ArgocdApplicationYamlBuilder 支撑),配置漂移在集群中,git 里没有单一事实来源。

影响

  • 新增/删除业务需改共享库或手动逐个建 App,无声明式入口;
  • ignoreDifferences、syncPolicy 等策略要逐个 App 维护,容易不一致;
  • 无法享受 AppSet 的 template 集中管理能力。

目标:1 个 ApplicationSet CR + list 列表,apply 即声明式管理全部业务 App。

差距 2:无独立 GitOps 仓库、无 Kustomize

现状api.git 内代码和 helm 同仓;helm templates 由共享库/开发者维护。

影响

  • 业务代码提交与部署配置变更耦合在同一次提交里,发布与代码评审不可分离;
  • Helm 模板在 7 个仓库间重复复制,升级配置要逐个改;
  • 没有 overlays/prod 这种"环境目录"概念,环境差异靠分支 + values 区分。

目标:GitOps 仓库(Kustomize base + overlays/{dev,test,uat,prod})承载部署配置,与代码演进解耦。仓库组织方式有两种:每业务独立仓库(强隔离)或公共单仓库(低成本,推荐,详见第 9 节)。

差距 3:镜像 tag 非声明式(核心差异)

现状deployWithArgoCD()image.tag 作为 helm 参数运行时写入 Application ,仓库里永远是旧值;selfHeal: false 是为了防止 ArgoCD 回滚运行时 tag。

影响

  • 集群实际运行版本与 git 对不上,"谁在跑什么版本"只能查 ArgoCD UI;
  • 无法通过 git 历史回滚版本;审计链路断裂;
  • selfHeal 关闭,ArgoCD 的"自愈"能力被禁用。

目标:tag 是 git 里的真实提交(每次发布一条 commit),版本历史可审计、可回滚,selfHeal 可开启。

差距 4:同步靠 CLI 触发

现状argocd app sync 由构建 job 在流水线里执行,发布成功与否依赖 Jenkins 执行环境(凭证、网络、CLI 版本)。

影响

  • 发布入口只有"Jenkins 触发"一条路,值班同学无法独立发布;
  • Jenkins 故障 = 发布通道故障。

目标 :push GitOps 仓库后 ArgoCD 自动(webhook/轮询)检测并同步,发布与 CI 解耦;Jenkins 只负责改 GitOps 仓库(tag 声明),同步由 ArgoCD 完成。

差距 5:金丝雀无人工确认

现状 :rollout steps 全是 pause: {duration: 45s} 自动过,发布全程无人干预,异常流量到了 80% 才可能被发现。

影响

  • 风险大版本(数据库迁移、破坏性变更)无法在 20% 停留验证;
  • 与目标流程第 4 步"pause 等待人工确认 → promote/abort"不符。

目标:第一个 pause 无 duration,等人执行 promote/abort(交互方式见第 7 节)。


6. 已符合项确认

现有体系已满足目标架构的 4 项关键要求:

  1. TraefikService git 不写 weight

    模板中 TraefikService 无 weight 字段,权重只由 Rollout 控制器运行时写,Traefik 网关读取后切外部流量;git 与运行时彻底分离。

  2. 业务完全隔离

    每个业务独立仓库、独立 Application、独立 namespace,发布只 sync 自己的 App,其余 6 个业务不受影响。

  3. 基础设施独立 Application

    2 个基础设施 App(jenkins-configurationjsl-mb-go)与 28 个业务 App 完全分开,符合"基础设施不进 ApplicationSet"的结构意图(当前尚未引入 ApplicationSet,故天然满足)。

  4. ignoreDifferences 保护权重 ✅(但分散)

    各业务 App 已配置 ignoreDifferences 保护 TraefikService 权重与 Service selector;不足是配置在应用级,不集中。


7. 金丝雀人工确认:两种方式对比

维度 方式 A:Jenkins 流水线内确认 方式 B:kubectl/argo CLI 外部确认
交互流程 流水线跑到 pause 时挂起,Jenkins 界面出现【继续/中止】;点击后流水线继续跑 promote 并完成收尾(健康检查、通知) 流水线推到 pause 后结束 ,人离开 Jenkins,在终端执行 argo rollouts promote/abort;后续提权、缩容由 Rollout 控制器自行完成
发布状态记录 完整留在 Jenkins 流水线视图,可回溯 脱离流水线,靠 kubectl argo rollouts get rollout <name> -n <ns> 查看
适合场景 单业务小团队、希望所有动作留痕、无独立发布平台 有值班平台/独立发布入口、不想让 Jenkins job 长时间占用 executor
缺点 job 长时间挂起占用构建节点;超时中断会留下"发布未完成"的中间态 状态不集中,人工在终端操作,对操作者 k8s 能力有要求
共享库改造量 中:需要 input/确认步骤 + promote/abort 封装 小:流水线推完即止即可,人工操作无需改动共享库

实质结论:两者金丝雀行为完全一致(权重推进、pause),差别只在"谁按确认键、记录在哪"。选型取决于是否有独立值班/发布平台;没有平台时,方式 A 更稳。


8. ApplicationSet 粒度方案对比

维度 方案 A:每业务 1 个 App(7 个) 方案 B:每业务 4 个 App(28 个)
ApplicationSet list 条目 7 条(每业务 1 条) 7 条 × generators 展开环境,或 28 条
环境区分方式 gitops 仓库内用分支(dev/test/uat/prod),App 的 targetRevision 随环境切换 gitops 仓库内用 overlays/dev、test、uat、prod 目录,4 个 App 各自 path 指向
优点 list 最简,与"自动生成 7 个业务 Application"描述一致;App 数量少 环境相互独立,可并行发布;overlay 目录即环境声明,符合 Kustomize 惯例;targetRevision 可统一
缺点 一个 App 同时只有 1 个 targetRevision,多环境发布需切换分支,天然串行;分支间漂移难控制 list 稍长;4 个环境各建 1 个 App,数量多
与现状(28 个 App)的迁移成本 需合并现有 28 App 的配置到 7 个,namespace/路径映射变化大 与现有 28 个 App 一一对应,迁移平滑 ,只需把各自 source 从 helm 改为 overlay 路径

建议 :优先 方案 B(28 个)。理由:①与现状 28 个 App 结构完全对齐,迁移无阵痛;②Kustomize 的 overlays 目录天然表达环境,与目标描述("overlays/prod")一致;③环境间可独立发布互不影响。若团队强烈希望 App 数量收敛到 7,再考虑方案 A。

8.1 1000 业务规模的 ApplicationSet 写法

背景:目标架构按"7 个业务、每业务独立 GitOps 仓库"描述,ApplicationSet 用 list 维护 7 条即可。业务量扩展到 1000 个时,若 1000 个业务各自用独立 GitOps 仓库(每个业务 repoURL 不同),不能使用目录生成器git directories 只扫描一个仓库,适用于公共单仓库),只能使用 listfiles 两种 generator。

写法一:List generator(业务数量少时手写,1000 个时由脚本生成)

yaml 复制代码
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: business-apps
  namespace: argocd
spec:
  generators:
    - list:
        elements:
          - name: app1
            repoURL: https://git.example.com/gitops-app1.git
            path: overlays/prod
            targetRevision: main
            namespace: app1-prod
          - name: app2
            repoURL: https://git.example.com/gitops-app2.git
            path: overlays/prod
            targetRevision: main
            namespace: app2-prod
          # ... 1000 个业务:每业务 1 行,repoURL/path/targetRevision/namespace 可各自不同
  template:
    metadata:
      name: '{{name}}'
    spec:
      project: default
      source:
        repoURL: '{{repoURL}}'
        targetRevision: '{{targetRevision}}'
        path: '{{path}}'
        kustomize:
          images:
            - 'registry.example.com/{{name}}:{{imageTag}}'
      destination:
        server: https://kubernetes.default.svc
        namespace: '{{namespace}}'
      syncPolicy:
        automated:
          prune: true
          selfHeal: false
        ignoreDifferences:
          - group: traefik.containo.us
            kind: TraefikService
            jsonPointers:
              - /spec/weight

维护说明:7 个业务时手写 7 行即可;1000 个时靠人工维护容易出错,建议用脚本从 CMDB/业务清单生成这段 list,并加 CI 校验(仓库 URL 格式、path 存在性、命名空间不重复等)。

写法二:Git files generator(100+ 业务推荐,ApplicationSet 本体固定)

思路:单独建一个"元数据仓库",里面一个 JSON 描述一个业务;ApplicationSet 扫描该仓库的 JSON 文件生成 Application,业务差异全部收敛在 JSON 里:

yaml 复制代码
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: business-apps
  namespace: argocd
spec:
  generators:
    - git:
        repoURL: https://git.example.com/tenant-registry.git   # 元数据仓库,只存 JSON
        revision: main
        files:
          - path: "apps/*/config.json"
  template:
    metadata:
      name: '{{name}}'
    spec:
      project: default
      source:
        repoURL: '{{repoURL}}'
        targetRevision: '{{targetRevision}}'
        path: '{{path}}'
        kustomize:
          images:
            - 'registry.example.com/{{name}}:{{imageTag}}'
      destination:
        server: https://kubernetes.default.svc
        namespace: '{{namespace}}'
      syncPolicy:
        automated:
          prune: true
          selfHeal: false
        ignoreDifferences:
          - group: traefik.containo.us
            kind: TraefikService
            jsonPointers:
              - /spec/weight

配套元数据仓库里的 JSON(tenant-registry/apps/app1/config.json):

json 复制代码
{
  "name": "app1",
  "repoURL": "https://git.example.com/gitops-app1.git",
  "path": "overlays/prod",
  "targetRevision": "main",
  "namespace": "app1-prod"
}

维护说明:新增业务 = 提交一个 JSON,自动生成对应 Application;删除业务 = 删 JSON;修改参数 = 改 JSON。ApplicationSet 本体约 30 行,一旦写好无需因业务增删而改动;1000 个业务的管理成本收敛为"1000 个 JSON 文件的增删改",JSON 还可按目录做 CODEOWNERS 细粒度授权。

两种写法对比

维度 List generator Git files generator
业务参数自由度 每行完全独立 每个 JSON 完全独立
新增业务 改 ApplicationSet YAML(脚本生成) 元数据仓库提交一个 JSON
删除业务 改 ApplicationSet YAML 删对应 JSON
1000 个时 YAML 长度 list 1000 行 固定约 30 行
权限细粒度 同一份 YAML 谁都能改 JSON 按目录 CODEOWNERS
推荐场景 ≤ 几十个业务 100+ 业务

关键结论

  1. 限制写法的是**"每个业务 repoURL 是否不同"**,不是业务数量:独立 GitOps 仓库 → list/files;公共单仓库 → 还可额外用目录生成器(每业务一个目录自动发现);
  2. 1000 个业务且配置各不相同 → 推荐 files generator
  3. 两种写法都满足目标架构核心诉求:ApplicationSet 只负责生成 Application,金丝雀发布由 argo-rollouts controller 独立完成,template 内置 ignoreDifferences 保护 TraefikService 运行时权重(与方案 B 一致)。

9. GitOps 仓库组织方案评估(公共单仓库可行性)

背景:目标流程最初按"每业务独立 GitOps 仓库"描述(7 业务 = 7 仓库)。业务量增长到几十、上百时,仓库数量线性增长,带来建仓、配凭证、权限、webhook 等管理 overhead。本节评估公共单仓库(monorepo)方案。

9.1 核心认知:仓库数量 ≠ 维护成本

两类成本需要区分:

  • 内容维护成本:共享 base(rollout/service/traefikservice 模板)只在 1 处维护,与仓库数量无关;
  • 仓库管理成本:建仓、配凭证、权限、webhook------随仓库数线性增长。

即使每业务独立仓库,业务仓库也只是薄薄一层(几行 overlay + image tag),共享模板仍在公共 base 中;但建 N 个仓库、配 N 次凭证的 overhead 是实打实的。公共单仓库把仓库管理成本降为 O(1)。

9.2 三方案对比

维度 A:每业务独立仓库 B:公共单仓库(monorepo) C:按域分仓(混合)
仓库数量 = 业务数 恒为 1 3~5 个
新增业务 建仓 + 配凭证 + AppSet list 加一行 加一个目录,git generator 自动发现 域内加目录
权限隔离 ✅ 最强(每仓独立授权) ⚠️ 弱(靠 CODEOWNERS/分支保护软隔离) ✅ 按域隔离
爆炸半径 ✅ 最小 ⚠️ 一次坏 push 影响全仓 ✅ 域内隔离
共享 base 升级 需跨仓传播(remote base 或额外机制) 改一处,全业务生效 ✅ 域内共享
CD 同步触发(GitOps 仓库变更 → ArgoCD) 每仓独立 webhook 需 path filter(只触发对应目录) 需 path filter
ArgoCD 凭证 每仓 1 个 只配 1 个 只配 3~5 个

9.3 公共单仓库目录结构

复制代码
gitops/                          ← 1 个仓库
├── base/                        ← 共享模板(按业务类型)
└── apps/
    ├── api/
    │   ├── kustomization.yaml   ← 引用 base
    │   └── overlays/{dev,test,uat,prod}/kustomization.yaml   ← image tag 在此
    ├── core/ ...
    └── web/ ...

ApplicationSet 用 git generator :扫描 apps/* 目录,每个子目录自动生成一个 Application。新业务 = 建 apps/xxx/ 目录,push,Application 自动出现------无需维护 list、建仓、配凭证。

9.4 与目标流程的映射(单仓库版零损耗)

目标流程"Jenkins 只修改 app1 独立 GitOps 仓库的 overlays/prod 的 image tag"→ 单仓库版:

Jenkins 修改 gitops/apps/app1/overlays/prod/kustomization.yaml 的 image tag → push → ArgoCD 检测变更 → 只同步 app1 这一个 Application。

业务隔离靠"目录独立 + Application 独立",不靠"仓库独立";目标流程中"其余业务完全不受影响"依然成立------ArgoCD 按 Application(目录)粒度同步。

9.5 单仓库短板与缓解

短板 缓解
权限粗粒度 CODEOWNERS 按目录指定 reviewer + 主分支保护 + 强制 PR 流程
坏提交影响全仓 CI 加 kustomize build 校验门禁(PR 必须 build 通过);误操作只影响本次 sync,可回滚
CI 触发粒度 path filter,或依赖 ArgoCD 轮询(只同步变更目录对应的 App)

9.6 按规模建议

  • 7 个业务(现状):直接采用公共单仓库。改造量轻于建 7 个仓库,未来无需再迁移;
  • 几十个业务:仍是单仓库,git generator 自动扩展;
  • 上百业务且团队分权明显:按域拆 2~4 个仓库(infra / 平台 / 业务域),域内仍是 monorepo------既控制仓库数量,又有域级权限边界。

9.7 结论

"独立仓库"解决的是权限隔离 ,不是"管理多少业务"的必然要求;管理大量业务靠的是 ApplicationSet git generator + 目录约定。公共单仓库在本文档对应规模下是更优解:维护成本最低、共享模板升级最方便、与目标流程映射零损耗。若后续出现强团队分权需求,再按域拆仓。


10. 改动量评估

10.1 分层工作量

改造项 量级 具体内容
新建 GitOps 仓库(推荐 1 个公共单仓库) 现有 helm 模板(rollout、双 service、TraefikService、IngressRoute、HPA、configmap)机械转译成 Kustomize base;apps/<业务>/overlays/{dev,test,uat,prod} 环境目录;gitee 建仓 + ArgoCD 配置仓库访问凭证(单仓库只需 1 个,目标约束④);仓库数量不随业务增长
业务代码仓库 helm/ 目录;Jenkinsfile 的 deploy 块从 path: helm 改为指向 gitops 仓库(每仓库约几行改动)
Jenkins 共享库 中(核心) deployWithArgoCD 改为:构建完 clone gitops 仓库 → 改 overlays/<env>/kustomization.yaml 的 image tag → commit+push → 等 ArgoCD 同步到 Healthy;② 新增金丝雀
相关推荐
易番番ERP1 小时前
筹备ERP项目|前期认知与调研的核心要点
微服务·云原生·易番番erp
AI智图坊2 小时前
宠物用品电商视觉内容生产的技术难点与自动化方案分析
大数据·运维·人工智能·ai作画·自动化·aigc
分布式存储与RustFS2 小时前
RustFS 原生支持 S3 Tables:对象存储怎么变成 AI 原生存储
云原生·开源·对象存储·分布式存储·s3·rustfs·性能基准
Query*2 小时前
Agent 开发之项目 AI 能力自我进化:通过浏览器自动化与数据采集实现持续学习
java·人工智能·ai·自动化
其实防守也摸鱼3 小时前
ZLibrary 类项目合规避坑指南:从技术实现到法律风险的全景梳理
运维·服务器·数据库·安全·自动化·github·copilot
hao xiao zi3 小时前
UI调试平台Web UI自动化项目框架设计
自动化测试·自动化·web自动化测试·playwright
天远数科4 小时前
零信任架构实战:基于天远风控经营异常预警构建自动化企业准入网关
运维·人工智能·架构·自动化
今天AI了吗4 小时前
AI工作流的自动化趋势:从手动实验到自主Agent的研究范式转变
运维·数据库·人工智能·sql·机器学习·自动化·github
青山科技分享4 小时前
跨境电商AI Agent哪个比较好用?剖析自动化运营工具的落地价值
运维·人工智能·自动化·ai智能体