Virtual Oxide Labs:模拟一整套 Oxide 机架

Hacker News Top 工具

摘要

Oxide Computer 介绍了 Voxel(Virtual OXidE Labs)——这是一套在单台机器上模拟完整 Oxide 机架的软件仿真栈,集成了 Propolis 虚拟化、FRR/BGP 网络、SoftNPU P4 交换机以及 SP/RoT 微控制器仿真,让产品保障团队无需使用特殊的测试版本,就能以真实的控制面软件进行高保真度的 CI 测试。

暂无内容
查看原文
查看缓存全文

缓存时间: 2026/10/14 22:07

# Virtual Oxide Labs:模拟完整 Oxide 机架 | Oxide Computer Company 来源:https://oxide.computer/blog/voxel-labs 测试和开发机架级硬件的难点在于,机架级设备并不容易获得。我是说,先不提 DDR5 当硬通货这回事;即使所有零件都供应充足,任何完工的机架也会迅速送往前线(也就是我们客户的机数据中心)。作为 Oxide 产品保证团队的一员,我觉得这完全不公平,却又完全合理。所以我们必须发挥一些创造力。我们必须要能: - 复现各种客户网络拓扑 - 运行我们真实的控制平面 - 测试我们最新版本的软件 - 表示硬件组件(毕竟我们是做机架的),包括我们的交换机和微控制器 而锦上添花的是:我们需要在不发布特殊"测试版"发布的情况下做到这一切。因为我们希望保持 CI 的简洁,也因为那样做不算公平竞争。 别误会——我们也不是毫无办法。我去年加入 Oxide 时,最早接触的东西之一就是我们的 *racklettes*,也就是比标准机架小的迷你机架,每个包含 4 个 sled 和 2 个交换机。这些 racklette 可以像真实机架一样初始化和运行,因为它们*就是*真实机架。只不过不是任何有经济效益的销售形态。但对于测试来说,它们好用极了。我们现在有 4 个,很快就会有 8 个,可以在上面测试任何硬件/软件组合的需求。 我们还有各种运行 Omicron 的模拟方法。你可以在 [How to Run Simulated](https://github.com/oxidecomputer/omicron/blob/main/docs/how-to-run-simulated.adoc) 和更完整的 [How to Run 指南](https://github.com/oxidecomputer/omicron/blob/main/docs/how-to-run.adoc) 中了解更多信息。我不会在这里展开太多细节,但简而言之,我们的控制平面(以及更多部分)的大部分组件都可以独立运行、并行运行,以及以不同程度进行模拟。 ## 什么是 Voxel? (https://oxide.computer/blog/voxel-labs#_whats_a_voxel) 你还记得游戏 Q*bert 吗?它是最先火爆的等距视角游戏之一,看起来大概像这样: Q*bert,等距游戏的怀旧回忆 为什么要给你看一张小得可笑的游戏截图呢?嗯,图中每个立方体代表一个"体素"(voxel),即三维空间中的一个点。它实际上是像素的三维版本。Volume Element(体积元素)+ Pixel(像素)= Voxel(体素)。挺有意思的,对吧? 无论如何,对 Oxide 来说,Virtual OXidE Labs(即 Voxel)意味着将极高的保真度打包到单个硬件中。它是我们之前虚拟实验室(称为 a4x2)的精神继承者,那个实验室让我们能够 hack 出运行在虚拟机中的像样的机架。顺便注意"保真度"这个词。正如 Bryan Cantrill 所说的,[基本原则](https://oxide-and-friends.transistor.fm/episodes/emulating-oxide-how-faux-can-you-go):实验室应使用未经 hack 或修改的原版 Oxide 软件。这就是 Voxel 给我们的。一个完整的软件模拟栈,基于 illumos 构建,使用 Rust 编写,我们可以在其中构建和测试各种真实配置: - 由 [Propolis](https://github.com/oxidecomputer/propolis) 提供的 sled 虚拟化 - 使用 Debian 和 [FRR](https://frouting.org/) 的 BGP(有编号和无编号)或静态网络 - 通过 Oxide 自有的 [SoftNPU——一个软件 P4 交换机](https://netstack.fm/episodes/oxide-networking-with-ryan-goodfellow)实现 P4 驱动的交换机 - 我们的 Service Processor(SP)和 Root of Trust(RoT)的微控制器模拟与仿真 更重要的是,它在相当小的占用空间内提供了所有这些功能。在家里,我在一台 Minisforum MS-A2 迷你 PC 上运行 Voxel 实验室,配备 32 线程 AMD Ryzen 9 9955HX 和 96GB 内存。在这台机器上,我可以轻松启动 6 个 sled,无论是单机架形式还是多机架配置(两个独立机架,一个管理平面)。只需要 [Oxide Helios](https://github.com/oxidecomputer/helios) 和一块足够快的 NVMe 驱动器。启动后,大约 10 分钟你就拥有了一个完整的 Oxide 机架,每个"sled"都在自己的 Propolis 虚拟机中——包括交换机(也在 Propolis 中)和其他基础设施。 ### 镜像创建 (https://oxide.computer/blog/voxel-labs#_image_creation) 还记得我说过我们必须使用原版 Oxide 软件吗?这实际上让事情变得简单了。我们要做的第一件事(遵循虚拟机管理程序工具中的常见做法)是创建一个可重用的快照。Oxide sled 只有两种形态:普通 sled(第一代叫"gimlet",当前代叫"cosmo")或 "scrimlet",即连接到 sidecar 交换机并运行交换机 zone 的 sled。其复杂性中的设计非常优雅,你应该在[我们的网络文档](https://docs.oxide.computer/guides/architecture/networking)中了解更多。 要为 Voxel 创建快照,我们只需要创建一个"sled"(虚拟机),在其上安装我们的控制平面(Omicron),在配置之前对其进行快照,然后瞧:一个随时可启动的 sled 就完成了。 控制平面可以通过两种方式安装: **从源码构建** Voxel 在 GitHub 上克隆 [Omicron 仓库](https://github.com/oxidecomputer/omicron/)(或使用本地定义的源码以加速开发),并使用 `cargo` 进行编译。 **从 TUF 仓库** 我们使用 [Tufaceous](https://github.com/oxidecomputer/tufaceous) 通过 The Update Framework(TUF)打包 Omicron 发布,并使用我们的 CI 工具 [Buildomat](https://github.com/oxidecomputer/buildomat/)。 以第二种方式为例,以下是 `voxel image create` 提取构成 sled 配置的关键组件的过程的开始部分: ``` $ pfexec ./target/debug/voxel image create --from-tuf ../5d176e0be7e5cc0d3288c1bef10005ec31f2cd7c.zip 5d176e0be7e5cc0d3288c1bef10005ec31f2cd7c [voxel] TUF source ../5d176e0be7e5cc0d3288c1bef10005ec31f2cd7c.zip: system version 23.0.0-0.ci+git5d176e0be7e, omicron 5d176e0be7e [voxel] extracted 12 zones from ../5d176e0be7e5cc0d3288c1bef10005ec31f2cd7c.zip [voxel] extracted 3 measurement corpus artifacts [voxel] extracting host artifacts -> /export/home/helios/voxel-rawfix/target/debug/../../voxel-image/.tuf-host [voxel] host boot image 1258295296 bytes, phase 1 rom 33554432 bytes [voxel] extracted SP/RoT firmware -> /export/home/helios/voxel-rawfix/target/debug/../../voxel-image/.tuf-fw/ca9184058bd7 ``` 经过大量的解包和暂存后,它会启动一个虚拟机,所有内容都写入/安装到其中。最后: ``` [voxel] ready: voxel-cp version=unknown unpacked_artifacts=18 built=2026-09-06T21:37:58 [voxel] clearing device-instance map, halting [voxel] flushing, up to 25s [voxel] stopping hypervisor [voxel] writing voxel image voxel-cp-5d176e0be7e-tuf ``` 该镜像是一个 ZFS 快照,可以重复使用来创建我们的机架。 ### 准备启动 (https://oxide.computer/blog/voxel-labs#_ready_for_launch) 启动机架的过程类似,只不过控制平面已经安装好了。此时我们只需要: 1. 一个 "frr" 镜像(用于网络的 Debian 虚拟机) 2. 一个控制平面镜像(就像我们刚创建的那个) 3. `voxel-init` 代理,为每个虚拟 sled 分配任务 日志输出很长,你可以自行滚动查看。之后我会进行总结。 如我所说,步骤很多。以下是发生的事情: 1. 以 [sprockets PKI](https://rfd.shared.oxide.computer/rfd/0238) 的形式生成信任材料 2. 模拟的 STM32H753 和 LPC55 微控制器被刷入 [Hubris 固件](https://github.com/oxidecomputer/hubris) 3. 我们的[自动化网络拓扑套件](https://github.com/oxidecomputer/falcon)(称为 falcon)使用 simnet 和 VNIC 对为每条链路连接拓扑,并暂存 sled(本例中为 g0、g1 和 g2) 4. Propolis 虚拟机启动;本例中共 6 个,3 个驱动网络,3 个作为 Oxide sled 5. `voxel-init` 运行:一个轻量级 Rust 代理,运行在每个节点上,执行以下操作: - 设置 NAT 和上行链路寻址 - 在每个 sled 上配置 underlay 设置 - 在模拟的启动盘上写入 M.2 分区布局,并为五个 U.2 数据盘打标签 - 将主机 phase 2 镜像和安装数据集播种到 M.2 - 分配 scrimlet 并运行交换机执行器,使它们在重启后"记住"自己的身份 - 激活 `sled-agent`,即控制平面的每个 sled 的配置层 6. 连接到 `wicketd` 的调试 API,引导机架通过其初始化阶段 这是一系列复杂步骤的舞蹈,关于"模拟微控制器"这一部分我确实铺垫了很久才提到。但简而言之,这些是任何 Oxide 机架都必须经历的完整且正确的步骤,只不过硬件被表示为不同的代码片段。例如,需要在两个虚拟机架之间添加新的互连?在 `rack.rs` 中加几行代码即可。 有*几*件事(目前!)还不遵循基本原则。例如,构成上述 sprockets PKI 的证书不像生产机架那样在制造时从 RoT 设置和获取。但这是我们目前可以接受的事情之一,因为它不影响实际的机架运行时。 ## 模拟 Service Processor (https://oxide.computer/blog/voxel-labs#_emulating_service_processors) 这就是我之前提到的部分。让我们的机架与众不同的一个重要因素是每个 sled 中嵌入的 [RoT 和 SP](https://docs.oxide.computer/guides/architecture/rack-components#_service_processors)。我们一直有一个 `SpSim` 构建体充当 service processor 的桩件,会在正确的时间返回正确的信息。但那是模拟(simulation),不是仿真(emulation)。它永远只走 happy path,对于真正的测试场景来说保真度不够。 因此,我们为 illumos 和 Linux(x86 和 ARM)构建了实际仿真的 Cortex-M7 和 Cortex-M33 设备。这个工具的[仓库](https://github.com/oxidecomputer/sp-emu)(sp-emu)是开源的。两种设备各在一个线程中运行,(大部分)忠实地仿真了三个主要要求:指令、时间和中断。在此基础上,你可以将我们的 Hubris 固件直接刷入这些模拟设备,然后通过普通 socket 进行通信。 Voxel 实验室可以通过 Management Gateway Service(MGS)和 Inter-Processor Communication Channel(IPCC)与这些虚拟设备通信。你可以在 [Management Gateway Service 仓库](https://github.com/oxidecomputer/management-gateway-service/)和 [Hubris 文档](https://hubris.oxide.computer/reference/)中了解这些概念的全部内容。 我想不出有什么"用这一招就能把真实微控制器跑成虚拟设备!"的捷径。但 sp-emu 工作中真正的挑战是时间。记住我们运行的所有代码都是为硅芯片设计的。Hubris 基于 1ms 的 SysTick 进行调度,模拟器不使用真实时间(wall time);因此我们必须发明一个时钟。话虽如此,模拟硬件也*比*真实硬件*慢*。所以……单位时间内可用的时间更少。因此,与其试图在时间上做文章,时间变成了指令。 例如,这是 `maybe_tick`: ```rust if self.systick == 0 { self.systick = self.syst_rvr; } self.systick -= 1; if self.systick == 0 { self.systick = self.syst_rvr; self.tick_events = self.tick_events.wrapping_add(1); if self.syst_csr & 2 != 0 && self.mode == Mode::Thread && !self.primask { self.exception_entry(15, bus); // SysTick exception } } ``` 在这种情况下,我们用内核自身的重载值来计数指令,并在单优先级设计允许安全处理异常的任何地方触发异常——在线程模式下,中断未被屏蔽时。 同理,访问外设花费我们时钟的一个 tick(一条指令),而在硅芯片上,它可能会在总线上阻塞几十个周期。 你可能注意到了 `self.exception_entry`,它在代码的其他地方定义: ```rust fn exception_entry(&mut self, vecnum: u32, bus: &mut Bus) ``` 简而言之,这个函数模拟了 Cortex-M 内核处理异常时硬件所做的全部工作,从"异常变为活跃状态"到第一条处理程序指令。这里的 `vecnum` 是 ARMv7-M 异常编号(同时也是该异常处理程序的向量表索引)。`bus` 是内存系统,用于实际推入栈帧和读取向量表。 Hubris 的内核不可抢占,但它以抢占方式调度任务。SVCall、PendSV、SysTick 和所有 IRQ 运行在同一优先级级别,而 fault 保持更高优先级。因此,模拟器不需要嵌套处理程序。它根据 PRIMASK、FAULTMASK 和 BASEPRI 设置来处理挂起的 IRQ。如果其中一个挂起了 PendSV,它将执行内核的延迟上下文切换。 有关内部工作原理的更多细节,你可以查看[这段精彩的文档](https://github.com/oxidecomputer/hubris/blob/master/sys/kern/src/arch/arm_m.rs#L5-L71)。 ```rust if let Some(irq) = bus.next_irq() { if self.basepri == 0 || (bus.irq_prio(irq) as u32) < self.basepri { bus.clear_pending(irq); self.exception_entry(16 + irq as u32, bus); return; } } if bus.take_pendsv() { self.exception_entry(14, bus); } ``` 这里还有很多可以讨论的内容,但总结起来,你可以看看这个伪代码风格的循环: ```rust loop { cpu.step(&mut bus, host.as_mut())?; // 一条 Thumb-2 指令 cpu.maybe_tick(&mut bus); // SysTick:时间就是指令 cpu.maybe_interrupt(&mut bus); // NVIC 和 PendSV 分发 if cpu.cycles % 4096 == 0 { bus.pump_eth(host.as_mut()); // MGS 数据包进出 bus.pump_uart(host.as_mut()); } } ``` 注意:是的,我知道我之前说没有"周期"(cycles),然后又有一个名为 `cycles` 的字段。这就是仿真的"假装到成功"(fake it till you make it)部分。 这就是 sp-emu 的整体心跳,无限循环运行。其他所有东西的存在都是为了让这些调用看起来真实。 ## 还有一件事 (https://oxide.computer/blog/voxel-labs#_and_one_more_thing) 除了模拟 sled 和微控制器的实际工作之外,剩下的是老式的用户体验问题。当你在单个系统上运行这么多组件时,想弄清楚哪些部分在哪里、如何连接到一个机架上的某个 sled 而不是另一个,可能会非常混乱。因此,我们用来启动和销毁虚拟机架的 `voxel` 命令也充当连接工具。 例如: ``` $ pfexec ./target/debug/voxel host login g0 [voxel] ssh [email protected] (g0 global zone) The illumos Project helios-3.0.23976 May 2026 root@g0:~# zoneadm list global oxz_switch oxz_internal_dns_5b07f3e7-444c-462c-9633-6967e52d6a3b oxz_ntp_b308987c-3408-4077-b9a0-d803ed1e420a oxz_cockroachdb_daa29fcd-fff0-4b3d-a722-b969e03398d9 oxz_cockroachdb_117986ee-8b2d-4567-8c6f-e01f3e63447e oxz_crucible_310a91b5-1b67-46cb-b08d-ad6534702a3d oxz_crucible_627c130b-97d6-4e8f-b13e-eb03b671c2a3 oxz_crucible_pantry_65e1b527-26fc-46fd-8584-d9792771926c oxz_crucible_2692a74a-3a22-420c-857a-a3c786e4b600 oxz_external_dns_baa049eb-7bdd-4d8e-ace3-c0ef054845bd oxz_crucible_2ffc1456-b0e1-4f8e-8b6d-6ab01377bd25 oxz_crucible_c5f7d004-9d9b-4741-9246-c4793b9c7976 oxz_nexus_c1a31871-bdb5-422c-b5b1-2de62aa31e30 ``` 该命令直接将用户登录到 g0 sled 的全局 zone 中。 或者: ``` $ pfexec ./target/debug/voxel tp login switch0 [voxel] ssh [email protected] -> zlogin oxz_switch (g0 switch0) [Connected to zone 'oxz_switch' pts/3] Last login: Sun Sep 6 22:17:52 from fdb0:a840:2500: The illumos Project helios-3.0.23976 May 2026 root@oxz_switch:~# ``` 这里的 `tp` 充当我们的[技师端口](https://docs.oxide.computer/guides/system/rack-installation#connect-tech-ports)的角色,允许用户直接连接到交换机 zone 以执行机架级命令和网络操作。 还有许多命令来管理镜像(导出/导入、删除)、配置(网络拓扑、sled 大小、多机架等),以及随着我们持续构建而不断推出的新功能。 Voxel 是一个

