Files
pikasTech-unidesk/docs/reference/gc.md
T
2026-06-01 23:41:53 +00:00

174 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.
# 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`
## 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 branch poller CronJob`v0.2` 不设 branch poller,只需确认不存在 v02 CronJob 残留。
- 等待 hwlab-ci PipelineRun、TaskRun 和 Job 空闲。
- 通过 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 失败。
## Safe Stop Line
磁盘目标可以设为 `<70%`,但安全边界优先级高于目标百分比。当执行以下命令后仍高于目标时,应停止自动清理并提交决策表:
```bash
bun scripts/cli.ts gc remote G14 plan --limit 20
bun scripts/cli.ts gc remote G14 plan --include-hwlab-registry --limit 20
```
若两个 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 确认数据类别和留存期限 |
| 扩容磁盘 | 低运行风险 | 节点容量预算和停机/在线扩容方式 |
## 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 高水位的长期基线分布如下,后续诊断出现同类量级时优先按同一顺序处理:
| 类别 | 路径 | 典型量级 | 归因说明 |
|---|---|---:|---|
| HWLAB local registry | `/var/lib/hwlab/registry` | 约 60GiB | 最大头;按 repo/tag retention 管理 |
| k3s runtime | `/var/lib/rancher/k3s` | 约 24GiB | embedded containerd、local-path PVC 和 k3s server/db |
| k3s containerd snapshots | `/var/lib/rancher/k3s/agent/containerd/.../snapshots` | 约 14GiB | workload image layer/snapshot cache,共享占用,不能直接按单 pod 删除 |
| k3s containerd blobs | `/var/lib/rancher/k3s/agent/containerd/.../blobs` | 约 6GiB | k3s image content store,共享占用 |
| k3s local-path PVC | `/var/lib/rancher/k3s/storage` | 约 3GiB | 可按 namespace/PVC 归因 |
| host containerd | `/var/lib/containerd` | 约 9GiB | k3s 外的 host/containerd cache,默认不由 remote GC prune |
| root workspaces/cache | `/root` | 约 2GiB | HWLAB/v0.2 worktree、npm/bun/cache 等 |
| logs | `/var/log` | 约 1GiB | journald 约占一半,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
bun scripts/cli.ts ssh G14 script -- 'df -h / | tail -1'
bun scripts/cli.ts ssh G14 script -- 'du -xh -d 1 / /var /var/lib /root 2>/dev/null | sort -h | tail -40'
bun scripts/cli.ts ssh G14 script -- 'du -xh -d 2 /var/lib/rancher/k3s /var/lib/containerd /var/log 2>/dev/null | sort -h | tail -80'
bun scripts/cli.ts ssh G14 script -- 'KUBECONFIG=/etc/rancher/k3s/k3s.yaml kubectl get pv,pvc,pod -A -o wide'
bun scripts/cli.ts ssh 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 元数据,存在重复计数风险。
## Validation Checklist
G14 GC 后必须验证:
```bash
bun scripts/cli.ts ssh G14 script -- 'df -h / | tail -1'
bun scripts/cli.ts ssh G14 script -- 'curl -fsS http://127.0.0.1:5000/v2/ >/dev/null && echo ok'
bun scripts/cli.ts ssh G14 script -- 'KUBECONFIG=/etc/rancher/k3s/k3s.yaml kubectl -n hwlab-ci get deploy hwlab-registry'
bun scripts/cli.ts ssh 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 健康。
## 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 提供证据,不默认删除 |
| Capacity trigger | 达到高水位时输出 safe-stop 决策表 | 避免为了百分比目标破坏运行面 |