Files
dsh_ai1net_server/交付物/AI1NET-三类节点结构调整可行性-20260926.md
admin c1b5e4d966 chore(工作区): 全量入库 + 补齐 .gitignore(以工作区为准)
- 变更规模:新增 514 / 修改 62 / 重命名 155 / 删除 4(归档重组与文档轮次)
- .gitignore 修:`归档/**/db-cwd归一-备份-*/` —— 原规则写绝对层级(归档/db-cwd归一-…),
  目录搬进 归档/配置与备份/ 后**静默失效**,43 MB 的 DB 备份又变成未跟踪
- .gitignore 补:嵌套 git 内部数据(归档/内嵌git-20261008/、归档/skills-git-旧线-20261007/dotgit-原样移出/)
- .gitignore 补:运行态与部署副本(.workbuddy/collab/、.workbuddy/tools/、.workbuddy/.load-pending、.workbuddy/tmp-*)
- .gitignore 补:备份件(*.bak-*)
- 未跟踪文件从 2190 降到 890(其余为 归档/ 归档件与 .workbuddy/memory/ 知识文件,按口径入库)
2026-10-10 23:13:22 +08:00

24 KiB
Raw Permalink Blame History

AI1NET 网络结构调整(三类节点)可行性评估

  • 日期:2026-09-26
  • 评估对象:用户提出的「覆盖网络连接所有节点和设备」三类节点划分(原话见 §9)
  • 评估口径:🔴 以定稿 dsh-server-docs/02-架构设计/覆盖网络-顶层架构全貌.md(2026-09-21 · 唯一权威)为准;本文与定稿冲突 ⇒ 以定稿为准
  • 证据等级:读码 + 既有真机实测;凡标 ⚠️待查 的项未经真机取证(⛔ 不得当既成事实)
  • 关联件:交付物/全功能承载判定-底层插件能否承-20260926.md(§3.10 K8S · §3.11 网络与 K8S API · §5 P6)

§0 一句话判定

三分法本身站得住,但有一个词站错了位置 ——「客户端版服务节点」不是"服务节点",是"主权承载节点"。把这个定语补上,你的三分就与定稿完全对齐,不需要改架构。

三条单句:

# 你的提法 判定
① 服务器版 服务节点(47 管理 + 106 K8S 承载) ✅ 成立,而且今天就是这么跑的;⭐ 它还给出了比我的 P6 建议更好的落法(见 §2.1)
② 客户端版 服务节点(桌面机装 K8S 提供多租户) ⚠️ 拆两问:给自己用 ⇒ ✅ 成立|给别人用 ⇒ ⛔ 不成立(四条件缺二 + 一条架构级信任门,见 §2.2)
③ 客户端版 实例节点(连到服务节点用) ✅ 成立,且这正是定稿 §5.3 里**唯一"机制齐备"**的那条路径(B,见 §2.3)

🔴 但比"可行不可行"更硬的是顺序 —— F1.5(G1 签名清单序号 + G6 撤根)=一切前置,而现状 G1 未修、G6 无任何机制。⇒ 「连接所有节点和设备」这件事,在**"撤不回去"这个问题解决之前,不能上规模**(§4)。


§1 先对齐词:你的三分 vs 定稿的三层权威

这是本评估最重要的一节。你的分类与定稿的分类不在同一个维度上,所以直接问"可行不可行"会答歪。

你分的 定稿分的
分的是什么 功能(这台机器给别人跑实例吗) 权威(谁说了算)
分了几类 服务节点 / 实例节点 / 设备 根 → 区 Manager → 区内 Worker·节点

定稿的三层权威(原文 §三):

权威 管什么 在你这套里对应谁
根(离线、可多把) 区域名录 · 用户全局唯一名 · 联邦吊销 🔴 你没提 —— 它不在任何一台"节点"上,在用户手里
区 Manager 本区归属 · 租约 · 资格 部分对应你的「服务节点」
区内 Worker / 节点 执行面 · 本机运维库 部分对应你的「服务节点」+ 全部「实例节点」

🔴 问题就在这:你说的「服务节点」在定稿里其实是两个不同的东西——

  • 区 Manager(权威层:谁能入网、实例算谁的、租约给谁)
  • Worker / 承载节点(执行层:真把实例跑起来)

