EnglishРусский Map
MicroVM

Spindle - движок QEMU microVM для CI в Tangled

title
Spindle - движок QEMU microVM для CI в Tangled
type
summary
summary
В self-hosted CI-runner'е Tangled появился движок QEMU-microVM: отдельные VM для workflow, конфиг NixOS из YAML, vsock-агент и двустороннее Nix-кэширование.
tags
microvm, ci, nix, virtualization, sandboxing
parent
microvm
created
2026-07-21
updated
2026-07-21
lang
ru
translation_of
spindle-microvm
source_updated
2026-07-21
translated
2026-09-01
translator
lllm/antigravity/gemini-3.7-flash-medium

Инженерная заметка от tangled (git-платформы для совместной работы на базе atproto), представляющая движок выполнения на базе QEMU-microVM для Spindle, её self-hosted CI-runner'ов. Каждый workflow получает собственную полноценную виртуальную машину - изолированное окружение, внутри которого можно делать всё что угодно, - с уровнем безопасности VM и скоростью запуска microVM. Это обновление существующего движка Nixery с сохранением полной совместимости: достаточно заменить nixery на microvm в workflow.

Что здесь даёт microVM

Та же архитектура, что и в qemu-microvm и pve-microvm: VM, из которой выбросили всё лишнее - никакого BIOS, сканирования PCI, эмулируемой графики и устаревших устройств, только virtio. Благодаря этому машина запускается быстро и расходует минимум памяти. Сегодня QEMU - единственный runner, но движок спроектирован так, чтобы в будущем можно было подключить и другие (упоминается Firecracker). Это даёт Spindle честную изоляцию на уровне ядра для недоверенных CI-нагрузок - конкретное применение для CI тезиса из microvm-2026 и sandboxing-ai-agents о том, что контейнер не является границей безопасности.

Гостевой агент на vsock

Spindle не заходит в гостевую систему по SSH и не запускает команды "снаружи". Внутри VM работает небольшой агент: в момент загрузки он подключается обратно к Spindle через vsock, передаёт приветствие, и после этого каждый шаг workflow отправляется ему в виде сообщения. Агент выполняет команды от непривилегированного пользователя, стримит stdout/stderr обратно и передаёт коды возврата. Хостовая часть живёт в spindle, а гостевая представляет собой небольшой бинарник на Rust под названием shuttle, реализующий протокол agentproto - любой желающий может реализовать его и использовать собственного агента. Шаблон взаимодействия хост <-> гость через vsock - та же схема, которую pve-microvm использует для проброса SSH-агента, а оркестраторы песочниц вроде superhq - для управления гостевыми системами без их вывода в сеть.

Образы NixOS, настраиваемые из workflow

Главная отличительная черта. Доступно два варианта образов:

  • Образы NixOS - вся гостевая система собирается через Nix, поэтому машина настраивается прямо из YAML-файла workflow. Новые ключи, которые понимает образ NixOS:
    • dependencies - пакеты, доступные на шагах workflow; они помещаются в devshell mkShellNoCC, который подгружается на каждом шаге (благодаря чему доступны полноценный stdenv, настройки pkg-config и прочее - openssl-sys компилируется без проблем). Простые имена берутся из nixpkgs, а синтаксис flakeref#attr позволяет подтягивать пакеты из любого flake.
    • registry - переопределение глобальных ссылок (зафиксировать nixpkgs на nixos-unstable, задать псевдонимы для собственных flake'ов).
    • caches - сопоставление URL бинарного кэша и доверенного открытого ключа; подключается к read-прокси, чтобы гостевая система забирала готовые пути вместо сборки с нуля.
    • services / virtualisation - передаются напрямую в NixOS. Параметр services.postgresql.enable поднимает Postgres до запуска шагов; virtualisation.docker: true запускает полноценный демон Docker внутри VM. К моменту выполнения первого шага Postgres уже слушает порт, а сокет Docker готов к работе - никакой возни с sidecar-контейнерами. (true служит сокращением для .enable = true везде, где есть опция enable.)
  • Образы не на базе NixOS - пока только Alpine, но может быть любой дистрибутив. Настройки уровня NixOS в workflow здесь недоступны, но если в образе установлен Nix, он всё равно может работать с кэшем Nix в Spindle.

Двустороннее кэширование Nix

Повторные запуски происходят быстро, поскольку Spindle агрессивно кэширует данные в обоих направлениях: зависимости, службы и любые Nix-деривации, собранные внутри microVM, отправляются в Nix-кэш Spindle, поэтому следующему workflow не приходится собирать их заново. Если Spindle уже собирал данную комбинацию базы и конфигурации, он передаёт гостевой системе готовый store path для реализации (скачивая его из настроенного кэша) вместо повторной сборки - так что идентичные повторные запуски отрабатывают быстро. Как и всё в Tangled, решение полностью self-hostable.

Место в общей картине

Практическое воплощение шаблона использования microVM в качестве фундамента изоляции в контексте CI, примечательное тем, что декларативная конфигурация машины (NixOS) вынесена прямо в манифест CI. Связанные страницы: microvm, qemu-microvm, pve-microvm (тот же движок QEMU-microVM для Proxmox), matryoshka-isolation, sandboxing-ai-agents и features-to-steal-from-npmx (ранее упоминавшийся в vault проект Tangled).