相似文章

Oxide Rack 3D Explorer

Lobsters Hottest

Oxide Rack 3D Explorer 是一款交互式3D可视化工具,用于探索Oxide Computer Company的硬件机架设计。

为调试而开发(2025)

Lobsters Hottest

Dave Pacheco 撰文介绍 Oxide 控制平面的 DNS 传播机制,以及如何围绕可调试性来设计系统,最终催生了 Omicron 调试器工具 omdb。

@CycleDecoded: 别再用原生 HuggingFace硬扛本地大模型推理了,显存直接爆满,吞吐量慢得像乌龟爬! 伯克利实验室出品的 vLLM,用搞操作系统内存分页(PagedAttention)的那套黑科技,直接把 GPU 显存压榨到了极限,KV Cache…

X AI KOLs Timeline

伯克利 Sky Computing Lab 开源的 vLLM 是一个高性能 LLM 推理与服务库,通过 PagedAttention 和连续批处理大幅提升吞吐量、降低显存浪费,并兼容 OpenAI API 和多种硬件。

HIVE:带置信度的开源研究工具

Reddit r/AI_Agents

HIVE(Hive Inspired Virtual Entity,受蜂巢启发的虚拟实体)是一个开源研究系统,通过九个从不同角度分析问题的 forager agent、一个 queen verdict(蜂后裁决)以及共享记忆(comb),并利用 Unpaywall 与 DOI 检索的已验证白皮书,为 LLM 输出提供可信度置信值,减少幻觉。系统可在本地运行(Ollama + Qwen3.6 35B),在 M1 Max 64GB 上完成设计与测试。