定稿把这两者分开(因为它们必须分得开:管账的机器挂了不该带着实例一起挂)。你把它们合成一个词「服务节点」,于是产生一个无解的歧义:

⚠️ 「客户端版服务节点」是 Manager 吗?

  • 若是 ⇒ 那就是定稿 §4.2「Manager 可升格」,牵动 F8 根集合治理 与 G6 撤根
  • 若不是 ⇒ 它只是"自己给自己跑实例",那它不该叫服务节点

⇒ 这个歧义是本方案唯一真正需要澄清的地方(§2.2 给解法)。


§2 逐条评估

§2.1 ① 服务器版 服务节点 —— ✅ 成立,且已是现状

你说的:47 服务器上的官方 dsh 实例 + 底层插件(admin 使用),可配置服务集群(106:K8S 集群,开多个实例给多租户用户)。

逐项对照实测:

你的说法 对照 判定
47 = 管理入口 47 是 Manager(dshs;PG13 15432)+ Worker w-47(19100) ✅ 已是
「官方 dsh 实例 + 底层插件 · admin 使用」 管理员实例=普通租户:dsh_instances 按 user_id 建,grep "role === 'admin'" src/supervisor/ src/web/routes/dsh.ts = 零命中;requireAdmin 只是一句 DB 角色判断(middleware/authn.ts:31-38) ✅ 成立,且今天就是这么跑的
106 = 承载(开多实例给多租户) 106 是 Worker w-106(19000) ✅ 同层,但见下方 ⚠️
「可配置服务集群」 定稿 §三第 3 行「区内 Worker / 节点 = 执行面」 ✅ 是执行面的替换,⛔ 不动权威结构

⚠️ 一处必须点名的现状冲突:106 上现在已经有 w-106 实例在 19000 上跑 ⇒ 把它变成 K8S 集群是形态切换,⛔ 不是叠加。「106 上现存的实例怎么办」(迁走 / 保留并行 / 退役)必须先定,否则是带数据的一次性动作。

⚠️ 待查:106 的机器规格(核数 / 内存 / 磁盘)—— 本评估未取证。参照 orchestrator.ts:1233 实测宿主 2 核 / 1870 MiB、单实例基座 106~145 MiB(:1229):若 106 与 47 同规格,装不下 K8S 再装多租户实例(命中 R11);若 106 是更大规格,则此条自动解除。这一项要真机取证后才能定 A 案可行性。

⭐ 本条最大的价值(比你自己可能意识到的更大): 它给 P6(承载走不走 K8S) 提出了一个比我原来建议更好的落法。

  • 我原来的建议:先 B 后 A(先维持自研单机,K8S 登记为演进方向)
  • 你的方案实际是:B 与 A 并存 —— 47 维持自研 uid + bwrap + cgroup + systemd(生产不动),106 试点 K8S(新承载)

⇒ 这是"隔离试点",风险最低:47 生产路径零改动,106 本来就是 Worker、可以当试验田;跑通了再谈要不要把 47 换过去。 ⇒ 我据此修正 P6 的建议(§7)。这是本评估里唯一一处你的方案优于我原建议的地方。


§2.2 ② 客户端版 服务节点 —— ⚠️ 必须拆成两问,答案相反

你说的:官方 dsh 客户端版,装底层插件(admin 使用),可在本机安装 K8S 集群,提供多租户服务。

这句话里藏着两件不同的事,答案一个是 ✅ 一个是 ⛔。

问 1:桌面机能不能跑 K8S 开多实例?

分平台看(读码实证,非推测):

平台 能不能 证据
Linux 桌面 ✅ 能(k3s / kind) —
Windows / macOS ⚠️ 要连过三关:虚拟化 → Linux 内核 → systemd 见下

