17 KiB
G14 CI/CD 性能分析
本文是 HWLAB G14 CI/CD 性能优化的长期参考,覆盖 G14 source branch、v0.2 加法 lane、Tekton PipelineRun、per-service BuildKit 镜像发布、GitOps promotion、Argo CD sync 和 runtime health。D601 legacy CI/CD、Code Queue runner 和 host 侧临时构建路径不属于本文范围。
性能模型
G14 CI/CD 耗时必须按阶段测量,不能只看一个 PipelineRun 总时长:
- Source trigger:
G14source commit 被hwlab-node-branch-poller发现。 - Source preparation:
prepare-sourceclone source、checkout 精确 revision、导入最新 GitOps artifact catalog,并安装必要 npm 依赖。 - Primitive validation:
repo-reports-guard、node-contract-check、codex-api-forwarder-check从准备好的 workspace 并行运行。 - Artifact planning:
plan-artifacts根据 component input hash 和上一轮 catalog 判断 affected/reused services。 - Per-service fan-out:affected services 通过 BuildKit 发布镜像;reused services 复用 catalog identity,不能改变 workload pod template。
- Artifact collection:
collect-artifacts汇总 per-service results 并验证 publish report。 - GitOps promotion:
gitops-promote刷新 catalog、render desired state、commit 并 pushG14-gitops。 - Argo rollout:Argo CD 消费
G14-gitops,同步 runtime namespace,并让公网 health 对新 desired state 生效。
每次性能报告必须标注运行类型:
reuse-only:没有服务镜像需要重建。single-component-build:一个服务镜像重建,其余服务复用。multi-component-build:多个但不是全部服务镜像重建。full-rebuild:共享输入或 build-system 输入变化导致全部服务镜像重建。
Timing 输出合同
G14 Tekton 日志中的分段耗时统一使用 JSON 行事件:event="node-cicd-timing"、schemaVersion="v1"、stage、status、durationMs,并尽量携带 pipelineRun、taskRun、task、revision 和 serviceId。后续性能对比只消费这些稳定字段,不从自然语言日志里反推耗时。
当前稳定 stage 名称:source-clone、catalog-fetch、npm-ci、buildkit-context-transfer、dependency-install、cache-import、cache-export、gitops-render、gitops-clone、gitops-commit、gitops-push、argo-refresh、workload-ready。
argo-refresh 以 hwlab-dev workload 的 hwlab.pikastech.local/source-commit 元数据收敛作为观测点,不要求 Tekton 跨 namespace patch Argo Application。workload-ready 以 hwlab-dev 的 Deployment/StatefulSet observed generation、ready replicas 和 updated replicas 为准;权限不足或超时必须用 status 明确输出,不得静默吞掉。
当前基线
当前 G14 pipeline 已具备关键架构优化:一分钟 source polling、组件级 lazy build、per-service fan-out、G14 本地 registry、本地 base image、BuildKit-only publish、GitOps/Argo 分离。v0.2 进一步引入手动 CLI trigger、专用 CI/CD source repo、devops-infra git mirror/relay 读写路径、env image 复用和 code-only boot commit rollout。剩余耗时主要集中在固定开销、GitOps promotion、runtime-ready 等待和镜像构建机制上。
v0.2 实测对比
以下对比来自 G14 k3s 内 Tekton PipelineRun/TaskRun 真实对象与 prepare-source JSON timing。按成功样本分组统计,失败样本只用于诊断,不纳入端到端成功基线。git mirror 纯读性能用同一 CI tools image 的临时 pod 在集群内测量。
| 场景 | 成功样本 | PipelineRun P50 | prepare-source P50 |
build wall P50 | 说明 |
|---|---|---|---|---|---|
G14 legacy full build,无 mirror |
8 | 512s | 114s | 23s | 14 个 build task,runtime-ready P50 约 249s。 |
v0.2 pre-mirror 9-build |
27 | 391s | 92s | 92s | 9 个保留服务 build task,GitHub/GitOps 读路径仍混在 prepare 阶段。 |
v0.2 mirror 9-build |
1 | 277s | 51s | 75s | source clone 走 mirror,样本量低,只作为趋势样本。 |
v0.2 env-reuse code-only/no-build |
3 | 172s | 49s | 0s | 8 个 task 成功、9 个 build branch skipped;只更新 boot commit/code identity。 |
v0.2 env-reuse code-only/no-build,source+catalog mirror |
2 | 143.5s | 37.5s | 0s | prepare-source 的 source clone 和 GitOps catalog lookup/fetch 都走 mirror;9 个 build branch skipped。 |
同口径 P50 加速效果:v0.2 pre-mirror 9-build 到 env-reuse code-only 约 2.27x;v0.2 pre-mirror 9-build 到 source+catalog mirror env-reuse code-only 约 2.73x;v0.2 mirror 9-build 到 source+catalog mirror env-reuse code-only 约 1.93x;G14 legacy full build 到 source+catalog mirror env-reuse code-only 约 3.57x。这些倍率只描述已观测的运行类型,不外推到 DB migration、Secret 变更或 runtime 架构变更。
git mirror 本身不是 50 秒级瓶颈。集群内临时 pod 对 http://git-mirror-http.devops-infra.svc.cluster.local/pikasTech/HWLAB.git 的早期实测结果为:git ls-remote refs/heads/v0.2 P50 约 19ms,git clone --no-checkout P50 约 787ms,git checkout --detach P50 约 64ms。修复 atomic/manual sync 后,对已发布 commit 的 git ls-remote 为 49-53ms,git cat-file <commit>^{tree} 为 40-43ms。Tekton prepare-source 的 37-65s wall time 是混合耗时,包含 entrypoint/PVC/workspace 启动、proxy/npm probe、source clone、GitOps catalog 读取、npm ci 和脚本收尾,不能直接归因给 mirror。
已观测的 prepare-source 内部分段:source clone 经 mirror 后约 0.9-1.1s;GitOps catalog 读取若仍走 canonical GitHub SSH 约 9s;catalog lookup/fetch 改走 mirror 后,catalog-ls-remote 为 47-58ms,catalog-fetch 为 92-113ms,catalog-fetch JSON timing 总计 277-348ms;npm ci --ignore-scripts 约 15-18s;剩余为 Tekton entrypoint、PVC/workspace、探针和 shell/Node 启动固定开销。只读 catalog lookup/fetch 与 source clone 一样走 git-read-url mirror;v0.2 GitOps promotion 写入 devops-infra 本地 mirror/relay,GitHub flush 异步完成,不在 CI 关键路径直接 push canonical remote。
devops-infra git mirror sync/flush 是 mirror 边界维护成本,不是 CI 读路径成本。mirror 不设 CronJob,trigger-current --lane v02 会在创建 PipelineRun 前按需执行一次 bounded pre-sync;bun scripts/cli.ts hwlab g14 git-mirror sync --confirm 和 git-mirror flush --confirm 只作为显式 mirror 维护或诊断入口。代表性手动 sync 样本中,Job 脚本内 total 为 12.1s,其中 GitHub fetch 4.6s、object closure validate 6.0s、publish update-ref 1.1s、fsck 0.12s;UniDesk route 从创建 Job 到返回日志总计约 18.9s。这个 12-19s 不代表 mirror clone 速度,而是 GitHub SSH fetch、对象校验、Kubernetes Job 启动/轮询和日志采集的总成本。
当前滚动基线量级:
| 阶段 | 典型范围 | 说明 |
|---|---|---|
| Source trigger | 0-60s 或手动触发开销 | G14 poller 每分钟运行一次,平均等待应接近 30s;v0.2 不设 poller,由 UniDesk 手动 trigger 自动 fetch 专用 CI/CD repo 并按需 pre-sync mirror。 |
prepare-source |
37-175s | source+catalog mirror 的 code-only 样本为 37-38s;旧路径、多 build 或未优化样本可到 75-175s。当前主要固定成本已转为 Tekton/PVC/entrypoint 和 npm ci。 |
| Primitive validation | 每项 5-10s | source 准备后并行运行,目前不是主要瓶颈。 |
plan-artifacts |
6-10s | 当前可接受,重点是保持只读和确定性。 |
| Reused service TaskRun | 每项 8-12s | fan-out wall time 接近最慢复用 task,但 unchanged services 仍会启动 build-shaped pod。 |
| Fast affected service build | 25-35s | 小型 Node 服务且 cache 命中时的常见范围。 |
| Heavy affected service build | 120-220s | 依赖面宽或重建 Codex 相关层的服务可能达到该范围。 |
collect-artifacts |
8-10s | 当前可接受,主要是校验和 report assembly。 |
gitops-promote |
50-105s | 主要由 render/check、GitOps clone/checkout、tree copy、commit、push 构成。 |
| Argo sync 到 DEV Healthy | 10-220s | 受 repository refresh timing 和 workload 是否真实滚动影响较大。 |
当前端到端预期范围:
| 运行类型 | PipelineRun | source commit 后到 DEV Healthy |
|---|---|---|
reuse-only |
3-4.5m | 3.5-6m |
single-component-build |
3.2-5.5m | 4-7.5m |
full-rebuild |
6-7m | 6.5-9m |
这些值是性能基线,不是发布 SLO。任何 CI/CD 优化变更都应按同一种运行类型做 before/after 对比。
根本原因
Source Preparation 冷启动
prepare-source 每次 PipelineRun 都执行 fresh source clone、精确 checkout、GitOps catalog lookup 和 npm ci。当前 tools image 已避免运行时安装系统包,但没有消除每轮 npm install 成本。npm 或 GitHub 延迟上升时,后续 validation 和 build task 都会被这个共享 workspace 阻塞。
根因:source preparation 被当成无状态冷启动处理,但实际工作负载反复使用同一个小型依赖图和同一个私有仓库。
Build Context 过宽且重复处理 Runtime 依赖
服务镜像由 scripts/artifact-publish.mjs 生成 Dockerfile。该 Dockerfile 安装 production npm dependencies,然后复制 internal、cmd、scripts、web、tools、skills、deploy 等大范围目录。per-service Tekton task 还会先把 prepared source repo 复制到 service work directory,再调用 BuildKit。
根因:BuildKit 接收到 monorepo-shaped context,并重复执行本应预烘或按服务裁剪的 dependency-layer 工作。
Reuse 路径仍启动 Build-Shaped Pod
组件级 lazy build 已能正确把 unchanged services 标成 reused,但每个服务仍有一个带 BuildKit sidecar wiring 的 build-* TaskRun。reused services 会很快写出 Tekton results 并退出,但 Kubernetes 仍要承担 pod scheduling、sidecar setup、entrypoint setup 和 result collection 开销。
根因:Tekton result wiring 绑定在 service task 上,reuse 被实现为 build-shaped task 内部的快速分支,而不是更轻量的 catalog-result 路径。
GitOps Promotion 做了完整 Workspace 工作
gitops-promote 做 source freshness check、artifact catalog refresh、desired state render、render check、GitOps branch clone、generated state copy、commit 和 push。这保证了 release truth 清晰,但当前 repository 和文件树操作比必要量更重。
根因:GitOps promotion 语义正确,但没有针对 shallow/sparse branch operation 或 incremental generated-state update 做优化。
Argo Repository Discovery 带来变量延迟
gitops-promote push G14-gitops 后,Argo CD 不一定立刻发现新 revision。对于 reused-image 或小镜像变更,workload rollout 本身可能很快,repository discovery 反而变成端到端耗时里的显著部分。
根因:CI push 和 Argo refresh 是松耦合的;GitOps 仍是真相,但运行态观察会滞后于 push。
Retention Cleanup 对排障噪声覆盖不足
retention cleaner 会删除超过保留窗口的 completed PipelineRuns,但近期 failed PipelineRuns、failed TaskRuns 和 orphan Error pods 仍可能堆在 hwlab-ci。这通常不会给 pipeline 增加分钟级耗时,但会拖慢诊断并制造 API/list 噪声。
根因:retention policy 更偏向长期清理,不是针对已知 bad-run burst 后的近期失败对象治理。
改进建议
| 优先级 | 建议 | 预期效果 |
|---|---|---|
| P0 | 增加稳定的分段 timing 输出,覆盖 source clone、catalog fetch、npm ci、BuildKit context transfer、dependency install、cache import/export、GitOps clone、render、commit、push、Argo refresh、workload ready。 |
直接加速很小,但能让后续优化具备可比数据,避免把网络、npm、BuildKit、Argo 延迟混为一谈。 |
| P0 | 给 prepare-source 使用 npm dependency cache,或在 CI tools image 里预装 repo dependencies,同时保留对 package-lock.json 精确性的校验。 |
将 prepare-source 从 75-175s 降到约 35-70s。单轮 PipelineRun 预计节省 40-100s。 |
| P0 | 构建并使用包含 production node_modules、Codex package 和平台专用 Codex binary 的 runtime base image。 |
减少服务镜像重复依赖工作。fast build 维持约 20-35s;heavy build 从 120-220s 降到约 45-90s;full rebuild 预计节省 1-3m。 |
| P0 | 为服务镜像增加生成式 .dockerignore 或 pruned BuildKit context,排除 .git、prepared node_modules、无关 generated files 和可排除的无关 service directories。 |
降低 context transfer 和 cache invalidation。小型 build 预计节省 10-40s,heavy build 预计节省 30-90s,同时降低磁盘压力。 |
| P1 | 将 unchanged services 从 BuildKit-shaped tasks 拆出。可让 plan-artifacts 直接输出 catalog-backed service results,或给 reused service 使用无 sidecar 的轻量 task,changed services 保持 BuildKit。 |
reuse-only 和 single-component fan-out 预计节省 10-30s,并显著减少 sidecar/pod 噪声;主要收益是稳定性和可观测性。 |
| P1 | 优化 gitops-promote:G14 DEV/PROD 对 G14-gitops 使用 shallow/sparse checkout;v0.2 对 devops-infra mirror/relay 使用最小写入,并复用已 render 的输出做 check,避免复制或提交未变化的 generated paths。 |
将 gitops-promote 从 50-105s 降到约 20-45s。每轮 promotion 预计节省 30-60s。 |
| P1 | GitOps push 成功后触发 Argo hard refresh,再用短轮询观察 sync。 | 当 workload 本身健康时,CI succeeded 到 DEV Healthy 从 10-220s 降到约 10-60s。 |
| P1 | 扩展 failed-run retention:给 failed PipelineRuns 和 orphan Error pods 设置明确的短保留窗口,同时禁止删除 active PipelineRuns 和 runtime namespaces。 | 对 pipeline 直接加速有限,但能显著降低 bad-run burst 后的诊断噪声和 API/list 噪声。 |
| P2 | 保持一分钟 polling,除非 source-trigger wait 成为主瓶颈;在固定开销降低前不要优先引入 GitHub webhook 复杂度。 | 理论平均最多节省约 30s;当前收益低于 prepare-source、BuildKit 和 GitOps promotion。 |
| P2 | 在 context 和 base image 优化落地后,再调 BuildKit CPU/memory requests 与 cache export mode。 | 可能额外提升 build 10-20%,但在 build context 和 dependency layer 仍过宽时过早调资源不可靠。 |
高优先级改进后的预期效果
高优先级改进指 P0 项,加上 P1 的 GitOps promotion 优化和 Argo refresh coupling。它不要求改变当前 Tekton/GitOps/Argo truth model,也不需要回退到 shell runner。
预期高优先级优化后范围:
| 运行类型 | PipelineRun | source commit 后到 DEV Healthy |
|---|---|---|
reuse-only |
1.8-2.6m | 2.2-3.5m |
single-component-build |
2.0-3.2m | 2.5-4m |
full-rebuild |
3.8-5.2m | 4.3-6m |
这是第一阶段务实目标:保持当前发布真相模型,优先消除普通 PR rollout 中占比最高的固定成本。
全部建议落地后的预期效果
全部建议包括高优先级项、reuse task 拆分、failed-run retention 改进,以及后续 BuildKit resource tuning。
预期全部优化后范围:
| 运行类型 | PipelineRun | source commit 后到 DEV Healthy |
|---|---|---|
reuse-only |
1.2-1.8m | 1.5-2.5m |
single-component-build |
1.6-2.6m | 2-3.2m |
full-rebuild |
3-4.5m | 3.5-5m |
剩余下限是真实工作:私有 source 访问、validation、immutable image publication、GitOps truth update、Argo sync 和 live runtime health。不要为了追求亚分钟 full CI/CD 而折叠这些边界。
实施顺序
- 增加低噪声 timing instrumentation。
- 为
prepare-source增加 npm/prepared-dependency cache。 - 构建包含依赖和 Codex binary 的 production runtime base。
- 裁剪 BuildKit context,并增加生成式
.dockerignore保护。 - 优化
gitops-promoteclone/render/copy/push 机制。 - GitOps push 后触发 Argo refresh,并测量 CI-success 到 DEV-health 耗时。
- 将 reuse path 从 BuildKit-shaped service tasks 中拆出。
- 扩展 failed-run retention cleanup。
- 在 build graph 变小后再调 BuildKit resources。
验收标准
任何优化变更只有在给出同运行类型 before/after 数据,并保持以下不变量时,才算可交付:
- Source commit 仍是唯一 artifact identity。
- 镜像仍使用 commit tag 和 digest 作为发布身份。
- G14 DEV/PROD 的
G14-gitops或v0.2的本地 mirror/relayv0.2-gitops仍是 Argo CD 消费的 desired-state truth。 - Unchanged services 不会因为全局 source commit 变化而滚动。
- Failed/stale PipelineRun cleanup 不触碰
hwlab-dev、hwlab-prod、Argo runtime state、registry storage 或 active PipelineRuns。 - Runtime success 仍由 Argo Application revision、workload readiness 和必要公网 health 证明。