174 lines
13 KiB
Markdown
174 lines
13 KiB
Markdown
# 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 数可超过 20,unique 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 决策表 | 避免为了百分比目标破坏运行面 |
|