news 2026/11/3 18:29:54

Sandstorm Blackrock 集群架构全解:将 2 到 2^16 台机器编排为单一 Sandstorm 实例的托管平台路线图

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Sandstorm Blackrock 集群架构全解:将 2 到 2^16 台机器编排为单一 Sandstorm 实例的托管平台路线图
  • 后端
  • 容器运行时
  • 安全
  • 云原生

【免费下载链接】sandstorm

Sandstorm is a self-hostable web productivity suite. It's implemented as a security-hardened web app package manager. | Actively sponsored by our friends at TestMu AI

项目地址:https://gitcode.com/gh_mirrors/sa/sandstorm
点击查看免费下载

Blackrock 是 Sandstorm 项目为托管服务与企业级部署设计的集群管理技术:它让一整个数据中心内 2 到约 2^16 台同地协作的机器(或虚拟机实例)对外呈现为一个Sandstorm 实例,用户界面与单机版几乎无差别。本文以 roadmap/blackrock/README.md 为骨架,结合仓库内src/sandstorm/与shell/下的真实实现,系统讲解 Blackrock 的设计目标、七大机器角色、基于 Cap'n Proto 的自定义网络协议与 SturdyRef 持久化能力模型,并逐条标注哪些设计已实现、哪些仍停留在路线图阶段,帮助读者完整理解 Sandstorm 从单机走向横向扩展集群的演进思路。

Blackrock 在 Sandstorm 生态中的定位

在 roadmap/README.md 中,Blackrock 被明确定义为 "the cluster management technology underlying managed hosting and our eventual enterprise product"(托管服务与企业级产品底层的集群管理技术)。也就是说,它是 Sandstorm 平台三大技术方向之一,与平台核心功能(Platform)、自托管体验(Self-hosting)并列。

从运维视角看,Sandstorm 默认架构是单机部署:docs/administering/hosting-provider.md 明确指出 "Sandstorm runs on a single server, due to its architecture",单机模式下提升用户数的主要手段是纵向扩容内存("RAM is the primary bottleneck")。而当托管商需要服务成千上万用户时,就需要横向扩展方案——Sandstorm.io 团队运营的 oasis.sandstorm.io 正是使用代号 Blackrock 的这套 scale-out 软件栈。该文档同时提醒:Blackrock 远不如标准 Sandstorm 开箱即用(far less "turn-key"),托管商若采用它,通常需要与 Sandstorm 开发者紧密协作并自行编写额外代码,更好的路径是"先跑单机,需要时再迁移到 Blackrock"。

Blackrock 的设计目标(Goals)完整列举如下:

  • 将 2 到约 2^16 台同地协作的机器(或 VM 实例)视为一个Sandstorm 实例,用户界面与单机 Sandstorm 基本一致;
  • 强制实施按用户(或许还按应用)的存储空间与内存配额;
  • 支持机器动态加入或移出集群,机器角色由集群自动分配并随需更新;
  • 任何一台机器宕机都不造成用户中断或数据丢失;
  • 在机器之间迁移 grains(沙箱化应用实例)以平衡负载、优化资源共享(例如共享应用二进制文件);
  • 通过避免可疑应用与高价值目标同机部署、监控主机可疑行为、定期清空并重启单台机器,缓解沙箱逃逸风险;
  • 在可用时利用廉价的对象存储。

同时文档明确划定了非目标:不支持地理位置分散的机器组成单实例——Blackrock 针对的是同一数据中心、同一 LAN 内的机器;跨集群移动应用应使用 Sandstorm 常规的联邦(federation)能力。

机器角色体系:同一镜像、多角色分配

Blackrock 集群中的所有机器都启动同一份只读操作系统镜像,镜像内包含全部 Blackrock 平台软件;机器启动后由集群主控(master)为其分配一个或多个角色。这种"统一镜像 + 动态角色"的设计直接支撑了"机器动态加入/移出、角色自动调整"的目标——没有角色固化在镜像里,一切以运行时分配为准。

整个角色体系分为八类:Master(主控)、Storage(存储)、Workers(工作机)、Coordinators(协调器,TODO)、Shells(又名 Front-ends,前端)、Mongo(数据库)、Gateways(网关)、Log sink(日志汇聚,TODO)。

Master:集群的角色分配与拓扑中枢

每个集群有且仅有一台 master。其职责包括:

  • 为所有其他机器分配角色;
  • 监控全集群资源使用情况,动态决策资源分配去向;
  • 当机器规格异构时,依据硬件特性分配合适角色——例如内存巨大的机器应做 worker,磁盘巨大的机器应做 storage;
  • 负责向所有其他机器通报"应该与哪些对端通信"的拓扑信息——例如新增一台存储节点后,master 会更新所有可能用到存储的机器,使它们把新节点加入各自的负载均衡池。

