1.4 virtio 设备隔离
机制原理
virtio 是虚拟机内最常见的"半虚拟化"IO 设备协议,CubeSandbox 中所有 guest ↔ host 数据通路(网络、磁盘、文件系统)都走 virtio。每个 virtio 设备的隔离由 3 个层面共同保证:
- 独立 queue:每个设备配置
num_queues=1, queue_size=1024(默认)——一条独立队列就一个独立 ring buffer,避免跨设备的 mem copy 路径混淆 - 独立 id 和 tag:设备有
id(内部编号,如cube-fs)和共享挂载的tag(guest 看到的 label,如cubeShared)。Guest 内只能 mount 这个 tag 看到的共享,无法触碰其它 sandbox 的 virtio 后端 - virtio backend in host process:每条 virtio 设备在 shim 进程内有独立的 worker 处理 guest kick / DMA(由 cloud-hypervisor 调度),不会和别的设备共用线程上下文
代码上的命名约定:
pub const VIRTIO_FS_TAG: &str = "cubeShared";
pub const VIRTIO_FS_ID: &str = "cube-fs";
FsConfig {
id: VIRTIO_FS_ID,
tag: VIRTIO_FS_TAG,
num_queues: 1,
queue_size: 1024,
...
}
net 设备 id 是命名空间化的:format!("{}-{}", utils::NET_DEVICE_ID_PRE, nets.len()),保证多设备也不冲突。
为什么 CubeSandbox 使用它
- 把 IO 路径"半虚拟化"——避免完整设备模拟(IDE/NVMe/USB)的庞大攻击面
- 每个设备独立 queue——设备 A 的一次 ring flood 不会污染设备 B 的队列
- Tag 名约定(
cubeShared)是 guest-side rootfs 的入口,也是 agent 启动 OCI 容器时识别 virtiofs 后端唯一寻址方式 - 和 KVM 一起构成微 VM 的最小可视 IO 面
如何使用 / 配置
- 透传 virtio-fs 由 annotation
cube.fs/cube.virtiofs控制:metadata: annotations: cube.virtiofs: | { "tag": "cubeShared", "source": "/var/lib/cubelet/sandboxes/box-42/rootfs", "cache": "always" } cache字段对应CubeShim/shim/src/sandbox/config.rs:35-37的SHARE_CACHE_ALWAYS=1, SHARE_CACHE_NEVER=2- net 设备的
id是程序生成的,user 不可改,但能用 annotationcube.net.tx_rate/cube.net.rx_rate控速(被 TokenBucket 处理)
注意:
- 不要尝试在 guest 内 mount 一个未申报 tag 的 virtiofs——会直接 ENOENT
- guest 内 modprobe virtio-pci 但不 modprobe virtio_mmio——具体看
vmlinux内编译了哪些模块 - 如果你暴露的是临时数据,用
cache: never,数据完整性 / 安全同步优于性能