🔴 三关的实证:

  1. 实例的启动链是 Linux 专有的 src/cli.ts:106 依赖检查:['bwrap', 'setpriv', 'systemd-run', 'nft', 'dsh'] orchestrator.ts:1249:真起实例走 spawn('systemd-run', sdArgs, …) ⇒ 需要 Linux 内核 + systemd。Windows 上只能靠 WSL2,而 WSL2 默认不开 systemd(须显式 systemd=true);Docker Desktop 的 VM 也没有。

  2. 强隔离能力直接 return src/cli.ts:39 —— --isolation-mode <m> Isolation tier: "soft" or "account" (**Linux, needs root**) src/supervisor/firewall.ts:42 —— process.platform === 'linux' && getuid() === 0 src/worker/agent.ts:147 —— if (process.platform !== 'linux') return src/supervisor/plugin-assembly.ts:796 —— 注释原文:「runPnpmAs 走 setpriv(Linux 专有),Windows 开发机上必然 ENOENT」 ⇒ 🔴 不是"性能差一点",是这些代码路径在非 Linux 上直接不执行。平台自己就知道这件事(注释写明了)。

  3. 而"官方 dsh 客户端版"这个描述,今天对不上 package.json 的 description 原文:「面向公网的多租户 DSH 托管平台:登录审核、每用户隔离的 DSH 环境(主 + 按需守护)、桌面与域名访问」 ⇒ 这里的「桌面」指的是桌面浏览器的访问方式,⛔ 不是 desktop app。 ⇒ 本仓库(生产口径 dshs)没有 apps/ 目录,没有桌面壳。「桌面壳」在 P1 的 A 案里是待实现项(缺点栏原文:「桌面/服务器两条壳要分别实现」)。

⇒ 问 1 的结论:「用 dsh 客户端 + 底层插件在本机装 K8S」这句话,今天描述不成立 —— 客户端壳不存在,而承载链要 Linux + systemd。真要落地,实际形态是「dsh 客户端(Windows 侧)+ 一个 WSL2/VM(Linux 侧)+ 里面一个 K8S」,⛔ 不是"客户端版 + 插件"。

问 2:就算跑起来了,能不能"提供多租户服务"(给别人)?

四个必要条件(缺一不可):

条件 为什么必须 服务器版 客户端版(桌面)
常开 别人的实例随时要用 ✅ ❌ 合盖 = 断服
可达 别人得连得上 ✅ 固定 IP ⚠️ NAT 后面 ⇒ 每个用户各自解决一次
有特权 要能起隔离进程 ✅ root ⚠️ 需管理员 + 虚拟化 + systemd
不占用主用机 要腾得出资源 ✅ ❌ 跑 K8S + 多租户实例,主机自己就没法用了

⚠️ 「可达」这条不是新问题,是 D8 那个门槛的翻版:09-26 已实测结论 ——「中继方需"别人能连到它"=用户侧 NAT 门槛(≠ 云安全组;同局域网零门槛)」。 ⇒ 服务器版只需解决一次;客户端版是 N 个用户 = N 个 NAT 问题。

🔴 但最要紧的一条不是能力,是信任

现状安全模型的根信任 = 平台容器。 实证:orchestrator.ts:823-827 原文 —— 平台主动关掉 DSH 内置沙箱(改 danger-full-access),理由是「不在实例内再叠加沙箱,隔离交由平台容器(bwrap + uid + cgroup)负责」。

⇒ 桌面机当承载方 = 把这条链的根信任从"平台"搬到"私人设备"。而这个设备:

私人设备的性质 后果
可被物理接触 内存可 dump、磁盘可直读(对方是 owner,chown 一句话)
管理员就是用户本人 他能读所有租户的 home 与凭据
不受平台运维管辖 不能打补丁、不能审计、不能强制下线

⇒ ⛔ 这不是"能不能做到",是"要不要把信任根搬家"。这是架构级的一道门 —— 与 §3.10 那条「设备侧不进集群」是同一件事的两面。

✅ 那 ② 什么时候成立?—— 换一个定语

区别只在"服务谁":

读法 服务谁 判定
主权服务节点 只服务自己的租户(我一个人的多个工作区 / 多个身份) ✅ 完全成立
公共服务节点 服务别人的租户 ⛔ 要过上面那道信任门

⭐ 而「主权服务节点」恰恰是客户端版最大的价值所在 —— 它就是单机多租户:一个用户在自己的机器上,用自己的 admin 身份,开自己的几个隔离实例。

⇒ 这个形态:

  • ✅ 与定稿不冲突(定稿 §5.3 路径 C:自建独立区、不需要任何根、自成一网)
  • ✅ 与「资源口径 = 机器可换」不冲突
  • ⚠️ 但今天无通路(见 §5)

