
vpod v0.7.1
Лёгкие и безопасные Linux-песочницы для недоверенных процессов. Работают в браузере и на сервере.
Vpod
Что такое vpod?
vpod — это лёгкая переносимая песочница, которая предоставляет недоверенному процессу мгновенную среду Linux. Она использует архитектуру RISC‑V и полностью работает внутри WebAssembly.
- Быстрый запуск : загрузка менее чем за секунду.
- Переносимость : работает где угодно без какой-либо настройки.
- Изоляция : всё состояние выполнения остаётся внутри WASM-песочниц.
Как это работает
vpod запускает полную систему RISC‑V (RV64GC, один виртуальный CPU), скомпилированную в WebAssembly. Внутри неё загружается настоящее ядро Linux с реальным пользовательским пространством, поэтому оболочки, инструменты и демоны ведут себя так же, как на реальном оборудовании.
Снимки. Вместо загрузки Linux с нуля vpod восстанавливает снимок: сохранённое состояние машины (регистры CPU, RAM, файловая система), снятое сразу после загрузки. Восстановление занимает значительно меньше секунды. Приостановка работает так же, но в обратном порядке: на диск записываются только «грязные» страницы памяти, поэтому вы можете приостановить песочницу и возобновить её позже, даже из другого процесса.
Упреждающая трансляция (AOT). Чистая поэлементная эмуляция медленна, а WebAssembly исключает JIT во время выполнения. Поэтому на этапе сборки снимка наиболее «горячие» пути гостевого кода транслируются из RISC‑V в нативный код, который компилируется прямо в сам WASM-модуль. Во время выполнения эмулятор передаёт управление этим транслированным блокам, когда гостевой код совпадает, и возвращается к интерпретатору, когда не совпадает. Это даёт примерно 5-кратный выигрыш на задачах, ограниченных производительностью CPU, без какого-либо влияния на изоляцию: транслированный код проходит те же проверки MMU и памяти, что и интерпретируемый.
Граница WASI. Компонент WASM общается с хостом исключительно через WASI 0.2. Гостевая система никогда не видит файловые дескрипторы, сокеты или память хоста: доступ к файловой системе идёт через явно смонтированные каталоги, а сеть — через пользовательский сетевой стек внутри компонента, который запрашивает у хоста только обычные исходящие сокеты. Всё остальное (гостевое ядро, процессы, память) живёт внутри линейной памяти WASM и умирает вместе с ней.
Спецификация RV64GC
G (расширения общего назначения)
- I : базовый набор 64-битных целочисленных инструкций.
- M : аппаратное умножение и деление, полезно для хеширования и криптографии.
- A : атомарные операции для потокобезопасных программ.
- F/D : числа с плавающей запятой одинарной и двойной точности, подходят для научных вычислений и задач машинного обучения.
C (сжатые инструкции) Уменьшает размер кода на 30%, улучшая скорость выборки инструкций и эффективность использования памяти. Это важно при запуске полного пользовательского пространства Linux внутри нашей ограниченной по памяти среды WASM.
[!NOTE] Расширение V (векторное) не реализовано. Инструкции RVV выполнялись бы как эмулируемый RISC-V; сквозной передачи SIMD на CPU хоста нет. Добавление V увеличило бы накладные расходы на эмуляцию без какого-либо выигрыша в производительности для векторных нагрузок.
Начало работы
Python SDK
pip install vpod
from vpod import Sandbox
# Run a command
sandbox = Sandbox.create()
result = sandbox.commands.run("whoami")
print(result.stdout) # root
sandbox.close()
# Persistent session — state preserved across calls
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 — variables persist
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
[!IMPORTANT] Первый вызов
Sandbox.create()загружает снимок по умолчанию (alpine) и кэширует его локально, если его там ещё нет.
CLI
curl -fsSL https://install.vpod.sh | sh
Или установите через PowerShell (Windows)
irm https://install.vpod.sh | iex
# Pull a snapshot
vpod pull alpine:latest
# Start an interactive shell
vpod
Документация
Посетите документацию Vpod.
Ограничения
- Накладные расходы на эмуляцию: внутри WebAssembly нет аппаратной виртуализации, поэтому весь гостевой код эмулируется. Накладные расходы полностью зависят от рабочей нагрузки: работа, ограниченная вводом-выводом и сетью, выполняется почти с нативной скоростью, тогда как интенсивная работа, ограниченная производительностью CPU, выполняется заметно медленнее даже с AOT-трансляцией. Если ваша нагрузка — в основном «запустить инструмент, прочитать файл, вызвать API», вы разницы не заметите.
- Нет доступа к GPU: CUDA, Metal и аппаратные ускорители машинного обучения недоступны. Поддержка может быть добавлена в будущем с помощью wasi-nn.
Вклад в проект
Вклад приветствуется — от сообщений об ошибках до поддержки новых устройств. Откройте issue, чтобы обсудить что-либо существенное перед реализацией.
Предварительные требования
- Rust (последний стабильный) с целью
wasm32-wasip2:rustup target add wasm32-wasip2 - Python 3.10+ для SDK
- Zig (0.16) и bsdtar, нужны только если вы собираете снимки самостоятельно
Настройка окружения для разработки
# One-time: generate the AOT stub (a fresh clone has no translated blocks)
./scripts/aot-stub.sh
# Build the WASM component (library + CLI)
./scripts/build-wasm.sh
# Install the host CLI
cargo install --path crates/vpod
# Install the Python SDK in dev mode
pip install -e "sdks/python[dev]"
Запуск тестов
CI запускает их для каждого PR, поэтому прогоняйте их перед отправкой:
cargo fmt --all -- --check # formatting
cargo clippy --all-targets --all-features -- -D warnings
cargo test --all # Rust tests
# Python SDK integration tests (needs the WASM library in place)
cp target/wasm32-wasip2/release/vpod_wasi_lib.wasm sdks/python/vpod/
pytest sdks/python/tests/ -v -m integration
Сборка снимков
Проект использует готовые снимки Alpine из registry.vpod.sh, поэтому обычно вам это не нужно. Чтобы собрать снимок локально:
./scripts/build-default-snapshot.sh # dist/alpine-3.23.0-256mb.snap
./scripts/build-data-snapshot.sh # 512 MB variant with numpy/pandas/scipy
[!IMPORTANT] Чтобы использовать локально собранный снимок, раскомментируйте строки в
resolve_snapshot()вcrates/vpod/src/main.rs.
Сборка снимков также может запускать AOT-проход (scripts/aot-snapshot.sh <snapshot>), который трассирует репрезентативную нагрузку, транслирует «горячие» блоки и пересобирает эмулятор со встроенными в него блоками. Это занимает время; заглушки из aot-stub.sh достаточно для повседневной разработки — всё работает так же, просто медленнее.
Pull requests
- Держите PR сфокусированными: одно изменение на PR.
fmt,clippyи набор тестов должны проходить (CI проверяет все три).- Если вы затрагиваете пути исполнения или памяти эмулятора, опишите, как вы проверяли корректность (как минимум набор тестов; для тонких изменений хорошая проверка — загрузка плюс реальная нагрузка внутри гостевой системы).
Лицензия
Этот проект лицензирован по Apache License 2.0. Подробности — в файле LICENSE.
