
vpod v0.6.0
Лёгкие и безопасные Linux-песочницы для недоверенных процессов. Работают в браузере и на сервере.
Vpod
Что такое vpod?
vpod — это лёгкая, переносимая песочница, которая предоставляет непроверенному процессу мгновенное Linux-окружение. Она использует архитектуру RISC‑V и полностью работает внутри WebAssembly.
- Быстрый запуск: загрузка менее чем за секунду.
- Переносимость: работает где угодно без какой-либо настройки.
- Изоляция: всё состояние выполнения остаётся внутри WASM-песочниц.
Как это работает
vpod запускает полноценную RISC‑V систему (RV64GC, одно виртуальное ядро), скомпилированную в WebAssembly. Внутри загружается реальное ядро Linux с реальным пользовательским пространством, поэтому оболочки, инструменты и демоны ведут себя так же, как на реальном оборудовании.
Снимки. Вместо загрузки Linux с нуля vpod восстанавливает снимок: сохранённое состояние машины (регистры CPU, RAM, файловая система), захваченное сразу после загрузки. Восстановление занимает значительно меньше секунды. Приостановка работает аналогичным образом в обратном направлении: на диск записываются только изменённые страницы памяти, поэтому вы можете поставить песочницу на паузу и возобновить её позже, даже из другого процесса.
Упреждающая трансляция. Чистая эмуляция «инструкция за инструкцией» медленна, а WebAssembly исключает JIT во время выполнения. Поэтому на этапе сборки снимка самые горячие пути гостевого кода транслируются из RISC‑V в нативный код, который компилируется непосредственно в сам WASM-модуль. Во время выполнения эмулятор переключается на эти транслированные блоки, когда гостевой код совпадает, и возвращается к интерпретатору, когда нет. Это даёт примерно 5-кратное ускорение на задачах, интенсивно использующих CPU, без какого-либо влияния на изоляцию: транслированный код проходит через те же проверки MMU и памяти, что и интерпретируемый.
Граница WASI. WASM-компонент взаимодействует с хостом исключительно через WASI 0.2. Гость никогда не видит файловые дескрипторы, сокеты или память хоста: доступ к файловой системе осуществляется через явно смонтированные каталоги, а сеть — через пользовательский сетевой стек внутри компонента, который запрашивает у хоста только обычные исходящие сокеты. Всё остальное (гостевое ядро, процессы, память) находится внутри линейной памяти WASM и исчезает вместе с ней.
Спецификация RV64GC
G (расширения общего назначения)
- I: Базовый набор 64-битных целочисленных инструкций.
- M: Аппаратное умножение и деление, полезно для хеширования и криптографии.
- A: Атомарные операции для потокобезопасных программ.
- F/D: Числа с плавающей запятой одинарной и двойной точности, подходят для научных вычислений и ML-инференса.
C (сжатые инструкции) Уменьшает размер кода на 30%, улучшая скорость выборки инструкций и эффективность использования памяти. Это важно при запуске полного пользовательского пространства Linux в нашей ограниченной по памяти WASM-среде.
[!NOTE] Векторное расширение V не реализовано. Инструкции RVV выполнялись бы как эмулируемый RISC-V; сквозной передачи SIMD на CPU хоста нет. Добавление V увеличило бы накладные расходы на эмуляцию без какого-либо выигрыша в производительности для векторизованных нагрузок.
Начало работы
TypeScript SDK
npm install @capsule-run/vpod
import { Sandbox } from "@capsule-run/vpod";
const sandbox = await Sandbox.create();
// Состояние сохраняется между вызовами
await sandbox.commands.run("export API_KEY=secret");
const key = await sandbox.commands.run("echo $API_KEY");
console.log(key.stdout); // secret
// Python REPL — переменные сохраняются
await sandbox.code.run("data = [1, 2, 3]");
const total = await sandbox.code.run("print(sum(data))");
console.log(total.text); // 6
await sandbox.close();
Тот же пакет работает во вкладке браузера, где снимок кэшируется в приватном хранилище источника, а не на диске.
[!IMPORTANT] Первый вызов
Sandbox.create()загружает снимок по умолчанию (alpine) и кэширует его локально, если он ещё не присутствует.
Python SDK
pip install vpod
from vpod import Sandbox
# Выполнение команды
sandbox = Sandbox.create()
result = sandbox.commands.run("whoami")
print(result.stdout) # root
sandbox.close()
# Постоянная сессия — состояние сохраняется между вызовами
with Sandbox.create() as sandbox:
sandbox.commands.run("export API_KEY=secret")
result = sandbox.commands.run("echo $API_KEY")
print(result.stdout) # secret
# Python REPL — переменные сохраняются
with Sandbox.create() as sandbox:
sandbox.code.run("import requests")
sandbox.code.run("data = [1, 2, 3]")
result = sandbox.code.run("print(sum(data))")
print(result.text) # 6
CLI
curl -fsSL https://install.vpod.sh | sh
Или установка через PowerShell (Windows)
irm https://install.vpod.sh | iex
# Загрузка снимка
vpod pull alpine:latest
# Запуск интерактивной оболочки
vpod
Документация
Посетите документацию Vpod.
Ограничения
- Накладные расходы на эмуляцию: внутри WebAssembly нет аппаратной виртуализации, поэтому весь гостевой код эмулируется. Накладные расходы полностью зависят от рабочей нагрузки: задачи, связанные с вводом-выводом и сетью, работают почти с нативной скоростью, тогда как тяжёлые задачи, интенсивно использующие CPU, работают заметно медленнее даже с AOT-трансляцией. Если ваша нагрузка в основном «запустить инструмент, прочитать файл, вызвать API», вы ничего не заметите.
- Нет доступа к GPU: CUDA, Metal и аппаратные ML-ускорители недоступны. Поддержка может быть добавлена в будущем с помощью wasi-nn.
Участие в разработке
Приветствуются любые вклады — от сообщений об ошибках до поддержки новых устройств. Откройте issue, чтобы обсудить что-либо существенное перед реализацией.
Предварительные требования
- Rust (последняя стабильная версия) с целью
wasm32-wasip2:rustup target add wasm32-wasip2 - Python 3.10+ для Python SDK
- Node 20+ для TypeScript SDK
- Zig (0.16) и bsdtar, нужны только если вы собираете снимки самостоятельно
Настройка среды разработки
# Однократно: генерация AOT-заглушки (в свежем клоне нет транслированных блоков)
./scripts/aot-stub.sh
# Сборка WASM-компонента (библиотека + CLI). Копирует оба уровня в sdks/python/vpod/
./scripts/build-wasm.sh
# Установка хостового CLI
cargo install --path crates/vpod
# Установка Python SDK в режиме разработки
pip install -e "sdks/python[dev]"
# Сборка TypeScript SDK. Подхватывает компонент из каталога Python SDK
cd sdks/typescript && npm install && npm run build
npm run build по умолчанию использует --tier aot; CI фиксирует --tier base. Сборка
отказывается использовать компонент старше самого нового файла в crates/, поэтому
перезапускайте ./scripts/build-wasm.sh после изменений в эмуляторе. Изменение эмулятора
проявляется только через гостя, поэтому устаревший компонент компилируется и проходит
почти все тесты.