关键可靠性设计是:master 不在任何单次请求的服务关键路径上。若 master 宕机,集群其余部分可以按照最近一次分配的角色继续运行,等待 master 恢复。这与"单台机器死亡不造成用户中断"的目标直接呼应。

Storage:对象存储之上的能力化加密代理

存储节点对外提供所有持久化存储的接口。文档特别强调术语区分:存储节点(storage node)通常并不直接操作磁盘,而是充当某个传统对象存储系统(如 S3)的代理;真正的物理存储应称为"disks"(磁盘)。

引入这层代理而非让其他机器直连磁盘,目的有三:

  1. 实现基于 Cap'n Proto 持久化层的能力化(capability-based)对象图存储接口——存储的不是扁平文件,而是相互引用、可沿对象图遍历的能力对象;
  2. 实现逐对象加密:每个对象拥有独立加密密钥,这些密钥本身作为访问对象所需的 SturdyRef 的一部分保存。由于 SturdyRef 通常又存储在其它(已加密的)对象中,因此不沿对象图从用户持有的某个基础能力出发,就无法访问任何对象。理论上,这些基础能力甚至可以用用户的 GPG 密钥加密保存,实现"完美加密存储";
  3. 保护访问磁盘所需的凭据(如 S3 凭据),使磁盘端无需被信任即可保证隐私。

文档给出的候选后端(disk 层)包括:Amazon S3、Google Cloud Storage、Tahoe-LAFS,以及一种利用本地集群所有磁盘的分布式文件系统。

文档还保留了项目自注的 TODO:截至文档记录时,当前存储实现仍是单机写本地磁盘,依赖底层磁盘实现提供完整性、可靠性与备份(Oasis 托管在 Google Compute Engine,利用其持久磁盘与快照能力);单机存储层之所以能扛住大量负载,是因为其工作基本只是读写块。但存储层"应该被重写以支持更好的可扩展性,并在可用时利用廉价对象存储"。

Workers:运行 grain 的可疑机器与 nbd 块设备

worker 机器按照协调器(coordinator,见下文)的指令运行 grains。由于存在沙箱逃逸的可能,worker 机器应始终被怀疑对待:

  • 整个 Blackrock 集群使用 Cap'n Proto 能力安全模型,保证一台被攻破的 worker 无法访问除恰好运行在它上面的 grains 之外的任何东西;
  • worker 应定期轮换出勤、清空(wipe),防止恶意进程长期驻留;
  • worker 还应接受统计意义上的可疑活动监控,一旦发现立即移出轮换。

worker 的关键存储机制是:每个 grain 的存储通过nbd(Network Block Device)驱动挂载自一个用户态实现的块设备,该用户态守护进程把块同步回存储层。这套设计带来两个直接收益:

  • 数据量大的 grain(例如音乐库)可以从冷状态快速启动——按需(on-demand)拉取块即可;
  • 长期存储可以保持接近最新状态,从而让 worker 机器故障不至于造成过多数据丢失。

与此同时,内核在块设备之上实现了久经考验的缓存层,页面一旦缓存就能把运行时开销降到最低。文档还留下一个 TODO(feature):可以探索优化初始加载时间的启发式策略,例如跟踪启动时常加载的块并提前开始读取;并且 nbd 实现了 trim 命令,可以用来跟踪文件系统实际使用的块、避免存储无用数据。

Coordinators(TODO(feature)):尚未实现的调度层

截至文档记录(2017 年 2 月),协调器尚未实现——"Currently frontends simply round-robin to workers"(当前前端只是对 worker 做轮询)。文档中的协调器设计如下:

  • 协调器告诉 worker 做什么:要启动新 grain 或启动一个当前未运行的 grain,必须先联系协调器,由它挑选合适的 worker 委派任务;
  • 每个协调器维护一组 worker,这些集合可以重叠也可以不重叠——可以是两个协调器各监控全部 worker,也可以各监控一半;启动 grain 的请求可交给任意协调器,调用方应在它们之间做负载均衡;
  • 协调器监控其 worker 上的资源使用,并在需要时下达 grain 迁移指令;它应当考虑每个应用的典型资源占用,以及该应用的"可疑程度"——可疑应用应与安全关键型应用隔离,以缓解沙箱逃逸的影响。

文档评价该模块"有大量算法与启发式策略的开发空间",属于路线图中留白最多的领域。

Shells(又名 Front-ends):Meteor 前端

