Files
pikasTech-unidesk/project-management/PJ2026-01/specs/PJ2026-01060107-nc01-ci-resource-governance.md
T

113 lines
9.0 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.
# PJ2026-01060107 NC01 CI资源治理
## 修改历史
| 版本 | 对应 commit id | 更新日期 | 变更说明 |
| --- | --- | --- | --- |
当前正文仍在规格治理草稿中;未定稿前不新增版本号,不为单次编辑追加 `待提交` 版本。
## 正文
## PJ2026-01060107 NC01 CI资源治理需求规格
## 1. 文档控制
| 字段 | 内容 |
| --- | --- |
| 编号 | PJ2026-01060107 |
| 短名 | NC01 CI资源治理 |
| 层级 | L3 子课题 |
| 状态 | 草稿 |
| 实现引用版本 | draft-2026-07-21-p0-nc01-ci-resource-governance |
| 需求规格模板 | [ISO/IEC/IEEE 29148 需求规格模板](../../templates/iso-iec-ieee-29148-requirements-spec-template.md) |
| 上级规格 | [PJ2026-010601 发布流水](PJ2026-010601-controlled-release.md) |
| 关联规格 | [PJ2026-010603 YAML运维](PJ2026-010603-yaml-first-ops.md)、[PJ2026-01060308 CI/CD YAML-first目标治理](PJ2026-01060308-cicd-yaml-first-target-governance.md) |
| 跟踪任务 | pikasTech/unidesk#2721、TaskTree `tg_743359ba-58aa-426b-a6f0-4df84fb1d795` |
本文定义 NC01 上 CI 构建并发、排队、资源合同、稳定去重和核心运行面保护。所有可调事实由 owning YAML 控制,代码只校验、渲染和观察;禁止手改 Pipeline、PipelineRun、TaskRun、Pod 或运行中 workload 来补齐合同。
## 2. 事故与目标
单个 HWLAB PipelineRun 曾同时展开 14 个 `build-services` TaskRun,使 8 核 NC01 的 load、Swap 和 k3s Kine/SQLite 延迟同时上升,并造成核心 API 约四分钟 502。PaC Repository 的 `concurrencyLimit` 只限制 Repository 触发层的并发 PipelineRun,不能限制一个 PipelineRun 内 matrix 展开的 TaskRun 数量。
治理目标是让 PR merge 和 branch update 不再产生发布运行;每个经人工审阅的发布意图只产生一个受控运行,并让单次运行中的构建工作按 YAML 预算进入有界 worker 队列。CI 压力下,k3s 控制面、CoreDNS、Sub2API 和 Public Edge 的可用性优先于构建吞吐。
## 3. 架构与数据流
```mermaid
flowchart LR
Y[owning YAML] --> V[配置校验]
V --> R[HWLAB Pipeline renderer]
R --> D[单 TaskRun 有界 worker 队列]
D --> T[Tekton TaskRun/Pod]
T --> K[Kubernetes 调度]
T --> O[plan/status/diagnosis]
K --> C[核心运行面保护]
```
受控手动发布触发和 Pipeline 内构建排队是两个独立层次。前者由发布 `plan`、人工审阅和带计划指纹的 `trigger` 管理,PaC Repository `concurrencyLimit` 只作为运行并发上限;后者由 renderer 将目标 matrix 收敛为一个受资源约束的 TaskRun,并在 Pod 内按 `maxParallelServices` 执行有界 worker 队列。不得复制大型内联 `taskSpec`,不得把二者合并为同名字段,也不得创建数据库、ConfigMap 或常驻控制器作为第二队列 authority。
## 4. 配置合同
HWLAB node/lane target 的 `ciResourceGovernance` 至少声明:
- `build.maxParallelServices`:单个构建 TaskRun 内最多并行服务数。
- `build.taskTimeout`:单个构建 TaskRun 的 Tekton timeout。
- `build.stepResources`:构建工具 step 的 CPU/内存 requests 与 limits。
- `build.sidecarResources`BuildKit sidecar 的 CPU/内存 requests 与 limits。
- `build.priorityClassName`:构建 Pod 的可抢占优先级;必须低于核心运行面。
- `deliveryTrigger.mode`L2/L3 固定为 `manual-plan-confirm`,禁止配置自动 push、merge 或 branch follower 触发。
- `deliveryTrigger.mechanism`:固定为 `pac-webhook`;受控 CLI 发送 webhook,禁止直建 PipelineRun。
- `dedupe.identityFields`:稳定意图键字段,固定为 repository、lane、source commit 和 pipeline intent。
- `coreProtection`:核心服务优先级和最小资源预算的配置引用;各服务事实仍归自身 owning YAML,不复制进 HWLAB lane YAML。
资源字段使用 Kubernetes quantity 字符串。requests 不得超过 limitsCPU 和内存必须同时声明。NC01 默认同时运行的构建服务数不得由代码、环境变量或运行面探测回填。
## 5. 原子需求
### 5.1 CI-RESOURCE-REQ-001 分层并发与排队
Renderer 必须只对 YAML 选中的构建 matrix 建立有界 worker 队列。单个构建 TaskRun 同时工作的服务数不得超过 `maxParallelServices`,每个服务使用独立工作目录和结果目录,任一批失败后不得继续下一批。原先依赖完整 matrix 的后续任务仍依赖该构建任务,非构建任务及其既有依赖语义保持不变。
### 5.2 CI-RESOURCE-REQ-002 资源合同
构建 TaskRun 的工具 step 和 BuildKit sidecar 必须带 YAML 声明的 `computeResources`。构建 Pod 使用低于核心服务的 PriorityClass;资源不足时允许构建排队或被抢占,不允许核心 API、DNS 或控制面为构建让路。
### 5.3 CI-RESOURCE-REQ-003 稳定去重
手动触发的发布意图键固定为 `repository + lane + source commit + pipeline intent`。相同键已处于 queued、running 或 succeeded 时,受控入口不得再创建第二次构建。人工重跑必须使用显式受控入口,携带独立、可审计的 rerun intent,并先重新 plan;不得通过删除旧 PipelineRun、修改 label 或人工创建 PipelineRun 绕过去重。
### 5.4 CI-RESOURCE-REQ-004 核心运行面保护
CoreDNS 和 k3s 控制面使用 Kubernetes 系统关键优先级。Sub2API 和集群内 Public Edge 使用平台核心优先级与自身 owning YAML 的 requests/limits。Host 运行的 Public Edge 使用其 owning YAML 声明的 CPU/内存保留或限制。任何保护变更必须通过相应受控 CLI 渲染和部署,禁止从 live workload 反解后强写。
### 5.5 CI-RESOURCE-REQ-005 状态与诊断
`plan` 必须针对精确 source commit 在一次只读输出中披露:YAML configRef、env identity、env reuse/build 判定、待构建镜像数量与服务列表、待 rollout 服务、全部受影响服务、范围基线、新增范围、触发层 concurrency、构建层 max parallel、批次数、step/sidecar 资源合同、priority class 和核心保护摘要。`status``diagnosis` 必须披露运行/排队 TaskRun 数与稳定意图键状态。共享读取超时只能投影为 warning 或 unavailable,不得把全部 consumer 伪装为真实失败。
- Renderer 范围判定必须符合以下规则:
- renderer 输入或配置变化会重建完整 runtime tree,并改写未选 workload 的 source identity 时,`plan` 必须显示全部实际 rollout 服务;
- 镜像构建范围继续由 env、组件输入和 artifact provenance 独立决定;
- 禁止用局部源码影响范围替代实际 GitOps Pod template diff
- 只有未选 workload 的 manifest 和 source identity 均保持不变时,才允许报告局部 rollout。
### 5.6 CI-RESOURCE-REQ-006 中心自动触发禁用
中心 PaC owning YAML 必须声明 `deliveryTrigger.mode=manual-plan-confirm``deliveryTrigger.mechanism=pac-webhook`。PaC webhook 接收端继续作为唯一 PipelineRun 创建入口,但 Gitea push hook、PR merge callback、branch follower、poller 和其他自动发送方不得调用它;PR merge 后只允许 source mirror 或 authority 更新。受控 apply 必须删除或禁用 Gitea 自动 hook,并在 status 中把自动发送方启用视为配置漂移。
### 5.7 CI-RESOURCE-REQ-007 子进程回收
长期运行且会启动 Git、SSH、编译器或其他子进程的容器必须具有明确的子进程回收者。业务进程不得在没有 init/reaper 的情况下直接作为容器 PID 1;已经正确等待直接子进程的实现仍须处理其退出后被 PID 1 接管的孤儿后代。init/reaper 必须只负责信号转发和子进程回收,不得成为第二业务生命周期 authority。
运行面诊断必须按父 PID 聚合 zombie,并映射到 namespace、Pod、稳定 workload owner 和修复类别。修复通过正常自动交付滚动 owner;直接终止 zombie、批量杀进程或只重启 Pod 不能作为根因修复。
## 6. 验收
- L0:配置解析、资源 quantity、requests/limits 关系、matrix 收敛、有界 worker 队列和依赖保持通过轻量验证。
- L1:受控 `plan/status/diagnosis` 显示 YAML 来源、并发预算、批次、资源和保护状态,不依赖裸 Kubernetes 命令。
- L1:所有会启动子进程的常驻 Pod 均显示 init/reaper 为 PID 1;在真实 Git/SSH 操作前后,owner 的 zombie 数不增长。
- L2:正常 HWLAB source PR merge 后不产生 PipelineRun。受控 `plan` 显示 env reuse、镜像构建数量、精确构建与 rollout 范围且没有非预期扩大;随后使用手动 `trigger` 向 PaC 发送一次 webhook,并由 PaC 创建一次 PipelineRun。观察到同一时刻构建 TaskRun 不超过 YAML 预算,相同发布意图不产生第二次构建,所有构建 Pod 带资源合同,并且 NC01 Node、CoreDNS、Sub2API、Public Edge 和公开 API 在构建期间保持健康。
验收失败时保留计划、手动触发链和运行证据,并修复 owning YAML、planner 或 renderer。重启 k3s、删除 Pod/PipelineRun、手工 Argo sync、运行时 patch、mirror flush 或裸补跑均不能作为最终通过证据。