🔴 一句话:把「服务节点」拆成「主权服务节点(只服务自己的租户)」和「公共承载节点(服务别人的租户)」—— 前者客户端版可以,后者不行。② 的原文写的是后者,所以不成立;改成前者,立刻成立。


§2.3 ③ 客户端版 实例节点 —— ✅ 成立,且是唯一"机制齐备"的那条

你说的:安装 dsh 客户端版 + 底层插件,可选择连接到服务节点,作为单独实例使用。

对照定稿 §5.1「设备入网六步」:

步 做什么 现状 你说的"可选择连接到服务节点"
① 拿到入口(邀请码 / 扫码) ✅ 已有 ✅
② 知道有哪些区可加入 🔴 缺(无区域名录 G2) ⚠️
③ 选加入哪个区(需该区审批) ⚠️ 半成 ✅ 「可选择」
④ 该区签发凭据 ✅ 已有 ✅
⑤ 节点本地校验 ✅ 已有 ✅
⑥ 建隧道(打洞 / relay) ✅ 已有 ✅

⇒ 这就是定稿 §5.3 路径 B「设备加入已有区」,原文标注 ✅「机制齐备」 —— 也是四条入口路径里今天唯一通的一条。

⚠️ 一处用词建议:「实例节点」这个词与定稿不齐,且在中文里有歧义——

  • 读成「跑着实例的节点」⇒ 那是承载方(=服务节点)
  • 读成「以实例身份入网的设备」⇒ 那是使用端

从上下文看你是后者。建议改称「使用端 / 设备」,与定稿 §2.1「节点(每机一钥)」对齐 —— 否则下一棒读到"实例节点"会当成承载方。


§3 你的方案缺的那一维:承载能力

你的三分是按"给别人跑实例吗"分的,这是功能维。但能不能给别人跑取决于四个独立条件,而这四个条件不随软件配置改变:

判据 含义 服务器 桌面
常开 物理事实,不是配置项 ✅ ❌
可达 固定入口 / 公网 / 中继 ✅ ⚠️
有特权 root / K8S / bwrap / cgroup ✅ ⚠️ Linux 专有
不占用主用机 腾得出资源 ✅ ❌
➕ 受平台管辖 能打补丁 / 能审计 / 能强制下线 ✅ ❌

⇒ 🔴 补上这五条,"服务节点"自然裂成两个:

                 有没有特权?          → 没有 ⇒ 只能当「使用端 / 设备」
                    │ 有
                    ▼
            常开 + 可达 + 不占主用机 + 受管辖?
                 │ 全有                     │ 缺任一条
                 ▼                          ▼
        【公共承载节点】              【主权承载节点】
        服务别人的租户                  只服务自己的租户
        ⇒ 只有服务器能当              ⇒ 服务器 ✅ / 桌面机 ✅

⭐ 这张图就是本评估的核心产出 —— 你的三分只要插入这一层,就完整了:

你的原分类 补维度后
① 服务器版服务节点 = 区 Manager + 公共承载节点 ✅
② 客户端版服务节点 = 主权承载节点(⛔ 不是公共承载)
③ 客户端版实例节点 = 使用端 / 设备 ✅

§4 🔴 比"可行性"更硬的:顺序

你问的是"结构调整是否可行"。结构本身可行 —— 但它的规模放大了一个未修缺口的爆炸半径。

你要的效果:「覆盖网络连接所有节点和设备」。

它要求什么:签发身份 + 撤回身份。

现状(定稿 §六 · §七):

缺口 内容 现状
G1 🔴 SignerSet / NodeGrant 只有 issuedAt、无序号,而 issuedAt 不参与任何判定 ⇒ 一份旧名单(已撤销的签名者还在里面)重放给节点,验签会通过 未修
G6 🔴 撤根无任何机制 —— 吊销清单只能撤节点,撤签名者靠"根签新名单",撤根本身没有手段 无机制
G1 + G6 叠加 撤根的唯一补救是"换新名单",而名单无序号 ⇒ 这条路本身也不可靠 定稿原文:「G1 与 G6 必须一起解决」

定稿 §七 原文:

🔴 一句话记法:F1.5 是一切的前置 —— 没有防重放序号,后面每一项下发的签名清单都是可重放的。

⇒ 结论:

  1. ⛔ 在 F1.5 之前,"把所有节点和设备都连进来"做不了 —— 因为撤不回去。
  2. ⚠️ 且规模越大越撤不回去 —— 节点越多,一份可重放的旧名单能影响的机器越多。这正是"先小规模、再扩张"的理由,不是"先扩张、再补机制"。
  3. ⚠️ 定稿 §九 第 1 条已如实标注:G1 重放未实测("issuedAt 不参与判定"是读码推断)⇒ 落地前须构造真实重放实验复现。

⇒ 🔴 这不是"能不能",是"什么时候",而且顺序不可颠倒。


§5 今天哪些有通路、哪些没有(对照定稿 §5.3 四条入口路径)

路径 说明 现状(定稿原文) 你的方案对应
A 新服务器首启 显示首管理员设置页(一次性)⇒ 建本区或加入他区 ⚠️ 今天只有 CLI,无 Web 通路 ① 服务器版服务节点
B 设备加入已有区 邀请码 ⇒ 该区签发 ⇒ 本地校验 ✅ 机制齐备 ③ 客户端版实例节点
C 自建独立区(不联联邦) 不需要任何根,自成一网 ⚠️ 今天无通路 ② 的"主权服务节点"读法
D 自建区加入联邦 需根背书区身份 🔴 今天无通路 ② 的"公共服务节点"读法

🔴 硬事实:

  • ① ✅ 已是现状(CLI 侧)
  • ③ ✅ 有通路(唯一通的一条)
  • ② ⛔ 两种读法今天都没有通路 —— 单机(C)⚠️ 无通路,联邦(D)🔴 无通路
  • ⚠️ C 与 D 都依赖 G2 区域名录,而 G2 依赖 F1.5

⇒ 你要做的"结构调整",其中两块(② 的两种读法)今天是空的。这不是你的方案错,是地基还没浇到那一层。

⚠️ 另附定稿硬约束(会被误做成需求):

首管理员设置页上的「有哪些 manager 可选」⛔ 不可做成公开列表 —— 那是拓扑信息,公开即扩大暴露面。改法:凭邀请码才列出该区信息。


§6 我建议的调整版

不改你的三个角色,只把维度补齐 + 改两个词:

# 你的原文 建议改成 为什么
① 服务器版 服务节点 服务器版 管理节点 + 公共承载节点 把"权威"与"执行"分开(定稿本来就是分开的)
② 客户端版 服务节点 客户端版 主权承载节点(只服务自己的租户) ⛔ 「公共服务」要过信任门;「主权服务」今天就能立项
③ 客户端版 实例节点 客户端版 使用端 / 设备 与定稿 §2.1「节点」对齐,⛔ 避免被读成承载方

补一句总纲:

覆盖网络连接"所有节点和设备" —— 目标是 ☑ 对的;但"公共承载"这一档,"所有设备"进不来,只有服务器能进。 ⇒ 设备能以使用端身份入网(✅ 路径 B),能以主权承载身份自成一区(⚠️ 路径 C,待建),⛔ 不能以公共承载身份服务别人的租户。

推进顺序(若采纳):

序 做什么 前置 说明
1 ① 的 106 试点(106 → K8S 承载池) 定 106 现存实例处置 + 取证 106 规格 ⛔ 与 F1.5 无关,可以并行
2 ③ 定型(使用端入网,路径 B) — ✅ 机制已齐备
3 ② 的"主权"读法(路径 C 通路) F1.5 + G2 ⚠️ 无通路,须先建
4 ② 的"公共"读法(路径 D 通路) 上面的 + G6 撤根 + F8 根治理 + 信任根决策 🔴 三重前置

§7 与既有拍板的关系

