From 693b72d92e93cd56dd105d36364228e139b7e000 Mon Sep 17 00:00:00 2001 From: pikastech Date: Mon, 20 Jul 2026 06:33:31 +0200 Subject: [PATCH] =?UTF-8?q?docs:=20=E5=9B=BA=E5=8C=96=20k3s=20=E9=87=8D?= =?UTF-8?q?=E5=90=AF=E9=97=AD=E9=94=81=E6=81=A2=E5=A4=8D=E8=BE=B9=E7=95=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.7 --- .agents/skills/unidesk-cicd/SKILL.md | 1 + .../references/incident-recovery.md | 39 +++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/.agents/skills/unidesk-cicd/SKILL.md b/.agents/skills/unidesk-cicd/SKILL.md index e16764ca..2f35505a 100644 --- a/.agents/skills/unidesk-cicd/SKILL.md +++ b/.agents/skills/unidesk-cicd/SKILL.md @@ -84,6 +84,7 @@ bun scripts/cli.ts hwlab nodes control-plane legacy-cicd --help - PipelineRun 重复内联大型 `taskSpec` 时,必须同时检查对象总大小、`spec`、`status.pipelineSpec`、Kine compaction、API timeout、node lease 和 kubelet 调和; - PipelineRun 已成功且 GitOps commit 已生成、但 Argo 仍停在旧 revision 时,先按传播延迟只读观察,不得立即重启 k3s、人工 Argo sync 或补链; - 只有节点/API/kubelet 已实际退化且 Pod 级调和无效时,才进入有界快速恢复;重启和终态对象清理只恢复控制面,不得作为最终修复证据; + - k3s 先 panic、随后报 credential 文件新于 datastore 时,必须区分原始崩溃与重启闭锁,只可恢复性移动 fatal 点名的单个文件; - 根因判定、快速恢复、长期防复发和原入口验收统一见 [references/incident-recovery.md](references/incident-recovery.md)。 - CI/CD 只读等待: diff --git a/.agents/skills/unidesk-cicd/references/incident-recovery.md b/.agents/skills/unidesk-cicd/references/incident-recovery.md index a7274bf5..e6296eb3 100644 --- a/.agents/skills/unidesk-cicd/references/incident-recovery.md +++ b/.agents/skills/unidesk-cicd/references/incident-recovery.md @@ -172,6 +172,45 @@ - backend/provider/public `/health` 返回成功; - 恢复动作、根因假设和待持久化修复进入 issue 与 TaskTree;遗留 MDTODO 按 `$unidesk-tasktree` 迁移。 +### k3s VXLAN panic 后的 credential/datastore 启动闭锁 + +- 出现以下连续指纹时,必须拆成两个故障阶段: + - k3s 先在 flannel VXLAN 设备重建路径 panic,或因 + `inotify_init: too many open files` 等 kubelet 启动错误异常退出; + - systemd 随后持续自动重启,但每次都报 + `server/cred/ newer than datastore and could cause a cluster outage`; + - 后一条 fatal 是重启闭锁,不等于最初触发 k3s 退出的根因。 +- 快速恢复前必须保存: + - 首次退出前后的完整 panic 堆栈; + - fatal 明确点名的单个 credential 文件路径; + - 该文件的大小、权限、mtime、birth time 和 SHA-256; + - k3s unit 状态及 API、node、Service endpoint 当前状态。 + - 若存在 inotify 错误,同时记录 `fs.inotify.max_user_instances`、 + `fs.inotify.max_user_watches`、当前 inotify instance 数和遗留容器进程数。 +- 只有用户已授权恢复且 fatal 明确点名单个文件时,才允许: + - 在 `server/cred` 目录之外创建本次事故独立、权限为 `0700` 的恢复目录; + - 将被点名文件移动到该目录,保留原名,不删除文件; + - 禁止移动整个 credential 目录、删除 datastore、改写 token 或处理未点名文件; + - 重启 k3s,让它从 datastore 重新生成该文件。 +- 重启后必须比对重新生成文件与备份的大小、权限和 SHA-256: + - 一致时记录为“移除磁盘时间戳闭锁”,不能宣称凭据内容已修复; + - 不一致时停止扩大操作,保留两份文件并进入 Secret/credential 专项调查。 +- inotify instance 已接近上限时,可在用户已授权的紧急恢复中临时提高 + `fs.inotify.max_user_instances`: + - 先记录原值和当前使用量; + - 只提高 instance 上限,不修改 `fs.file-max` 或广泛终止未知进程; + - 临时值必须登记到 issue,后续由 owning YAML 决定持久值并调查 instance 泄漏; + - 临时提高上限不能替代遗留 shim、runtime 生命周期或资源泄漏修复。 +- 验收必须覆盖: + - k3s `active` 且不再 restart loop; + - node `Ready`、UniDesk workload Ready、backend `dbReady=true`; + - frontend/provider ingress 健康; + - 事故前失败的原始 `trans` route 恢复。 +- 后续 issue 必须分别追踪: + - flannel/k3s panic 的触发条件、版本和升级或规避方案; + - 被点名 credential 文件的写入者与 source of truth; + - 受控 CLI 对该 fatal 的诊断、可恢复备份和验收能力。 + ### 长期防复发 - 从 renderer/source 消除重复内联: