⚠️ 本提交是**另一执行会话**(台账记录的 T01 执行方)已完成、且**已上线**的源码侧改动, 由本会话代为入库(台账 T01 已标「已完成并归档」;线上插件 0.3.21 已投放两实例)。 - 形态:并入既有「功能管理」section 内的**分组**,**不新开 section**(用户口径「不要分开管理」); **仅入口层合并、机制层独立** —— 技能是 watch 驱动(启停立即生效、无需重启),插件要重启实例, 两条 API(/api/skills/mine* vs /api/plugins/mine*)与两套落盘位置一律不动。 - 行式交互:名称(截断三件套)+ 来源徽章(共享/我的)+ 状态 + 事实(文件数·体积,tabular-nums)+ 动作; 沿用官方卡片行语汇(动作区 margin-left:auto + nowrap)⇒ **结构上不可能换行**。 - 平台共享技能(source:'shared'、locked)显示 🔒 且**不渲染任何动作按钮**, 与后端 assertNotShared() 的 409 双向一致(前端不给注定失败的按钮,后端仍兜底)。 - 上传/删除:同名走**两阶段替换**(先暂存 → 页内确认,写明「不可恢复」+ 旧/新文件数对照); 删除必须过页内确认;启用/停用可逆故不弹窗。失败一律行内展示后端中文原文(不自己造词)。 - zh/en 全量词条(msk.*,46 条/语言)。 - 新增 scripts/verify-my-skills.mjs(把「不换行 / 危险操作必须二次确认 / 锁定行无按钮」钉成机械断言), 并接入根 package.json 的 npm run verify。 验证:node scripts/verify-my-skills.mjs ✓(本会话复核已跑通)
Phase 3 核心路径 PoC(不写业务代码)
🧭 ← 返回 README · 结论落地为:K8s 部署教程
对应内部设计稿 §7 的四项风险验证。不引入任何业务代码——全部用一次性 镜像(busybox / node / socat / CloudNativePG)验证基础设施假设。四项全部通过, 才允许进入 Phase 0 镜像化 / Phase 2/3 落地,避免 Phase 3 返工。
前置条件
- 一个 k3s 集群(
k3s --cluster-init3 server + N worker 皆可,单机 k3s 也能跑 PoC)。 - 已装且健康:
- Longhorn(item 1、4 依赖;item 1 是硬前提,必须
longhorn.ioStorageClass 可用) - Cilium(item 3 依赖;NetworkPolicy 必须被强制)
- CloudNativePG operator(item 4 依赖)
- cert-manager / MetalLB / kube-vip 与本 PoC 无关,暂不需要
- Longhorn(item 1、4 依赖;item 1 是硬前提,必须
kubectl指向该集群(kubectl get nodes有输出)。- 本地有
bash+curl(item 2/3 用);item 2 的 WS 客户端用node(本机或容器内均可)。
kubectl get nodes
kubectl get storageclass longhorn # item 1/4 前提
kubectl get pods -n kube-system -o wide | grep -E 'cilium|longhorn|csi'
kubectl get crd clusters.postgresql.cnpg.io # item 4 前提
Item 1 — Longhorn RWX + subPath + runAsUser/fsGroup(§4.9 / §6.0 的 PoC)
验证的未知点:fsGroup 是否会 chown subPath 叶子?非 root 目标 uid 能否在 PVC
根建目录、0700 属主是否正确、子目录挂载后能否读写。
⚠️ 这是
docs/k8s.md§4.9 标明的「PoC 第一项必须验证」。若失败,按 §4.9 的 回退:bootstrap 阶段用特权 Job 完成chmod 1777(在启 PSA restricted 之前), 时序固定为「初始化 PVC → 启 PSA → 允许用户 Pod」。
cd 01-longhorn-subpath
./run.sh
通过标准(脚本自动断言):
- bootstrap Job(特权)
chmod 1777 /mnt成功。 - init Job(非 root,
runAsUser/fsGroup = 100001)能mkdir -p /mnt/u1/{ws,home}且chmod 0700 /mnt/u1成功——即非 root uid 能写 PVC 根(chmod 1777生效)。 - 测试 Pod(
runAsUser=100001,subPath: u1)能写/读文件,且stat显示目录属主 uid=100001、权限 0700。 - (可选)另一个 uid(100002)无法读该目录——
subPath叶子 + DAC 的越权边界。
Item 2 — socat 桥 WebSocket 透明转发(§3.2 / §4.3)
验证的未知点:DSH 只监听 loopback,socat TCP-LISTEN:8081 → 127.0.0.1:8080 的纯
TCP 转发对 WebSocket Upgrade 是否透明。
cd 02-socat-ws
./run.sh
通过标准:
- 通过 sidecar 的 8081 能拿到 fake-dsh 的 HTTP 200(TCP 基础通)。
- WebSocket Upgrade 握手经 8081 返回
101 Switching Protocols,且Sec-WebSocket-Accept校验正确(证明 Upgrade 请求与响应都原样穿透 socat)。 - 一条文本帧 echo 往返成功(双向透明)。
若 2/3 不透明,回退:换
nginx/netcatsidecar(同端口转发),见 §9。
Item 3 — NetworkPolicy 默认拒绝 + 控制面→DSH 单向(§3.5 / §4.4)
验证的未知点:Cilium 是否强制 NetworkPolicy;default-deny 下「仅控制面可达 DSH 8081」的单向放行是否正确,跨来源访问被拒。
cd 03-networkpolicy
./run.sh
通过标准:
- 同 namespace 内打了
app=dsh-orchestrator的「控制面」Pod 能连通 DSH 8081。 - 同 namespace 内其它 Pod(
app=attacker)访问 DSH 8081 被拒(超时/拒绝)。 - 这也覆盖 §3.5 的「每次 NetworkPolicy 变更后跑自动化验证」——本脚本即该验证的雏形。
若 flannel(k3s 默认)下 2 仍通,说明 CNI 未强制策略,必须切 Cilium(§11.2)。
Item 4 — CloudNativePG on Longhorn 的 pgbench 基线(§4.5)
验证的未知点:Postgres 对延迟/IOPS 敏感,Longhorn RWO 复制是否拖慢同步复制, 延迟是否可接受。
cd 04-cnpg-pgbench
./run.sh
通过标准(人工判读,无固定阈值,取决于硬件):
- CloudNativePG 3 实例主备建立、
Ready。 pgbench -S(select-only)tps 与延迟与本机 NVMe 基线对比,落在可接受区间。 §4.5 结论:不够则回退「节点本地 NVMe + PG 主备」。
通过后
四项全过 → 记录结果(tps/latency 数字、Longhorn 权限行为结论)到本 README 尾部, 再进入 Phase 0(镜像化)。任一项失败 → 按对应 §9 回退方案调整后重跑。