Files
pikasTech-unidesk/docs/reference/gc.md
T
2026-06-11 00:41:20 +00:00

237 lines
19 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.
# Disk GC And Retention Reference
UniDesk 的磁盘治理入口是 `bun scripts/cli.ts gc ...`。该入口用于短期一次性止血和低风险防膨胀策略,所有清理动作都必须先有结构化 plan,再通过显式确认执行。GC 不是通用 `rm -rf` 或原生命令集合;当目标磁盘水位无法在保护边界内下降到阈值以下时,应停止并升级为 retention/capacity 决策,而不是扩大清理范围。
## Command Boundary
- `gc plan`:只读生成主 server 清理候选、估算收益、风险等级、保护对象和数据库诊断摘要。
- `gc run --confirm`:只执行当前 plan 可见候选页,默认不执行分页隐藏候选;用 `--limit``--result-limit``--full|--raw` 控制披露和执行范围。
- `gc policy plan|install`:渲染或安装低风险长期策略,例如 journald cap 和每日 allowlisted 文件/tmp 清理 timer。
- `gc db-trace plan|run --confirm --before-date YYYY-MM-DD --vacuum-full`:显式 trace 遥测留存入口;涉及数据库重写时按维护窗口处理。
- `gc remote <providerId> plan|run --confirm|status --job-id <id>`:通过 UniDesk SSH 透传在 provider host 上执行受控 GC。远端长任务必须使用异步 job 和 `status` 短查询,不应让单次 SSH 等待完整 registry GC 或其他长清理。
所有成功和失败输出都必须是 JSON。`plan` 必须标记 `dryRun=true``mutation=false``run` 必须要求 `--confirm` 并报告 `diskBefore``diskAfter``summary``results``protected`。远端 GC 可用 `--target-use-percent N` 显式表达目标根盘水位;`summary.target` 必须给出目标所需释放量、候选估算、预计水位、缺口和 `safeStop` 决策,避免靠人工心算判断是否应该继续扩大清理范围。
## Protected Data
默认 GC 不得删除或 prune 以下对象:
| 对象 | 保护原因 |
|---|---|
| PostgreSQL PGDATA | 数据库权威状态,必须走备份、留存或迁移流程 |
| Docker image/container/volume | 运行面和发布真相可能依赖旧镜像或 volume |
| Baidu Netdisk staging/backups | 备份链路状态和可重建缓存边界需单独判定 |
| D601 registry storage | artifact registry retention 需使用专门入口 |
| `/var/lib/rancher/k3s``/var/lib/rancher/k3s/storage` | k3s 控制面、containerd 状态和 local-path PVC 数据 |
| `/var/lib/kubelet``/var/lib/containerd` | kubelet/runtime 状态和可能被 workload 复用的 image cache |
| HWLAB 固定 workspaces | `/root/hwlab``/root/hwlab-v02``/root/agentrun` 是 source/runtime 约束的一部分 |
| Kubernetes workload、Secret、PVC、PV、Argo、Tekton 对象 | 必须通过对应运行面 retention 子命令或 GitOps/CI 控制入口处理 |
如果需要触碰上表对象,必须先补高层 UniDesk CLI 子命令、dry-run 计划、保护对象、验证命令和失败分类;不能把原生 `kubectl``docker prune``crictl rmi` 或手写 registry shell 作为长期流程。
## Remote G14 Policy
`gc remote G14 ...` 必须先确认目标是 G14 原生 k3s 节点,且 preflight 中节点名包含 `ubuntu-rog-zephyrus-g14-ga401iv-ga401iv`。G14 默认候选只允许:
- systemd journal vacuum 到目标上限。
- Docker `json-file` 日志截断。
- Docker BuildKit cache prune,默认只清理超过 `--build-cache-until` 的 cache。
- apt archive clean。
- allowlisted `/tmp` 诊断目录删除。
- 受限 core dump 删除。
受限 core dump 只匹配 `/root/unidesk/core.<pid>` 普通文件。执行前必须重新校验路径 allowlist、Git 未跟踪、非 symlink、无 `fuser` 活跃引用。估算收益必须按实际分配块数计算,并可另行披露 `apparentSizeBytes`;不能把 sparse core dump 的表观大小当成可回收磁盘空间。
## HWLAB Registry Retention
G14 HWLAB registry 清理必须显式使用 `--include-hwlab-registry`,默认 `gc remote G14 plan` 不进入 registry。策略必须保守,不能只留 latest,也不能只删除 tag link 后误判已经释放空间。
默认保留规则:
| 保留项 | 规则 |
|---|---|
| 当前 workload 引用 | 保留所有当前 k3s workload 使用的 tag ref 和 digest ref |
| digest closure | 从当前 workload、保留 tag、protected/base/非业务 repo 出发,保留 manifest config/layer/manifest-list 的 digest 闭包 |
| 近期 tag | 保留 `--registry-min-age-hours` 内全部 tag,默认 48 小时,可显式设为 0 |
| 每 repo 最新 tag | 每个业务 repo 至少保留 `--registry-keep-per-repo` 个最新 tag,默认 20,最小 1 |
| cache/base/protected tag | 保留 cache repo、`latest`、基础镜像 tag 和显式 protected tag |
| 非业务 repo | 默认不删除非 `hwlab/hwlab-*` 的 commit-like tag |
删除范围包括两类:不在保留集内的 commit-like tag,以及 `hwlab/hwlab-*` / `hwlab/cache/hwlab-*` repo 内不在保留 digest closure 的 stale `_manifests/revisions/sha256/<digest>`。执行时先在 registry 在线状态下通过 API 删除 manifest,再缩容 registry pod,删除遗留 tag/revision 目录,运行官方 `registry garbage-collect`,最后恢复 registry。`--registry-gc-only` 只用于中断恢复或人工维护窗口收尾:它不删除任何 tag 或 revision,只运行官方 GC。
BuildKit cache repo 的历史 `latest` 写入会留下大量 untagged manifest revision;只删除 tag 通常只能释放少量 manifest blob,无法释放旧 cache layer。需要大幅降低 `/var/lib/hwlab/registry` 时,必须以 plan 输出的 `deleteRevisions``protectedDigestClosure` 和 official GC 后的 `diskAfterBytes` 判断是否真正生效。
Registry 执行必须以远端异步 job 完成,并具备以下维护保护:
- 先记录并暂停 G14/v0.2 branch poller CronJob;目标集群中某条 lane 暂无 CronJob 时记录为 absent,不视为失败。
- 暂停 poller 后再等待 hwlab-ci PipelineRun、TaskRun 和 Job 空闲;不能在暂停前因为 active CI 直接拒绝,否则 poller 竞态会导致 maintenance 反复失败。
- 通过 registry API 删除 manifest 时 registry 必须仍在线。
- registry 下线后只能删除通过 plan 判定的 tag/revision 目录;不得直接删除 blob 目录。
- 缩容 registry 后运行官方 `registry:2.8.3` garbage-collect pod。
- finally 阶段删除 GC pod、恢复 registry replicas、等待 rollout、恢复 CronJob suspend 状态。
- 状态查询使用 `gc remote G14 status --job-id <id>`,不使用长 SSH 会话等待。
- `gc remote` 的 stdout 是有界 JSON:当 `--full` 或大量候选导致结果过大时,完整结果会写入远端 `/tmp/unidesk-gc-remote/jobs/<job>.json`stdout 只返回摘要、`jobId``statePath``statusCommand`,再用 `gc remote G14 status --job-id <job>` 渐进查询,避免输出爆炸被误判为 JSON 失败。
## G14 CI Workspace Retention
G14 的 Tekton workspace retention 不能通过原生 `kubectl delete`、直接删除 `/var/lib/rancher/k3s/storage` 或手工清 PV host path 完成。所有完成态 PipelineRun workspace 清理都必须走对应高层 UniDesk CLI,先 dry-run 输出候选和保护对象,再 confirm 执行。
AgentRun `v0.1` 使用 `agentrun-ci` namespace
```bash
bun scripts/cli.ts agentrun control-plane cleanup-runs --min-age-minutes 30 --limit 200 --dry-run
bun scripts/cli.ts agentrun control-plane cleanup-runs --min-age-minutes 30 --limit 200 --confirm
bun scripts/cli.ts agentrun control-plane cleanup-released-pvs --limit 200 --dry-run
bun scripts/cli.ts agentrun control-plane cleanup-released-pvs --limit 200 --confirm
```
HWLAB 使用 `hwlab-ci` namespace
```bash
bun scripts/cli.ts hwlab g14 control-plane cleanup-runs --lane v02 --min-age-minutes 30 --limit 200 --dry-run
bun scripts/cli.ts hwlab g14 control-plane cleanup-runs --lane v02 --min-age-minutes 30 --limit 200 --confirm
bun scripts/cli.ts hwlab g14 control-plane cleanup-released-pvs --lane all --limit 200 --dry-run
bun scripts/cli.ts hwlab g14 control-plane cleanup-released-pvs --lane all --limit 200 --confirm
```
Retention 入口的长期合同:
- 默认只选择 `Succeeded`/`Failed` 的完成态 PipelineRun,且必须达到 `--min-age-minutes`
- 默认保护每条 lane 或前缀下最新完成的 PipelineRun,保留当前 CI/CD 状态证据;只有显式定点目标才允许清理最新证据。
- dry-run 必须披露候选 PipelineRun、owned PVC、active mount 保护、预估可回收空间或可回收对象数,以及 confirm 命令。
- confirm 首先删除 PipelineRun,让 Tekton ownerRef 释放临时 PVC;随后用 `cleanup-released-pvs` 处理 local-path 未自动删除的 `Released` PV。
- `cleanup-released-pvs` 只能选择 `local-path``Delete` reclaim policy、目标 CI namespace 的 Released PV;不得触碰业务 namespace、runtime PVC、Secret、registry storage 或 GitOps desired state。
CI workspace retention 是 registry retention 之前的低风险步骤。若它清不出足够空间,不能扩大到 raw PV/path 删除;应继续进入 registry retention plan,或进入 safe-stop 决策。
## Safe Stop Line
磁盘目标可以设为 `<70%` 或维护窗口临时目标如 `<50%`,但安全边界优先级高于目标百分比。目标必须直接传给 CLI,使输出带有可机读缺口:
```bash
bun scripts/cli.ts gc remote G14 plan --target-use-percent 50 --limit 20
bun scripts/cli.ts gc remote G14 plan --target-use-percent 50 --include-hwlab-registry --limit 20
```
`summary.target.safeStop=true``state``shortfall``safe-stop-no-meaningful-candidates` 时,应停止自动清理并提交决策表。若默认 plan 和 registry plan 都无法覆盖目标缺口,剩余空间通常位于 registry 保留集、k3s runtime、containerd image cache 或 PVC 数据中。继续下降需要显式选择以下更高风险方案之一:
| 方案 | 风险 | 需要的前置决策 |
|---|---|---|
| 降低 registry 每 repo 保留数或缩短近期 tag 窗口 | 可能影响切旧 tag 回滚 | 明确旧 tag 回滚窗口和服务 owner 接受标准 |
| containerd/k3s image cache prune | 可能触发 workload 重新拉镜像或旧镜像缺失 | registry 健康、镜像可拉取性和维护窗口 |
| PVC/runtime 数据 retention | 可能删除业务状态或 CI 证据 | 业务 owner 确认数据类别和留存期限 |
| rsyslog 文件日志压缩/截断 | 可能丢失一线故障证据 | 明确日志留存窗口,先补受控 CLI/logrotate 策略 |
| source worktree/cache TTL | 可能删除并行任务上下文或本地依赖缓存 | worktree owner、分支状态、dirty 状态和可重建性判定 |
| 扩容磁盘 | 低运行风险 | 节点容量预算和停机/在线扩容方式 |
G14 进入 50% 这类维护窗口目标时,标准顺序是:
1. `gc remote G14 plan --target-use-percent <N>` 取得默认低风险候选和缺口。
2. 运行 AgentRun/HWLAB CI workspace retention,并二次处理 Released PV。
3. 使用 `--include-hwlab-registry` 规划 registry retention;默认保守保留,维护窗口内可显式把 `--registry-keep-per-repo` 降到 1,但必须保留当前 workload refs 和 digest closure。
4. 再次运行 `gc remote G14 plan --target-use-percent <N> --include-hwlab-registry ...`
5. 若只剩 KiB 级低风险候选且 `safeStop=true`,停止自动清理,不得为了命中百分比目标手工删除受保护目录。
## G14 Space Attribution Baseline
G14 当前只有一个本机 k3s cluster;空间归因时不要把 `hwlab-dev``hwlab-prod``hwlab-v02` 理解成独立 cluster,它们是同一 k3s 上的 namespace/runtime slice。长期诊断应按三层归因:
| 层级 | 归因方式 | 判读口径 |
|---|---|---|
| Host path | `du -x``/var/lib/*``/root``/usr` 等目录统计 | 判断根盘主要压力源 |
| k3s namespace/PVC | `kubectl get pv,pvc,pod -A -o json` 结合 local-path PV host path | 把可归属数据映射到 namespace/workload |
| Registry repo/tag/revision | registry v2 repository/tag link、manifest revision 与 blob manifest 解析 | 判断镜像历史 tag、cache revision 与共享 layer 的贡献 |
G14 高水位的长期基线分布如下,后续诊断出现同类量级时优先按同一顺序处理。registry 和 CI workspace retention 后,空间压力通常从 `/var/lib/hwlab/registry` 转移到 k3s containerd snapshot/content、local-path PVC、host containerd、rsyslog 文件日志和 source worktree/cache;这些都属于受保护或需策略化处理的运行面,不能为了达到百分比目标直接删除目录。
| 类别 | 路径 | 典型量级 | 归因说明 |
|---|---|---:|---|
| HWLAB local registry | `/var/lib/hwlab/registry` | 高水位约 60GiB;强 retention 后约十几 GiB | 最大头;按 repo/tag/revision retention 管理,不能直接删 blob |
| k3s runtime | `/var/lib/rancher/k3s` | 高水位约 45-55GiB;清理后约 28-35GiB | embedded containerd、local-path PVC 和 k3s server/db |
| k3s containerd snapshots | `/var/lib/rancher/k3s/agent/containerd/.../snapshots` | 高水位约 30-40GiB;清理后约十几 GiB | workload image layer/snapshot cache,共享占用,不能直接按单 pod 删除 |
| k3s containerd blobs | `/var/lib/rancher/k3s/agent/containerd/.../blobs` | 高水位约 8-12GiB;清理后约数 GiB | k3s image content store,共享占用 |
| k3s local-path PVC | `/var/lib/rancher/k3s/storage` | 高水位约 8-10GiBCI retention 后约 6-8GiB | 可按 namespace/PVC 归因,只能通过运行面 retention 入口清理 |
| host containerd | `/var/lib/containerd` | 约 9-12GiB | k3s 外的 host/containerd cache,默认不由 remote GC prune |
| root workspaces/cache | `/root` | 约 2-8GiB | HWLAB/v0.2 worktree、npm/bun/cache 等;worktree TTL 需 owner/dirty 判定 |
| logs | `/var/log` | 约 1-3GiB | journald 可由 GC caprsyslog 文件需受控 logrotate/压缩策略,pod logs 通常较小 |
PVC 的长期判读口径:
| Namespace | 典型占用 | 主要来源 |
|---|---:|---|
| `hwlab-ci` | 约 2GiB | 完成态 Tekton TaskRun workspace PVC;单个 PVC 通常约 0.24GiB |
| `hwlab-dev` | 数百 MiB | `hwlab-code-agent-workspace` 与 dev Postgres |
| `hwlab-prod` | 数百 MiB | `hwlab-code-agent-workspace` |
| `hwlab-v02` | 数百 MiB | `hwlab-code-agent-workspace` 与 v0.2 Postgres |
Registry 的长期判读口径:
| Repo 类型 | 典型形态 | 说明 |
|---|---|---|
| `hwlab/hwlab-cloud-api` | tag 数可超过 20unique blob 数 GiB | 最大业务 repo,优先观察 tag 增长 |
| `hwlab/hwlab-agent-*``hwlab/hwlab-cloud-web``hwlab/hwlab-gateway*` | 每 repo 保留约 20 tag 时通常各占数 GiB | 多服务并行构建导致 registry 线性增长 |
| `hwlab/cache/*` | tag 少但共享 layer 多 | 不能按 expanded size 简单相加 |
| base/protected image | tag 少,占用低到中等 | 保留用于构建和运行回滚 |
Registry 报告必须区分 `uniqueBlobBytes``sharedBlobBytes`。多个 repo/tag 复用同一 layer 时,expanded tag size 会重复计算;判断可回收空间应以 official registry GC 后的根目录变化为准。
## Diagnosis Commands
G14 空间审计默认只读。需要报告时优先采集以下摘要,避免全量 dump 大 JSON:
```bash
trans G14 script -- 'df -h / | tail -1'
trans G14 script -- 'du -xh -d 1 / /var /var/lib /root 2>/dev/null | sort -h | tail -40'
trans G14 script -- 'du -xh -d 2 /var/lib/rancher/k3s /var/lib/containerd /var/log 2>/dev/null | sort -h | tail -80'
trans G14 script -- 'KUBECONFIG=/etc/rancher/k3s/k3s.yaml kubectl get pv,pvc,pod -A -o wide'
trans G14 script -- 'find /var/lib/hwlab/registry/docker/registry/v2/repositories -path "*/_manifests/tags/*/current/link" -type f | wc -l'
```
需要深挖 registry 时,报告字段至少包括 repo、tag count、manifest revision count、latest tags、protected digest closure、unique blob bytes 和 shared blob bytes。需要深挖 k3s runtime 时,报告字段至少包括 namespace/PVC、PV host path、owner workload、PVC 实占、k3s containerd snapshots/blobs 总量。不要把 `/var/lib/kubelet/pods``/var/lib/rancher/k3s/storage` 简单相加,因为 kubelet pod 目录可能包含 PVC bind mount 或 runtime 元数据,存在重复计数风险。
需要深挖日志和 worktree 时,默认只读报告,不直接清理:
```bash
trans G14 script -- 'du -xh -d 1 /var/log 2>/dev/null | sort -h | tail -40'
trans G14 script -- 'du -xh -d 2 /root/hwlab-v02/.worktree 2>/dev/null | sort -h | tail -60'
```
rsyslog 文件日志不属于当前 `gc remote` 默认可变更对象。若 `/var/log/syslog*``/var/log/kern.log*` 或同类文件成为 50% 目标的最后缺口,应先新增受控 logrotate/压缩/截断 CLI,并在输出中披露保留 tail、压缩对象、释放估算和失败恢复;禁止直接 `truncate` 或删除日志文件作为长期流程。`/root/hwlab-v02/.worktree` 只能在明确 owner、branch、dirty 状态和可重建性后清理,不能按目录大小直接删除。
## Validation Checklist
G14 GC 后必须验证:
```bash
trans G14 script -- 'df -h / | tail -1'
trans G14 script -- 'curl -fsS http://127.0.0.1:5000/v2/ >/dev/null && echo ok'
trans G14 script -- 'KUBECONFIG=/etc/rancher/k3s/k3s.yaml kubectl -n hwlab-ci get deploy hwlab-registry'
trans G14 script -- 'KUBECONFIG=/etc/rancher/k3s/k3s.yaml kubectl -n hwlab-ci get cronjob hwlab-g14-branch-poller -o custom-columns=NAME:.metadata.name,SUSPEND:.spec.suspend --no-headers && ! KUBECONFIG=/etc/rancher/k3s/k3s.yaml kubectl -n hwlab-ci get cronjob hwlab-v02-branch-poller >/dev/null 2>&1'
```
DEV workload 验证应检查非零副本 workload 是否 ready`0/0` 的显式停用 deployment 不应误报为事故。registry tag 数只作为辅证,不能替代 workload ref 保护和 registry API 健康。
同时必须用高层 CLI 验证受影响运行面仍对齐:
```bash
bun scripts/cli.ts agentrun control-plane status
bun scripts/cli.ts hwlab g14 control-plane status --lane v02
bun scripts/cli.ts agentrun control-plane cleanup-runs --min-age-minutes 30 --limit 200 --dry-run
bun scripts/cli.ts hwlab g14 control-plane cleanup-released-pvs --lane all --limit 200 --dry-run
```
验收结论至少包含:根盘水位、`DiskPressure=False`、registry readiness/API、AgentRun `aligned=true`、HWLAB v0.2 `state=aligned`、active PipelineRun 数,以及 remaining low-risk candidates / safe-stop 决策。若目标百分比未达到但 `safeStop=true`,必须写清剩余缺口和下一类策略选择,不得把未执行的高风险清理伪装成已完成。
## Long-Term Anti-Bloat Plan
| 措施 | 默认策略 | 预期收益 |
|---|---|---|
| Registry conservative retention | workload refs + 48h tag + 每 repo 20 tag + official GC | 高构建频率下通常是主要收益,可释放十几到几十 GiB |
| CI tag growth cap | 每个 service 对 commit tag 增长设置上限并进入 GC plan | 防止 registry 每周持续膨胀 |
| Tekton/Pipeline retention | 完成态 PipelineRun/TaskRun/Job 按留存期清理 | 释放少量空间,降低 API 噪声 |
| Log/journal cap | journald 上限、文件日志轮转、Docker json log truncate | 稳定防止日志膨胀,收益通常为数百 MiB 到数 GiB |
| Core dump limits | 限制 dump 大小或按 allowlist 删除实际分配块 | 防止 crash dump 污染观测;sparse dump 不应被高估 |
| Containerd image audit | 定期只读报告 runtime image cache 构成 | 为维护窗口 prune 提供证据,不默认删除 |
| Worktree TTL audit | 报告 `.worktree` owner、branch、dirty 和 node_modules/cache 占用 | 为安全清理并行任务 scratch 提供证据 |
| Capacity trigger | 达到高水位时输出 safe-stop 决策表 | 避免为了百分比目标破坏运行面 |