项 原状态 本评估的影响
P6(承载走不走 K8S) 我倾向先 B 后 A 🔴 修正:你的方案给了第三条路 —— B 与 A 并存(47 维持自研生产不动 + 106 试点 K8S)⇒ 这是风险最低的落法,我改为推荐它。「先 B 后 A」不再是最优。
D8(端口) 09-26 拍板「先不开端口」 ✅ 不变 —— 本方案不需要开任何端口(② 的主权承载走本机回环;① 走 443 中继)
P5(平台可自建) 倾向分成两步、排在 F1.5 之后 ⚠️ ② 的"主权"读法其实就是 P5 的客户端形态 ⇒ 两条线是同一件事,应合并考虑
§3.10 结论(设备侧不进集群) 已定 ✅ 不变,且本评估用②的信任分析加强了它
G1 / G6 / F1.5 一切前置 ⚠️ 本评估进一步强化:方案想连"所有节点和设备" ⇒ 规模直接放大 G1 的爆炸半径

§8 待拍板

⛔ 顺序不可颠倒;每项一句话说清 + 为什么需要你定 + 候选优缺点。本轮只问 1 条。

🔴 S1 —— 106 上现在那个实例怎么办?(带数据的一次性动作,不可逆)

要你定的是:106 服务器上现有的那个租户实例(跑在 19000 端口),在你把它变成 K8S 承载池之前,是先迁走、原地保留并行,还是退役。

为什么需要你定:这是一次带用户数据的一次性动作,做错了数据就丢了/或者用户会突然断服。而且它决定了 106 这条路是"替换"还是"叠加"——两种做法的后续工作量差一个量级。

A 案 · 先迁走(把那个实例搬到 47 或别的机器,再在 106 上装 K8S) (优点:106 可以干净地当承载池,架构清晰,⛔ 不留两套共存;缺点:迁移本身是带数据的动作,有停机窗口,且跨节点迁移今天未设计——memory 已登记"实例跨节点迁移 ⛔ 未设计"。)

B 案 · 原地保留并行(106 上既有实例照跑,K8S 用另一组端口/目录起) (优点:⛔ 零迁移风险,可以立刻开工试点;缺点:106 上两套承载并存,资源要重新算(2 核机可能不够),运维要同时管两套。)

C 案 · 退役(把那个实例停掉,用户另行安排) (优点:最干净;缺点:要用户配合,且如果那是真实用户,等于给人断服。)

我的倾向:B(原地保留并行) —— 106 本来就是 Worker、试点阶段不需要它"干净";先拿到 K8S 跑通与否的答案,再谈要不要清场。⚠️ 但前提是 106 的规格装得下两套 —— 这一项我还没取证(§2.1 待查项),要么先让我取证、要么你直接告诉我 106 的机器规格。


§9 出处

用户原话(2026-09-26):

AI1NET 网络结构调整为是否可行:覆盖网络连接所有节点和设备 1、服务器版 服务节点:(47服务器dsh官方实例+底层插件 admin 使用)可配置服务集群(106服务器:K8S集群 开启多个实例分别给多租户用户使用) 2、客户端版 服务节点:(官方dsh客户端版本,安装底层插件 admin使用,可在本机安装K8S集群 提供多租户服务) 3、客户端版 实例节点:(安装dsh客户段版本,安装底层插件 可选择连接到 服务节点作为单独实例使用)

本评估引用的证据:

证据 位置
定稿(唯一权威) dsh-server-docs/02-架构设计/覆盖网络-顶层架构全貌.md(§三 三层权威 · §4.2 升格 · §5.1 入网六步 · §5.3 四条入口路径 · §六 G1–G7 · §七 推进顺序)
实例启动链(systemd-run / bwrap / setpriv) src/supervisor/orchestrator.ts:1249、:1221、:1219
平台依赖检查(Linux 专有) src/cli.ts:106、:39
隔离能力平台分支 src/supervisor/firewall.ts:42、src/worker/agent.ts:147、src/supervisor/plugin-assembly.ts:796
平台主动关掉内置沙箱(信任根=平台容器) src/supervisor/orchestrator.ts:823-827
管理员实例=普通租户 src/db/repo.ts:617、src/web/middleware/authn.ts:31-38
「桌面」=桌面浏览器访问(⛔ 非 desktop app) package.json description
宿主规格与单实例内存 orchestrator.ts:1233、:1229
NAT 门槛(D8 实测) 交付物/端口决策与设备中继可行性-20260926.md
K8S 判定与 P6 交付物/全功能承载判定-底层插件能否承-20260926.md §3.10/§3.11/§5