Shell 机器运行 Sandstorm shell UI——一个 Meteor 应用。代码中这些机器被称为 "frontends"(前端),文档认为这个叫法其实并不准确("an arguably incorrect name")。

在仓库中,shell/目录正是这套 Meteor 应用:其服务端入口位于 shell/server/main.ts,客户端入口在 shell/client/main.ts,而 Blackrock 多副本场景下的能力路由基础设施可见于 shell/imports/server/frontend-ref.js 与 shell/imports/server/core.js。后者实现了FrontendRefRegistry(前端能力引用注册表),并围绕frontendRef字段把前端提供的 Cap'n Proto 能力保存为可恢复的持久引用——例如 core.js 通过globalFrontendRefRegistry.restore(db, saveTemplate, token.frontendRef)恢复能力,这正是多 shell 副本场景下路由能力所依赖的机制。另外 shell/imports/server/accounts/saml/saml-server.js 中还有一条注释提醒:某些状态"可能需要在 Blackrock 下改用 Mongo collection 才能在多前端场景工作"。

Mongo:当前依赖与长期替换计划

由于 Sandstorm shell 当前依赖 Mongo 作为数据库,Blackrock 集群需要专门的 Mongo 机器运行该数据库,其中一台为主(master)、其余为从(slave)。文档列出两项 TODO:

  • TODO(feature):数据库也应同步回对象存储;
  • TODO(project):长期来看,应当用自有存储接口替换 Mongo。

这条依赖在仓库中同样可证:shell/imports/server/core.js 有一段注释专门处理 "Fix Mongo converting Buffers to Uint8Arrays",说明 shell 与 Mongo 的数据交互是实打实的当前实现细节。

Gateways:连接公网与集群内部的桥

网关(gateway)负责桥接公网(或 Sandstorm 集群之外的更广企业网络),工作拆分为几块:

  1. 接收入站 HTTP 请求、终结 SSL、转发给 shell 或直接转发给 grains——这是已实现的核心职责;
  2. TODO(feature):实现一套 Cap'n Proto 接口,用于对外建立/接受 TCP 连接以及参与 UDP 流量;这类连接将被禁止连到集群内其他机器,能力可交给设备驱动,从而在不授予任何内网访问权限的情况下授予其外部网络访问;
  3. TODO(feature):把 Cap'n Proto 本身代理到外部世界——内部网络与公网使用不同参数化的 Cap'n Proto 协议,因此能力跨越边界时必须被主动代理;这同时也让系统有机会把外部能力与内部能力分开追踪,并向外部隐藏内部 SturdyRef 表示,作为额外一层安全。

仓库中网关的实现证据非常充分:src/sandstorm/gateway.c++ 中的GatewayService是直接处理 HTTP 等流量的 C++ 代码,而路由决策通过 src/sandstorm/backend.capnp 定义的GatewayRouter接口回到 Sandstorm 业务逻辑(Node.js 进程):网关先连接 backend 获得作为引导能力的GatewayRouter,再通过openUiSession(根据 sandstorm-sid cookie 换取 WebSession)、openApiSession(根据 Authorization 头中的 token 换取 ApiSession)等方法完成会话路由。backend.capnp中还明确注释了 Blackrock 场景:"in Blackrock, where multiple instances of the shell might be running, all GatewayRouters are equivalent, regardless of which shell replica"(在 Blackrock 中即使运行多个 shell 副本,所有 GatewayRouter 也都等价,无论连到哪个副本)——这是网关层与多副本 shell 解耦的直接依据。此外 src/sandstorm/config.c++ 中有一条配置日志 "Gateway is no longer experimental. Disabling EXPERIMENTAL_GATEWAY is ...",说明网关模块已经走出实验阶段。

Log sink(TODO(feature)):尚未实现的日志汇聚

所有其他机器应向日志汇聚节点(log sink)汇聚日志以供分析。截至文档记录该功能尚未实现——"Currently logs are collected and written to disk on the master machine"(当前日志由 master 机器收集并写到本地磁盘)。

网络与 Cap'n Proto 设计:面向 LAN 的自定义协议

Blackrock 集群使用一套为特定用例定制参数化的 Cap'n Proto RPC 协议。文档先给出实现现状注记:截至 2017 年 2 月,Cap'n Proto 仍运行在 TCP 之上,且由于 3-party handoff(三方交接)尚未实现,所有通信实际上都经 master 机器代理转发——这显然会在规模增长时成为瓶颈,但当时运行平稳。

传输层(Transport):UDP 优于 TCP 的理由

Blackrock 假设内部通信是近乎全连通的网状(fully-connected mesh)——几乎每台机器都会向其他每台机器偶发发消息。既然假定在同一 LAN 内,可以为此优化使用UDP 而非 TCP:

  • 丢包在 LAN 中很罕见;
  • UDP 可以避免"每次想跟一台尚未建立连接的机器通信都要做 TCP 握手";
  • 该模型对临时网络抖动更鲁棒:对 Cap'n Proto 软件来说,断连相当有破坏性,因为所有未持久化的能力都会丢失;而基于 UDP 可以轻松设计"等待网络恢复一段时间"的策略。

加密(Crypto):vat ID 与免握手的密钥交换

每个 vat(能力网络中的对等体/机器)由唯一的vat ID标识。vat ID 实际上就是该 vat 自己生成的ed25519 公钥——对应的私钥绝不应离开生成它的机器,且每当整机被清空时应一并丢弃。vat 可以通过对 challenge 签名来证明自己拥有某个 vat ID。

在多数情况下,Blackrock 实例的内部网络可能不需要分组加密,因为高端网络硬件通常可被信任为只把包投递给正确目的地。但如果需要加密,最直接的方式是curve25519 密钥交换:两个 vat 仅凭彼此知道对方的 vat ID(以及各自的私钥)就能协商出共享秘密,从而无需任何握手即可开始互发流量——这与 UDP 传输的设计天然契合。

持久能力(SturdyRefs):能力网络的持久化基石

在 Blackrock 网络内,SturdyRef(持久能力引用)分为有限几种类型:

  • Storage refs:直接指向存储中的对象,由存储节点恢复(restore);
  • Grain refs:指向特定 grain 内托管的 capability,由协调器恢复;
  • External refs:指向公网上的 capability,由网关恢复;
  • Ephemeral refs:指向某个特定 vat 上托管的 capability,只能由该 vat 恢复;这类 cap 天生短命,因为 vat 本身短命(频繁轮换),但它们能挺过重启与进程崩溃,比 live refs 更稳固。

每个 SturdyRef 都被"密封(sealed)"到请求创建它的 vat 所属的trust zone(信任区域),并且只能由同一 trust zone 恢复——这防止了跨信任边界泄漏的比特(bits)被利用。每个 vat 自身是一个 trust zone,此外还有四个特殊区域:storage、gateways、coordinators、shells。这四个分组内的 vat 都能保存 SturdyRef,使组内任意其他成员之后可以恢复它们。

SturdyRef 在仓库源码中有大量印证。在 src/sandstorm/supervisor.capnp 中注释了 "In the Sandstorm internal realm, the type of SturdyRefs themselves is simplyData",并多处描述save()与restore()语义;src/sandstorm/supervisor.c++ 中实现了把 token 设为 SturdyRef(如setSturdyRef(args.getToken()))、按SystemPersistent语义保存/恢复能力(含sealFor信任区域逻辑)等关键路径;src/sandstorm/sandstorm-http-bridge.c++ 中也能看到应用侧"尚未落盘、需要保存一个 SturdyRef"的注释。在 src/sandstorm/grain.capnp 中则详细对比了授权码(authorization code)与 SturdyRef 的区别,并解释为何避免让应用直接拿到"新铸造的 SturdyRef"——因为 SturdyRef 泄漏更危险,攻击者可能拿它发起伪造的 powerbox 请求。这些注释共同表明:SturdyRef 不是简单的对象 ID,而是密码学安全、按信任区域密封的持久能力凭证,这正是 Blackrock 对象图存储与 worker 不可信假设的安全基石。

从路线图到现状:实现状态总览

原文档以 TODO 标注的形式记录了各模块的实现进度。下表汇总各角色/功能的文档标注状态与仓库中的佐证位置,方便读者对照:

模块文档标注状态仓库佐证
Master已设计(每集群单台,不在请求关键路径)见本文第 3 节
Storage已实现为单机本地磁盘;重写为对象存储代理属 TODOsrc/sandstorm/backend.capnp(配额/存储接口)
Workers已实现(nbd 块设备 + 用户态同步守护进程)src/sandstorm/沙箱与桥接代码
Coordinators未实现(前端轮询 worker)无对应实现
Shells/Front-ends已实现(Meteor 应用)shell/client/main.ts、shell/imports/server/frontend-ref.js
Mongo已实现(一主多从),替换为自有存储属 TODO(project)shell/imports/server/core.js
GatewaysHTTP/SSL 终结已实现;TCP/UDP 接口与 Cap'n Proto 外部代理属 TODO(feature)src/sandstorm/gateway.c++、src/sandstorm/backend.capnp
Log sink未实现(日志暂写 master 磁盘)无对应实现
传输层未实现(当前 Cap'n Proto 走 TCP,经 master 代理)无 UDP 实现
加密设计完成(ed25519 vat ID + curve25519 协商)文档为唯一来源
SturdyRefs已实现(save/restore、trust zone 密封)src/sandstorm/supervisor.c++、src/sandstorm/supervisor.capnp、src/sandstorm/grain.capnp

需要强调的是,roadmap/blackrock/README.md本身是技术路线图文档而非实现说明:其中 Coordinators、Log sink、UDP 传输、外部 TCP/UDP 能力、Cap'n Proto 外部代理等条目均明确标注为 TODO,读者不应将之当作当前可用功能。而 Storage 的"对象存储代理 + 逐对象加密"、SturdyRef 的 trust zone 模型等,则在src/sandstorm/的 Cap'n Proto 模式与 C++ 实现中留下了可追溯的设计证据,是理解 Sandstorm 能力安全模型从单机延伸到集群的关键。

延伸阅读

  • roadmap/blackrock/README.md:本文核心来源——Blackrock 完整路线图原文;
  • roadmap/README.md:Sandstorm 整体技术路线图,说明 Blackrock 与 Platform、Self-hosting 的关系及 TODO 分类约定(project / feature / roadmap);
  • docs/administering/hosting-provider.md:托管商视角的 Blackrock 定位与部署建议(单机起步、需要时迁移);
  • src/sandstorm/backend.capnp:GatewayRouter接口定义及 Blackrock 多 shell 副本等价性注释;
  • src/sandstorm/supervisor.capnp 与 src/sandstorm/grain.capnp:SturdyRef 语义与授权码/持久能力对比的权威注释;
  • shell/imports/server/core.js 与 shell/imports/server/frontend-ref.js:前端能力引用注册表与 Mongo 依赖的实际代码。
  • 后端
  • 容器运行时
  • 安全
  • 云原生

【免费下载链接】sandstorm

Sandstorm is a self-hostable web productivity suite. It's implemented as a security-hardened web app package manager. | Actively sponsored by our friends at TestMu AI

项目地址:https://gitcode.com/gh_mirrors/sa/sandstorm
点击查看免费下载

相关推荐

上一篇:Open edX Platform MFE 配置端点治理:ADR 0035 确立 /api/frontend_site_config/v1/ 为规范端点
下一篇:企业法务智能化的架构革新:从模型选型到能力沉淀的范式重构

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/25 18:36:42

华为ENSP v1.3离线实验环境搭建与避坑指南

简介:本资源是面向网络工程初学者与HCIA/HCIP备考者的华为ENSP实战实验合集,覆盖中小型园区网、企业分支、WLAN、防火墙双机热备等典型组网场景,系统训练静态路由、VXLAN、MSTPVRRP、PIM-SM/DM组播、IPv6无状态配置、DHCP Snooping、路由重发…

作者头像 李华
网站建设 2026/10/25 18:36:25

Cassava 工具指南:高效处理 CSV 文件编码、编辑与拆分

简介:Cassava是一款轻巧但功能丰富的CSV编辑软件,面向需要频繁处理表格数据的办公人员、数据分析初学者及开发者。它支持以类似文本编辑器的方式直接编辑CSV内容,并内置宏功能与简易电子表格能力,可满足批量修改、行列调整、数据导…

作者头像 李华
网站建设 2026/10/25 16:54:51

WSL2 下升级 Node.js 到 24 版本:OpenClaw 部署的必备指南

刚在 WSL2 里折腾 OpenClaw(就是大家俗称的“小龙虾”)的时候,卡在了一个特别不起眼但必须解决的环节:Node 版本太旧,官方要求的 Node 24 一直装不上。当时我的 WSL2 里还是 Node 18,npm 版本也偏低&#x…

作者头像 李华
网站建设 2026/11/3 3:54:14

Agent-Reach:面向业务落地的智能体抵达协议

1. 项目概述:Agent-Reach 是什么,它解决的不是“调用API”而是“让智能体真正抵达业务现场”Agent-Reach 这个名字里,“Agent”不是指某个具体模型或服务,而是泛指具备目标理解、工具调用、状态记忆与自主决策能力的智能体&#x…

作者头像 李华
网站建设 2026/10/25 16:54:06

本地部署AI智能体驱动HFSS/CST:电磁仿真全流程自动化实战

这些年做射频和电磁仿真,桌面上的HFSS、CST图标早就是吃饭的家伙了。但说实话,真正动手去扫参数、调模型、后处理提取结果,很多操作都是机械重复的——改个贴片尺寸、跑一遍频扫、导出一张S参数图、再调下一个尺寸,一天就这么过去…

作者头像 李华