Files
pikasTech-HWLAB/docs/reference/g14-cicd-performance.md
T
2026-05-28 11:41:08 +08:00

165 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# G14 CI/CD 性能分析
本文是 HWLAB G14 CI/CD 性能优化的长期参考,覆盖 `G14` source branch、Tekton PipelineRun、per-service BuildKit 镜像发布、`G14-gitops` promotion、Argo CD sync 和 DEV runtime health。D601 legacy CI/CD、Code Queue runner 和 host 侧临时构建路径不属于本文范围。
## 性能模型
G14 CI/CD 耗时必须按阶段测量,不能只看一个 PipelineRun 总时长:
1. Source trigger`G14` source commit 被 `hwlab-g14-branch-poller` 发现。
2. Source preparation`prepare-source` clone source、checkout 精确 revision、导入最新 GitOps artifact catalog,并安装必要 npm 依赖。
3. Primitive validation`repo-reports-guard``g14-contract-check``codex-api-forwarder-check` 从准备好的 workspace 并行运行。
4. Artifact planning`plan-artifacts` 根据 component input hash 和上一轮 catalog 判断 affected/reused services。
5. Per-service fan-outaffected services 通过 BuildKit 发布镜像;reused services 复用 catalog identity,不能改变 workload pod template。
6. Artifact collection`collect-artifacts` 汇总 per-service results 并验证 publish report。
7. GitOps promotion`gitops-promote` 刷新 catalog、render desired state、commit 并 push `G14-gitops`
8. Argo rolloutArgo 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="g14-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 分离。剩余耗时主要集中在固定开销和镜像构建机制上。
当前滚动基线量级:
| 阶段 | 典型范围 | 说明 |
| --- | --- | --- |
| Source trigger | 0-60s | poller 每分钟运行一次;平均等待应接近 30s。 |
| `prepare-source` | 75-175s | 主要由 fresh clone、GitOps catalog fetch 和 `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-35sheavy build 从 120-220s 降到约 45-90sfull rebuild 预计节省 1-3m。 |
| P0 | 为服务镜像增加生成式 `.dockerignore` 或 pruned BuildKit context,排除 `.git`、prepared `node_modules`、无关 generated files 和可排除的无关 service directories。 | 降低 context transfer 和 cache invalidation。小型 build 预计节省 10-40sheavy build 预计节省 30-90s,同时降低磁盘压力。 |
| P1 | 将 unchanged services 从 BuildKit-shaped tasks 拆出。可让 `plan-artifacts` 直接输出 catalog-backed service results,或给 reused service 使用无 sidecar 的轻量 taskchanged services 保持 BuildKit。 | reuse-only 和 single-component fan-out 预计节省 10-30s,并显著减少 sidecar/pod 噪声;主要收益是稳定性和可观测性。 |
| P1 | 优化 `gitops-promote`:对 `G14-gitops` 使用 shallow/sparse checkout,复用已 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 而折叠这些边界。
## 实施顺序
1. 增加低噪声 timing instrumentation。
2.`prepare-source` 增加 npm/prepared-dependency cache。
3. 构建包含依赖和 Codex binary 的 production runtime base。
4. 裁剪 BuildKit context,并增加生成式 `.dockerignore` 保护。
5. 优化 `gitops-promote` clone/render/copy/push 机制。
6. GitOps push 后触发 Argo refresh,并测量 CI-success 到 DEV-health 耗时。
7. 将 reuse path 从 BuildKit-shaped service tasks 中拆出。
8. 扩展 failed-run retention cleanup。
9. 在 build graph 变小后再调 BuildKit resources。
## 验收标准
任何优化变更只有在给出同运行类型 before/after 数据,并保持以下不变量时,才算可交付:
- Source commit 仍是唯一 artifact identity。
- 镜像仍使用 commit tag 和 digest 作为发布身份。
- `G14-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 证明。