
Всем привет!
Это Андрей Яковлев, исследователь в области кибербезопасности. Сегодня разбираем, как изолировать ИИ-агент в виртуальной среде с помощью Docker Sandbox.
У меня в ~/.config/secretkeys/ лежит очень важный OAuth-токен. У вас на машине, скорее всего, тоже есть аналогичные штуки: ключи от облака, GitHub PAT в ~/.config/gh/, SSH-ключи в ~/.ssh/. И когда ИИ-агент запущен от имени моего пользователя, он видит все это по тем же путям, что и я. Не гипотетически может увидеть, а буквально читает и может распорядиться властью, данной ему, не самым лучшим образом, о чем я рассказывал в предыдущей статье. Поэтому я долго не пользовался агентами всерьез.
Больше всего меня пугали не риски промпт-инъекции или намеренной атаки. Давила постоянная тревожность: запущу агент не в той директории, а он перепутает токены и сходит туда, куда не надо, либо снесет диск одной командой. Я делал отдельные виртуалки под каждый проект и они работали, но ели время и ресурсы. Хотелось иметь инструмент, которому можно доверять и который не потребует ставить дома серверную стойку под вычислительные ресурсы для виртуальных машин.
Несколько месяцев назад я нашел инструмент, который, как мне тогда показалось, отлично подойдет под мои запросы. Разбираю, что из этого вышло.
Содержание
В предыдущей статье я разбирал шесть классов угроз для кодовых ИИ-агентов: случайный rm -rf, промпт-инъекцию, малварь, использующую агент как инструмент разведки, атаку на цепочку поставок через установку стороннего пакета, кражу токенов доступа и каскадную CI/CD-компрометацию. Общий знаменатель здесь — процесс агента, имеющего полные права того пользователя, который его запустил. Сейчас изоляция на уровне среды представляется не просто прогрессивным инструментом безопасности, а обязательным условием использования агента.
Эта статья про то, как и с помощью чего собирается изоляция, без глубокого технического разбора виртуализации и без воспроизведения атак на практике; этот материал я оставлю для следующих заходов. Конкретно я рассматриваю инструмент от Docker под названием Docker Sandbox — микровиртуалку с собственным ядром, сетью с файрволом «из коробки» и приватным Docker-демоном. Docker Sandbox ставится в три команды и заменяет отдельные виртуальные машины (далее — VM), созданные вручную под каждый проект с агентом.
Сразу скажу про источники информации для статьи: это официальная документация Docker по sandbox (на момент написания полная), включая архитектурный раздел и Network Policies. Я опираюсь на нее и размещаю рядом свой опыт, который накопил за несколько месяцев ежедневного использования агентов с Docker Sandbox. Если что-то в тексте у меня не совпадает с документацией, я опираюсь на практику. Где это важно, оговариваюсь явно.
Инструмент активно развивается: к примеру, за несколько месяцев успела появиться и устареть версия, включаемая в Docker Desktop, а официальная документация на сайте Docker несколько раз переписывалась. То есть на момент вашего, дорогой читатель, знакомства со статьей некоторые детали могут отличаться от описанных ниже. Поэтому настоятельно рекомендую сверяться с актуальной версией документации на официальном сайте Docker [1] перед началом использования.
Уточнение терминов
Прежде чем перейти к командам, определим терминологию. Под Docker Sandbox я понимаю продукт в целом: концепцию microVM-изоляции для ИИ-агентов от Docker. sbx — это CLI-инструмент, через который продукт сейчас живет. Раньше у Docker была другая имплементация в виде команды docker sandbox в Docker Desktop, с нее все начиналось. Но в актуальной документации она помечена как устаревшая и заменена на отдельный CLI-инструмент sbx. Дальше в статье я говорю про sbx.
Архитектура изоляции
В этом разделе приведу пять утверждений, которых хватит, чтобы понять, что именно дает изоляция и где заканчиваются ее границы.
Контейнер делит ядро с хостом, а sandbox нет
Контейнер — это набор специфичных для Linux механизмов: namespaces изолируют процессы и сеть, cgroups ограничивают ресурсы. Но ядро у контейнера и у хоста общее, поэтому любой системный вызов из контейнера проходит через то же ядро, что и системные вызовы пользователя. Sandbox устроен иначе: он запускается как отдельная microVM с собственным ядром, а границей между агентом и хостом выступает гипервизор, а не namespaces [2]. Это принципиально другой уровень изоляции.
Агент не видит ваш Docker
Внутри microVM работает собственный Docker-демон. Агент может собирать образы, запускать контейнеры, поднимать docker-compose, и ничего из этого не доходит до хостового Docker Engine. Сокет хоста (/var/run/docker.sock) недоступен для монтирования внутрь sandbox [3]. Это снимает целый класс эскалаций, где потенциальная вредоносная нагрузка дотягивается до Docker socket и через него управляет хостом. [Docker Security Cheat Sheet]
Агент не видит ваши файлы — кроме тех, что вы сами показали
В sandbox видна только рабочая директория (workspace в терминологии Docker), которую вы передали при sbx run. Другие директории хоста — ~/.ssh/, ~/.config/cloud/, /etc/ — недоступны фундаментально [2]. Символическая ссылка за пределы области не разрешается [2]. Важная оговорка: если вы передаете домашнюю директорию целиком (sbx run claude ~), агент получает доступ ко всему, что лежит в домашнем каталоге, в том числе к ключам. Естественно, это ожидаемое поведение, так и задумано, поэтому рабочую директорию агента стоит ограничивать минимально необходимым.
Sandbox живет между запусками, в отличие от обычного контейнера
Привычный контейнер одноразовый: упал, перезапустил и состояние стерто.
Да, можно ставить контейнер на паузу и хранить состояние во внешних каталогах, которые будут монтироваться каждый раз. Но это не совсем оно.
Sandbox устроен иначе. Пакеты, конфиги и скилы агента остаются между запусками, пока вы не сделаете sbx rm. У меня скилы лежат в двух местах: частично в ~/.claude внутри sandbox (живут с конкретным sandbox), частично — в репозитории проекта (живут с кодом и попадают внутрь sandbox вместе с рабочей директорией). Второй паттерн устойчивее: репозиторий переносится между sandbox, скилы переезжают вместе с кодом.
Сеть через прокси на вашем хосте
Из sandbox наружу идет только HTTP/HTTPS [5] и только через прокси на стороне хоста (host-side proxy в документации Docker [5]). Просто TCP, UDP, ICMP, DNS заблокированы на сетевом уровне [5]. Прокси делает TLS-терминацию и заодно инжектирует заголовки авторизации из ваших секретов, которые лежат вне sandbox, так что настоящее значение API-ключа в sandbox вообще не попадает. Заодно блокируются обращения к private IP, loopback и link-local [5].
Итог: изнутри Sandbox трафик идет наружу через локальный MITM прокси на хосте, все остальное на сетевом уровне отрезано.
Граница изоляции понятна. Издержки изоляции — это следующий вопрос.
Установка
Перед установкой Docker sbx стоит учесть два момента.
Первый: согласно документации Docker, на момент написания статьи поддерживаются macOS Sonoma 14 и новее, Windows 11, а также Ubuntu 24.04 и новее с поддержкой KVM.[4]. Несколько месяцев назад картина была другая: когда я ставил sbx в macOS в феврале 2026-го, требовалась именно Tahoe (версия 26). Пришлось обновляться с Sequoia.
Второй: команды установки на разных платформах разные. В macOS через Homebrew, в Windows через winget, в Linux — через apt. Это видно в блоках ниже. А вот команды самого sbx после установки везде одинаковые: sbx run, sbx ls, sbx policy работают на любой ОС без модификаций. Дальше в статье приведены команды установки для каждой платформы отдельно, а примеры запуска и настройки без разделения, потому что они идентичны для всех платформ.
# macOS brew install docker/tap/sbx sbx login # Windows winget install -h Docker.sbx sbx login # Linux (Ubuntu) curl -fsSL https://get.docker.com | sudo REPO_ONLY=1 sh sudo apt-get install docker-sbx sudo usermod -aG kvm $USER newgrp kvm sbx login
На Linux чуть больше шагов. Сначала подключается APT-репозиторий Docker (флаг REPO_ONLY=1 ставит только репозиторий, без самого Docker Engine). Потом из него ставится пакет docker-sbx, и ваш пользователь добавляется в группу kvm. sbx использует KVM как гипервизор, и без доступа к нему microVM не поднимется.
Если что-то пошло не так, sbx diagnose покажет, где именно. Команда проверяет бинарь CLI, daemon, версии, состояние директорий и аутентификации, умеет выводить данные в JSON и в Markdown для репорта в issue Docker.
sbx login запускает OAuth в браузере и записывает сессию локально. Да, и мне не до конца понятно, зачем логиниться. Докер объясняет это довольно пространными формулировками о необходимости идентификации и удобстве управления политиками внутри команды. После авторизации CLI просит выбрать сетевую политику по умолчанию: это часть онбординга и необходимый шаг [4]. О пресетах политики я расскажу ниже в отдельном разделе.

sbx login. Три варианта (Open, Balanced, Locked Down). Базового варианта из коробки нет, осознанный выбор обязателен.Docker Desktop при работе с sbx не нужен. Управление политиками на уровне организации возможно, но это отдельный платный продукт Docker AI Governance, подробнее о нем я рассказываю в разделе «Сетевые политики». Без подписки на Docker AI Governance sbx работает локально, без ограничений администратора. Это нормальный режим для индивидуального разработчика.
CLI поставлен. Что с ним реально делают каждый день?
Основные команды
Сценарий, который я демонстрирую, простой: создаем sandbox, запускаем агент, заходим в shell параллельно. Один сплошной фрагмент, как это выглядит у меня в реальности:
████████ ~ ♥️ 13:18 cd ~/myProject ████████ myProject ♥️ 13:19 sbx run claude Creating new sandbox 'claude-myProject'... a8531b2e5fc6: Download complete 0e4f92455740: Download complete c2407f5c2e01: Download complete 2417a2836e92: Download complete Digest: sha256:a8531b2e5fc6fea3a9bb88c598cde60b3b1a3ce50589fd3e7fb6c282735c31bc Status: Downloaded newer image for docker/sandbox-templates:claude-code-docker INFO: Started Docker daemon in 0.5s Starting claude agent in sandbox 'claude-myProject'... Workspace: C:\Users\████████\myProject ╭─── Claude Code v2.1.162 ─────────────────────────────────────────────────────────────────────────────╮ │ │ Tips for getting started │ │ Welcome back! │ Ask Claude to create a new app or clone a repository │ │ │ ──────────────────────────────────────────────────── │ │ ▐▛███▜▌ │ What's new │ │ ▝▜█████▛▘ │ Check the Claude Code changelog for updates │ │ ▘▘ ▝▝ │ │ │ │ │ │ Opus 4.8 (1M context) · API Usage Billing │ │ │ /c/Users/████████/myProject │ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────╯ ▎ Opus 4.8 is here! Now defaults to high effort · /effort xhigh for your hardest tasks ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── ❯ ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── ⏵⏵ bypass permissions on (shift+tab to cycle) · ← for agents Not logged in · Run /login

sbx run claude. Видно скриншот терминала с pull-выводом Docker образа и запущенным Claude codeОбраз агента подтягивается на первом запуске и дальше идет из кэша. Следующий старт укладывается в секунды две-три. sbx run работает и без аргументов: открывается интерактивный TUI picker для выбора агента и рабочей директории, удобно для первой пробы.

sbx без аргументов). Показывает карточки всех запущенных и остановленных sandbox с CPU, memory, портами плюс панель network governance с allowlist и логом обращений. Визуально демонстрирует, что sbx не голый CLIВ соседнем терминале можно открыть параллельную сессию:
$ sbx ls NAME AGENTSTATUS WORKSPACE claude-my-project claude running /Users/andrew/my-project $ sbx exec -ti claude-my-project bash agent@claude-my-project:~$ whoami agent agent@claude-my-project:~$ cat /etc/os-release | head -1 PRETTY_NAME="Ubuntu 25.10" agent@claude-my-project:~$ exit
Флаг -ti для sbx exec обязателен, если нужна интерактивная сессия. Без него shell стартует в неинтерактивном режиме.
Деталь для более полного понимания: sbx stop сохраняет состояние VM и можно выполнить команду sbx run claude-my-project и поднять с того же места, sbx rm удаляет microVM совсем. Рабочая директория на хосте не удаляется ни в одном из случаев. Где лежала, там и осталась. Sandbox живет именно между запусками, а не представляет собой контейнер на одну сессию.
Несколько вариантов запуска, которые я использую чаще всего:
sbx run claude ~/my-project # Явное указание рабочей директории sbx run claude . /path/to/docs:ro # Дополнительные read-only-директории sbx run claude -- --continue # Передача флагов агенту через -- sbx run claude --branch feature/x ~/my-project # Изолированный git-worktree под ветку [https://docs.docker.com/ai/sandboxes/usage/#branch-mode] sbx create claude ~/project # Создать sandbox без старта агента sbx run claude-my-project # Подключиться к существующему Sandbox sbx ports claude-my-project --publish 8080:3000 # Пробросить порт sandbox на хост
Пояснения по каждой неочевидной команде:
? -- --continue — всё после -- уходит агенту как есть. Без оберток и хитрых скриптов можно передавать любые CLI-флаги конкретного агента.
? --branch feature/x — создает git-worktree в .sbx/<sandbox>-worktrees/<branch> и изолирует работу агента от main [4]. Полезный прием, если не хочется давать ИИ-агенту трогать основную ветку.
? sbx ports — пробрасывает порт из sandbox на хост, когда агент собрал dev server или API. В этом случае сервис внутри sandbox должен слушать на 0.0.0.0, не на 127.0.0.1, иначе проброс не сработает.
За несколько месяцев работы накопилось несколько практических наблюдений, описания которых в документации нет.
Два агента в одном shell sandbox. Если переключаюсь между Claude и Codex в одном проекте, держу один shell sandbox (sbx run shell ~/my-project) и из него поочередно запускаю агентов локально внутри VM. Окружение не дублируется: npm-пакеты, Python venv, конфиги делятся на оба агента. В этом сценарии на хосте только одна microVM вместо двух — ресурсы экономятся, и проще синхронизировать скилы и инструкции между агентами. Подходит, когда хочется запустить разные агенты в одном проекте.
Git: read внутри sandbox, write с хоста. Принцип наименьших привилегий в чистом виде: агент внутри sandbox читает репозиторий, может смотреть разницу между коммитами и ветками, формулирует сообщение к коммиту, ставит изменения в индекс. Финальные git commit и git push я делаю с хоста, где лежат SSH- и GPG-ключи. Ключи внутри sandbox не нужны. Если агент случайно подменит коммит-хук или попытается переписать историю, инцидент останется внутри VM, репозиторий на удаленном сервере не пострадает. Один и тот же каталог .git/ в рабочей директории работает в двух разных контурах операций.
СРОЧНО В НОМЕР! Пока готовилась статья, Docker Sandbox научился подписывать коммиты ключами с хоста. Но в моем случае агент не делает коммит и пуш, поэтому для меня все остается по-старому.
«Залипший» sandbox. Один раз Claude Code отказался подхватывать новую модель, когда вышла версия Opus 4.7. Разбираться с состоянием VM было нерационально долго. Я попросил агент сложить плагины, скилы и важные конфиги в .backup/ в директории проекта. Это папка внутри рабочей директории, она доступна и на хосте, и в sandbox одновременно — изменения с одной стороны видны сразу с другой. Потом я сделал sbx rm claude-my-project, запустил sbx run claude заново, и агент сам, под моим чутким руководством, подтянул файлы из .backup/ обратно. Заняло несколько минут. Рабочая директория тут работает как мост между поколениями sandbox: никаких специальных команд для миграции данных не нужно, потому что директория доступна с обеих сторон.
Контейнеры живут между запусками, но хранить конфиги внутри sandbox (в ~/.claude/ внутри VM) все равно рискованно: такие файлы переживут sbx stop, но не переживут sbx rm. То, что должно сохраниться, кладется в репозиторий. Он остается доступен и на хосте.
Привычка, которая иногда встречается у пользователей и которую полезно отбросить, — класть все в один большой sandbox на все случаи жизни. Лучше держать гранулярность: отдельный sandbox под отдельный проект. Расход ресурсов на microVM не такой большой, чтобы экономить на изоляции, а импакт при инциденте сужается до пределов одного проекта.
Маленькая деталь в конце раздела: агент внутри sandbox может узнать, что он именно в sandbox. Спрашиваешь Claude Code, и агент честно отвечает, в каком окружении он сейчас живет, и это помогает. Например, агент может напрямую запросить у пользователя выдать разрешение на доступ к определенному домену, понимая, что он в sandbox с сетевыми политиками, вместо того чтобы часами долбиться в стену и искать причину отсутствия доступа по сети.
Запуск агента уложился в одну команду. Какие обращения он отправит во внешнюю сеть?
Сетевые политики
В sbx есть три пресета сетевой политики, и при первом sbx login CLI заставляет выбрать один пресет: по умолчанию опции «из коробки» нет [4].
Open. Весь исходящий трафик HTTP/HTTPS разрешен. Подходит для прототипа или быстрой разработки, когда стоимость ошибки маленькая.
Balanced. Deny by default плюс allowlist популярных ресурсов: пакетные реестры (npm, PyPI), GitHub, основные CDN, API крупных провайдеров моделей. Точный список не привожу: он эволюционирует. За актуальной выкладкой следите в документации Docker [6]. Это стартовая точка для повседневной деятельности, и документация Docker рекомендует начать с режима Balanced.
Locked Down. Заблокировано все, кроме явно разрешенного. Применимо в подозрительных сценариях, например при анализе малвари, или в случаях, когда есть явно недоверенный код: там лишний исходящий трафик нежелателен сам по себе.
Базовые команды управления политикой:
sbx policy set-default balanced # Пресет по умолчанию sbx policy allow network -g api.anthropic.com # Разрешить домен sbx policy allow network -g "*.npmjs.org,*.pypi.org" # Несколько доменов sbx policy deny network -g ads.tracking.com # Запретить домен sbx policy ls # Активные правила sbx policy rm network -g --resource ads.tracking.com # Снять правило sbx policy reset # Сбросить и переспросить sbx policy log # Лог запросов прокси (все sandbox) sbx policy log my-sandbox # Лог одного конкретного sbx policy log --json # Машиночитаемый вывод sbx policy log --limit 50 # Последние 50 записей
Флаг -g делает правило глобальным для всех ваших sandbox. Если его не указать, политика привязывается к конкретному sandbox по имени. Например, sbx policy allow network my-sandbox api.example.com разрешит доступ только из my-sandbox. В примерах ниже я везде использую -g, потому что собираю общий профиль доступа на машину, но можно и точечный.
Несколько свойств, на которых я успел споткнуться или которые мне пригодились [6]:
Wildcard поддерживается.
*.npmjs.orgпокрывает все поддомены, включаяregistry.npmjs.org, cdn.npmjs.org.Deny beats allow. Если домен подпадает под оба правила, побеждает запрет. Это удобно для точечного отключения: добавляешь общий wildcard-allow на корпоративный домен и точечный deny на ad-домен поверх.
HTTP/HTTPS only.
sbx policy allowвлияет только на HTTP/HTTPS-домены. Другой TCP-трафик можно разрешить, прямо указав адрес и порт [5][6]. UDP- и ICMP-трафик заблокирован на уровне сети и не может быть разблокирован сетевыми политиками. Это намеренное архитектурное свойство, и именно оно закрывает DNS-туннелирование, описанное в предыдущей статье, — в случае если на вашем DNS-сервере в инфраструктуре настроена фильтрация по доменам… Ведь настроена? Да?Трафик на локальные адреса и в частные сети блокируется и требует от пользователя целенаправленного разрешения в политиках. Зачем? Потому что бывает и такое.
За два месяца активного использования я сделал несколько практических наблюдений.
По умолчанию у меня установлен режим Balanced или Open. Пресет Locked Down включаю отдельно, под конкретную задачу, когда исходящий трафик нежелателен сам по себе и проще выставить «Все запрещено», а потом точечно разрешить только то, что понадобится для конкретных действий. Для рабочих проектов Balanced дает нужный список разрешенных доменов «из коробки» без раздельной настройки под каждый репозиторий.
Агенты конструктивно реагируют на блокировку. Claude, упершись в закрытый домен, не уходит в retry loop и не пытается обойти политику. Он возвращается к пользователю с сообщением вида: «Для этого шага нужен доступ к api.example.com, разрешишь?». Решение о расширении доверенного списка принимаю я, не агент. Это и есть human in the loop, ради которого выстраивается изоляция: контроль над тем, куда агент дотягивается, остается на пользователе, а не растекается по спискам доступа и базовых политик.
Логи прокси информативные. В них видно, что запрошено, что пропущено по доверенному списку, что заблокировано: домен, время и sandbox, из которого пришел запрос. Это бесплатный аудит сетевой активности агента: не нужно отдельно настраивать tcpdump или подключать SIEM-систему, чтобы увидеть, что Claude хотел сходить в api.openai.com, а вы его туда не пускали.

sbx policy log с двумя секциями (Blocked requests / Allowed requests), таблицей. Визуальный пример «бесплатного аудита».Попыток «выйти» из sandbox не было. За два месяца работы ни разу не видел в логах попытки агента дотянуться до запрещенного домена самостоятельно: все блокировки были по легитимным запросам, которым в моей политике не нашлось разрешения. Это слабая выборка для статистики, но как ориентир она успокаивает: базовые установки Balanced не создают постоянного фона ложноположительных алертов.
И еще один практический штрих про режим Locked Down. Когда я запускаю недоверенный код, то ставлю sandbox в Locked Down и явно разрешаю один-два домена для конкретной задачи (например, *.virustotal.com для проверки хешей). Любая попытка достучаться изнутри sandbox куда-то еще видна в логах и блокируется на уровне сети, а не на уровне правил детекта. Это не полное лабораторное окружение, и не рекомендуется так делать, хотя этот подход и лучше, чем просто открыть подозрительный архив на хосте без изоляции.
С исходящим трафиком разобрались. Но прежде чем разбирать ключи, которые агент будет подкладывать в такой трафик, остановлюсь на решении Docker для организации, а потом перейду к одной поведенческой детали, которая в sandbox работает иначе, чем на голом хосте.
Управление политиками безопасности песочниц на уровне организации
Это платный продукт. На момент написания у Docker есть Docker AI Governance — отдельная подписка, через которую администратор задает сетевые и файловые политики напрямую из консоли администратора. Эти правила имеют приоритет над локальными sbx policy на машине разработчика. Администратор получает централизованный допуск, возможность запретить определенные домены (для всех sandbox организации одновременно), возможность управлять тем, какие пути на хосте разработчикам разрешено монтировать как рабочие директории (нельзя смонтировать /etc или ~/.ssh в sandbox, если админ так настроил), и опциональную делегацию: админ может позволить разработчикам добавлять дополнительные allow-правила локально, но не снимать его запрет.
Это решает классическую корпоративную задачу: «У меня в инфраструктуре сто разработчиков, и я хочу, чтобы никто из них не мог сам разрешить sandbox ходить в любой произвольный домен или смонтировать чувствительный путь к рабочей директории».
Соседние enterprise-инструменты Docker, которые работают в том же сегменте Docker Business, но решают другие задачи:
Hardened Docker Desktop с Enhanced Container Isolation — ECI запускает контейнеры в Linux user namespaces, это защита самого Docker Desktop от эскалации привилегий (неспецифично для sbx);
Settings Management — с помощью него админ навязывает конфигурацию Docker Desktop всем разработчикам (через JSON-файл или Admin Console);
Registry Access Management — для централизованного контроля доступа к реестрам образов;
Image Access Management — для контроля того, какие образы из Docker Hub можно скачивать.
Docker AI Governance — AI/sbx-специфичная часть стека, не интегрированная с остальными в единый продукт и живущая в отдельной подписке, но адресующая ту же enterprise-картину: безопасное использование Docker и его агентов в организации [10]. На обычной подписке Personal, Pro, Team или Business этой возможности нет: политика sbx остается локальной для каждой машины, и для enterprise-кейса есть только внешние механизмы: governance-процессы и MDM, policy push на установку. Ниша локального аудита и контроля действий ИИ-агента — отдельный разговор, к которому мы еще вернемся за рамками этой статьи.
--dangerously-skip-permissions
У многих агентов есть флаг вида --dangerously-skip-permissions (или --yolo, в зависимости от агента), который отключает необходимость подтверждения каждого действия у пользователя. На голом хосте такая опция выглядит как минимум подозрительно. Имя флага не зря содержит слово dangerously: за ним стоит реальный риск — агент запускает все что угодно, не спрашивая. При негативном сценарии вы сможете только наблюдать, как агент быстро и по кусочкам аннигилирует вашу систему.
Внутри sandbox этот флаг включен по умолчанию у большинства поддерживаемых агентов, и Docker в FAQ обосновывает это прямо: радиус поражения уже определен архитектурой. Сам sandbox — это и есть граница безопасности. Поскольку агенты крутятся в изолированной microVM с сетевыми политиками, с изоляцией секретов и без доступа к хосту за пределами рабочей директории, обычные причины запрашивать подтверждение каждой команды (защита от деструктивных действий, контроль сетевых обращений, ограничение модификации файлов) уже закрыты слоями изоляции [9].
На практике это снимает с меня целый пласт задач, связанных с микроконтролем, которые раньше съедали ощутимое время. Без sandbox каждое npm install, cargo build, перемещение файла или sed-замена в большом проекте либо подтверждается вручную, либо вызывает тревогу: «А вдруг агент сейчас сделает что-нибудь не то?». Внутри sandbox этой тревоги нет: если ошибется, ошибка ограничена пределами VM, рабочая директория восстанавливается из Git, sandbox пересоздается командой sbx rm + sbx run. Я могу держать несколько агентов параллельно на разных проектах и не отвлекаться на согласование каждого действия.
Одно исключение, о котором стоит помнить. Если вы запускаете агент через shell sandbox (то есть выполняя команду sbx run shell ~/my-project), а потом внутри руками поднимаете, например, claude, то в таком случае флаг --dangerously-skip-permissions нужно указать явно: shell sandbox не знает, какой агент в нем живет, и мод YOLO по умолчанию не включается.
Теперь — к ключам, которые агент будет подкладывать в исходящие запросы.
Секреты
Чаще всего API-ключ передается напрямую в API-запросе через ANTHROPIC_API_KEY=... в окружении агента, однако этот способ устарел. Проблема в том, что переменная окружения внутри VM доступна любому процессу, в том числе запущенному вредоносным пакетом, который агент только что подтянул. sbx решает эту задачу через прокси на стороне хоста [7][8]:
Хост хранит учетные данные через
sbx secret set.При запросе, например, к
api.anthropic.comпрокси перехватывает HTTP-вызов.Прокси добавляет
Authorization: Bearer sk-ant-...в заголовки.Агент внутри VM получает только ответ API. Реальное значение ключа в VM не попадает.
sbx secret set anthropic # CLI запросит значение ключа с маской ввода sbx secret set github # GitHub PAT, npm token и т. п. sbx secret ls # Список без значений sbx secret rm anthropic # Удалить
Секреты можно ставить глобально или для конкретного sandbox.
Важно учитывать ограничение sbx secret: команда работает с фиксированным набором провайдеров (Anthropic, OpenAI, GitHub и другими). Для кастомных переменных окружения вроде BRAVE_API_KEY или внутреннего корпоративного токена путь идет через /etc/sandbox-persistent.sh внутри sandbox: это shell script, который sbx подгружает при каждом входе в Bash внутри sandbox. Переменные оттуда становятся доступны интерактивным сессиям и агентам, запущенным через sbx run [9]. Один нюанс: если вы вызываете команду напрямую через sbx exec <name> <command>, sbx запускает ее без shell — и файл /etc/sandbox-persistent.sh не подхватывается. В этих случаях оборачивайте команду в bash -c "...", чтобы окружение подгрузилось [9].
Лично я sbx secret не использовал: с Claude Code авторизация идет через webflow, сессия обновляется в необходимых интервалах, и отдельный токен в локальном хранилище мне не нужен. Когда я буду работать с провайдерами, требующими открытого API-ключа внутри запроса, сценарий поменяется, но пока такого не было.
Сокрытие секретов — лишь частный случай. Возвращаюсь к шести классам угроз из первой статьи цикла: что из них изоляция реально закрывает?
Что закрывает изоляция
Привязываю каждый класс к sbx. Это оценка из опыта — лабораторной точности здесь ждать не стоит. В следующей части серии сделаю полный разбор, сравню следующие сценариев: агент на хосте, агент в контейнере, агент в Docker Sandbox, и расскажу про воспроизводимые эксперименты, которые можно будет повторить у себя.
Класс угрозы из первой части статьи |
Закрывает ли ее sbx |
Почему |
Случайный |
✅ Полностью |
Файловая система вне рабочей директории недоступна |
Промпт-инъекция |
❌ Нет |
Модель получит ту же инструкцию, sbx ограничивает только blast radius |
Малварь, использующая агент |
⚠️ Частично |
Вредонос крутится в microVM, до хост-секретов не дотянется |
Атака на цепочку поставок через агент |
⚠️ Частично |
Зависимость отравлена, но не выходит за периметр sandbox |
Кража токенов |
⚠️ Частично |
Хост-секреты закрыты, секреты в рабочей директории — нет |
Компрометация CI/CD |
⚠️ Частично |
Если CI-токен попал в sandbox, то он доступен изнутри. Sandbox — не магия |
Один ✅, один ❌, и четыре ⚠️. Это и есть центральный тезис статьи: sbx помогает снизить радиус потенциального поражения, а не предлагает универсальное решение. Он действительно делает невозможным случайный rm. Ту часть промпт-инъекции, которую обрабатывает LLM, он принципиально не закрывает: это происходит на уровне модели и приема данных. Все остальное нужно для ограничения последствий, а не для предотвращения события.
«Частично» дает драматическую разницу между сценарием без изоляции и с sbx. Для большинства угроз, описанных в первой статье цикла, разница между «Без изоляции» и «Использование через sbx» сводится к разнице между «Хост скомпрометирован» и «Sandbox скомпрометирован, хост целый». В первом случае атакующий получает рабочую станцию разработчика с SSH-ключами, токенами и доступом к корпоративной VPN; во втором — изолированный sandbox размером в один проект, без хост-секретов, с мониторингом исходящего канала и без Docker-демона хоста. Для большинства моделей угроз этого хватает, чтобы переместить инцидент на уровень ниже.
В следующей статье цикла я планирую поставить вопрос иначе: не «закрывает или нет», а «насколько именно сужается радиус поражения относительно запуска на хосте без песочницы и обычного контейнера и какие сценарии все равно проходят насквозь». Для этого нужны эксперименты: DNS-туннелирование при разных пресетах, тестирование поведения под Locked Down, попытки доступа к сетевым ресурсам разной степени подозрительности и т. п. Всему этому место в отдельном материале.
Куда дальше
На этом я закончил с базовыми настройками и основными рычагами управления защитой. За несколько месяцев использования sbx заменил мне отдельные виртуальные машины, которые я раньше держал под ИИ-агенты: он стартует быстрее, ставится проще и при этом дает аналогичную изоляцию.
Если резюмировать, базовый путь выглядит так: вы ставите sbx из своего пакетного менеджера (команды для macOS, Windows и Linux я приводил выше, в разделе «Установка»), делаете sbx login, на начальном этапе выбираете пресет Balanced, дальше в проектной директории запускаете sbx run claude или <Имя вашего агента>. Агент работает в изолированной microVM с сетью в режиме доступа только к разрешенным ресурсам и MITM-прокси на стороне хоста для секретов. Хост при этом остается в большей безопасности, чем при запуске агента на нем. Сам переход занимает несколько минут. После него для пяти из шести классов угроз из моей предыдущей статьи потенциальный импакт сужается до периметра sandbox VM. Реализацию шестой угрозы, промпт-инъекции, изоляция не предотвращает. Инъекция приходит в модель, как и раньше, однако то, что скомпрометированный агент способен сделать далее, ограничено.
Одна честная оговорка: sbx — продукт в фазе активной эволюции. Пока я писал эту статью, каталог поддерживаемых агентов sbx вырос с восьми до десяти. Добавились:
Cursor — CLI-режим Сursor называется agent (не IDE Cursor с GUI), запускающийся в моде YOLO по умолчанию;
Droid — AI-агент Factory (требуется Factory-аккаунт), которого в изначальной версии не было.
За те месяцы, которые прошли между моими первыми проверками (Docker Sandbox в феврале, sbx — в апреле) и моментом, когда вы это читаете, у Docker неоднократно менялись набор поддерживаемых агентов, синтаксис отдельных команд и статус параллельной имплементации в Docker Desktop. Архитектура и принципы, о которых я пишу (microVM, прокси на стороне хоста, deny by default), стабильны и переживут текущий цикл переименований. Меняется набор CLI-флагов и эргономика команд — это вопрос пользовательского опыта, а не модели изоляции. Конкретные имена команд, флагов и подкоманд сверяйте с актуальной docs.docker.com перед запуском.
Заметка про устаревшую имплементацию: у docker sandbox в Docker Desktop был флаг
--bypass-host, который выводил конкретные домены из MITM-инспекции прокси. В начале 2026 года этим флагом я чинил странное поведение Codex в связке с docker sandbox: Codex обнаруживал атаку и отказывался отправлять запросы через MITM-прокси, пока docker sandbox не был запущен с командой --bypass-host *.openai.com. Поведение касалось конкретной устаревшей имплементации, к sbx как продукту оно отношения не имеет. В актуальном sbx эквивалентного флага я не нашел. Воспроизвести ситуацию в рамках статьи не успел. Если столкнетесь с похожим — пишите в комментариях, разберемся вместе.
Статья посвящена рабочему сценарию — применению агента в sandbox для проекта. Но sbx можно использовать и для персонального ассистента с доступом к личным данным (к документам, заметкам, почте) через локальную интеграцию. Например, OpenClaw (в первой статье, в разделе «Кража данных и токенов», я разбирал инцидент, в котором конфиги OpenClaw стали целью инфостилер-кампании). Сценарий с персональным ассистентом требует иной конфигурации образа: другого набора инструментов, политик сети, другой модели доверия к рабочей директории.
Docker Sandbox позволяет собирать кастомные образы. Желающих поупражняться приглашаю в комментарии и предлагаю составить конфиг для личного ассистента (желательно с аргументацией, почему так, а не иначе).
За кадром остались три вопроса:
Как именно работает гипервизор-изоляция изнутри?
В ходе каких экспериментов можно определить реальные границы защиты?
Как собрать кастомный образ под конкретный сценарий?
Это материал для следующей части серии. Если тема зайдет и в комментариях будет интерес, соберу третью часть.
Источники
На этом пока всё!
Если хотите больше такого, заходите в мой Telegram-канал, который я веду совместно с замечательными людьми. Там авторское мнение по теме ИИ и кибербеза, мемы из частной коллекции и многое другое. Буду рад!
Комментарии (35)

Anton-Sergeevich
24.06.2026 15:59Та же тревожность, только в профиль: когда проектируешь CI/CD для Telegram-ботов, токены ботов, ключи от продакшн-баз и секреты вебхуков часто лежат в переменных окружения или в
.env, и агент, запущенный от моего пользователя, видит их все. Хуже того, боты по своей природе открыты внешнему миру — любой пользователь может прислать сообщение, которое через лог попадёт в контекст агента, и это уже не гипотетическая промпт-инъекция, а рабочий вектор.Я пришёл к тому же: изолировать среду. Но вместо полноценных виртуалок пока использую контейнеры с read-only-маунтами и прокидываю только нужную директорию. Это не серебряная пуля, но хотя бы ограничивает радиус взрыва. А какой инструмент вы в итоге нашли и насколько он зашёл в боевых сценариях? Потому что проблема «агент видит всё, что вижу я» до сих пор держит меня от того, чтобы дать агенту SSH-доступ на продакшн, и я почти перестал спать.

Andrew42 Автор
24.06.2026 15:59Для меня отлично подошел вариант с изоляцией через sbx, в частности, ключи можно держать снаружи песочницы за счет sbx secret и агент не будет видеть никакие секреты

Andrew42 Автор
24.06.2026 15:59Upd
"никакие" звучит слишком радикально, стоило сформулировать мягче, "не будет видеть секреты, добавленные в sbx secret"

Sap_ru
24.06.2026 15:59Несовсем понял, как именно изолировать секреты. Ну, токены, которые sbx поддерживает, понятно. А как именно помогает /etc/sandbox-persistent.sh ? Он же ничего толком не изолирует.
Ну, и вообще остаётсся вопрос изоляции ключей и секретов.
Andrew42 Автор
24.06.2026 15:59Все так и докер прямо указывает это в документации. sbx secret позволяет хранить набор ключей для ограниченного числа поддерживаемых сервисов

powerman
24.06.2026 15:59У подхода Docker Sandbox есть серьёзный недостаток в плане безопасности: из такой песочницы элементарно сбежать на хост. Поскольку рабочий каталог с проектом шарится с хостом, то агент может подложить в каталог проекта малозаметные файлы, которые приведут к выполнению кода на хосте: git hooks,
.mise.local.toml, direnv, etc. - есть тьма инструментов, которые "для удобства" выполняют код из файлов проекта, и зачастую изменения в таких файлахgit diffне показывает. Так что идея делать git commit/push на хосте - это как раз уязвимость (из-за хуков), а не усиление безопасности.На мой взгляд категорически неприемлемо шарить каталог проекта с агентом. Агент должен работать как отдельный сотрудник, с собственным клоном репо проекта, в собственном домашнем каталоге, имея доступ только к разрешённым для него секретам. И обмениваться с ним кодом можно только через git push/pull - это исключает атаки через все вышеупомянутые "невидимые" файлы.
Ещё один важный нюанс: если не вайб-кодить, то не получится ограничиться работой только внутри
claude- изменения нужно ревьювить, допиливать, а для этого нужно иметь доступ к уже настроенному и удобному окружения хоста (IDE с кучей утилит и их конфигов).В результате, более правильный подход к безопасной работе с агентами, на мой взгляд, совершенно противоположный подходу Docker Sandbox/Dev Container/виртуалок: с изолированной средой нужно шарить не каталог проекта, а настроенное окружение хоста (рабочие инструменты).
Пример реализации этого подхода (даже два варианта - один на базе
ssh ai-dev@localhostа второй на базе linux namespaces) я выложил в https://github.com/powerman/sandbox-ai-dev. К сожалению, утилиту для упрощения установки я пока не реализовал, плюс поддерживается только Linux (впрочем, вариант на базе ssh в теории можно адаптировать для macOS).
Andrew42 Автор
24.06.2026 15:59Приятно видеть комментарий, реализующий альтернативный подход.
Насчет малозаметных файлов тейк понятный, сам об этом думал, но решил, что граница между безопасностью и комфортом для меня пролегает в первую очередь по непреднамеренным деструктивным действиям агента. Меня в первую очередь пугает неожиданное изменение системных файлов или пресловутый rm rf, а sandbox для этого подходит идеально.Кстати, замечательная идея насчет клона репо, пока писал статью, завезли новое, что в обзор не попало. Dokcer sbx стал из коробки поддерживать Clone mode, насколько это близко вашему подходу и реализации?
Что касается настроенной IDE хоста, улавливаю некое противоречие, наличие отдельной копии для агента неизбежно ухудшает скорость синхронизации, в случае с подключение по SSH к среде разработки в локальной песочнице да, этот момент решается, хоть и сложнее настраивать окружение.
А вот насчет шарить окружение категорически не согласен, все переменные окружение, доступные агенту, потенциально под угрозой.
Расскажите, а как у вас дела с Docker контейнерами? Доступно ли внутри песочницы изолированное ядро для запуска контейнеров?

powerman
24.06.2026 15:59Меня в первую очередь пугает неожиданное изменение системных файлов или пресловутый rm rf
У меня в репо в README выложен rationale и модель угроз, почитайте, возможно передумаете. Если вкратце, то на сегодня в принципе нет защиты от атак prompt injection и supply chain - нет и даже не предвидится. Это значит что любой агент в любой момент становится вредоносным. Учитывая отсутствие защиты и популярность этой темы (выраженную например в проценте вредоносных навыков для openclaw - я видел цифры порядка 60% если не путаю) полагаться на то, что это не случится лично с нами - довольно наивно. Поэтому, на мой взгляд, Вы не того опасаетесь.
Clone mode, насколько это близко вашему подходу и реализации?
В плане того, чтобы не шарить с агентом рабочий каталог - да, по описанию очень похоже. Упомянутую мной дырищу это должно закрыть, так что рекомендую его использовать. А вот удобство работы в отдельной VM всегда будет сильно хуже, чем в привычной среде на хосте - и моё решение умудряется совместить безопасность и это удобство, чем и уникально. :)
Что касается настроенной IDE хоста, улавливаю некое противоречие, наличие отдельной копии для агента неизбежно ухудшает скорость синхронизации, в случае с подключение по SSH к среде разработки в локальной песочнице да, этот момент решается, хоть и сложнее настраивать окружение.
У меня там два варианта. На базе Linux namespaces синхронизация обеспечивается через ro bind-mount этих конфигов, что моментально. На базе ssh на localhost синхронизация пока сделана через rsync при запуске, в целом работает прекрасно, но есть и другие варианты на будущее. Но синхронизация конфигов это половина дела, ещё нужно открывать ссылки в браузере хоста, сохранять look&feel DE хоста для GUI приложений, показывать десктопные уведомления на хосте, проигрывать звуковые уведомления, etc. В целом у меня всё получилось - работа в песочнице никак не ощущается отличной от работы на хосте в плане UX.
А вот насчет шарить окружение категорически не согласен, все переменные окружение, доступные агенту, потенциально под угрозой.
Я под окружением имел в виду утилиты и их конфиги, начиная с zsh и заканчивая VS Code, а вовсе не переменные окружения.
К слову говоря, у меня там довольно сильно проработана защита от случайных утечек секретов - grep/ps/env никаких секретов никогда не возвращают. Специально, конечно, все доступные агенту секреты получить можно без проблем запустив secret-tool - но тут уже срабатывает фактор что все доступные агенту секреты были созданы специально для него, так что никакого "лишнего" доступа они не дадут.
Расскажите, а как у вас дела с Docker контейнерами? Доступно ли внутри песочницы изолированное ядро для запуска контейнеров?
Докер доступен, но ядро ОС общее - защита от эксплойта ядра автоматом требует (micro)VM, а VM автоматом убивает UX, так что я сделал выбор в пользу UX.
При использовании варианта ssh используется rootless docker под юзером ai-dev, в варианте на namespaces запускается rootful docker но внутри того же userns что и вся песочница, так что получение там рута никаких дополнительных прав снаружи песочницы не даёт.

Andrew42 Автор
24.06.2026 15:59А вот удобство работы в отдельной VM всегда будет сильно хуже, чем в привычной среде на хосте - и моё решение умудряется совместить безопасность и это удобство, чем и уникально
Насчет совмещения плюсов во многом соглашусь. За исключением отсутствия отдельного ядра внутри.
У меня там два варианта. На базе Linux namespaces синхронизация обеспечивается через ro bind-mount этих конфигов, что моментально.
Расскажите, пожалуйста, подробнее или укажите место в репозитории, где посмотреть. Видимо, не все верно понял, но пока кажется, что и скрытые от гита файлы, которые обсуждали парой сообщений выше, должны синхронизироваться.
На мой взгляд категорически неприемлемо шарить каталог проекта с агентом. Агент должен работать как отдельный сотрудник, с собственным клоном репо проекта, в собственном домашнем каталоге, имея доступ только к разрешённым для него секретам.
Разделяю этот подход, хоть у нас и немного разошлись взгляды на шеринг рабочих директорий.
Сильно за рассматривать агента как отдельного актора, что подразумевает, в том числе, выдачу ему персонализированных учетных данных.
У меня там два варианта. На базе Linux namespaces синхронизация обеспечивается через ro bind-mount этих конфигов, что моментально. На базе ssh на localhost синхронизация пока сделана через rsync при запуске, в целом работает прекрасно, но есть и другие варианты на будущее. Но синхронизация конфигов это половина дела, ещё нужно открывать ссылки в браузере хоста, сохранять look&feel DE хоста для GUI приложений, показывать десктопные уведомления на хосте, проигрывать звуковые уведомления, etc. В целом у меня всё получилось - работа в песочнице никак не ощущается отличной от работы на хосте в плане UX.
Очевидное пустое поле для sbx это агентные IDE, в том числе Cursor. Нет из коробки варианта запуска Cursor IDE в песочнице так, чтобы агент шарил ручками в песочнице, а GUI был доступен пользователю через хост без задержек. Смотрели ли в эту сторону?
Ps насчет Readme пока не успеваю ознакомиться, вернусь позже
powerman
24.06.2026 15:59Видимо, не все верно понял, но пока кажется, что и скрытые от гита файлы, которые обсуждали парой сообщений выше, должны синхронизироваться.
Синхронизируются конфиги вроде
~/.bashrcи~/.config/git/. Пример списка в репо тут. Каталог с проектами/репо у агента полностью собственный, в нём не синхронизируется ничего, только через git push/pull.Смотрели ли в эту сторону?
А что туда смотреть, у меня это всё штатно работает. Я же говорю, по UX работа в песочнице ничем от работы на хосте не отличается. У меня в песочнице открыто несколько терминалов, можно прямо в них запускать GUI приложения вроде VS Code/Cursor и они штатно работают прямо на Wayland хоста, видят в прокинутых конфигах текущую тему DE, имеют доступ к /etc и /usr хоста, etc. Можно запускать их не в терминалах а хоть прямо из менюшки DE - только нужно вызов нужного приложения обернуть через скрипт sandbox-а (примерно в том же духе, как работает firejail etc.).

Andrew42 Автор
24.06.2026 15:59Пока вы рассказываете довольно интересно, посмотрю, и, если интересен отзыв, вернусь в течение пару недель

Rubiorif
24.06.2026 15:59Просто не давай агенту писать в .git и проблемы с невидимыми скриптами отвалятся сами собой

Andrew42 Автор
24.06.2026 15:59Задумался о технической реализации этого. Предполагаем что агентам не верим и что просто промпта нам недостаточно. Хуки? Отобрать у пользователя, запускающего агента, права на запись в директорию?

powerman
24.06.2026 15:59Агент, который имеет возможность изменять код и запускать тесты - имеет возможность делать абсолютно что угодно (просто добавив временный код в тест и запустив тесты разрешённой командой). А агент который таких возможностей не имеет - бесполезен. Поэтому единственный рабочий способ что-либо агенту запретить - запустить его в песочнице/виртуалке где запрещённое действие выполнить не может никто, включая Вас.

vatosarmat2
24.06.2026 15:59Спасибо за статью! Похоже, контейнер\виртуалка с --dangerously-skip-permissions - самый оптимальный способ работы с Claude, и настоящие профессионалы обычно работают именно так. Использовать Claude в виде VSCode расширения не очень удобно: он постоянно спрашивает разрешение на использование Bash-тула для чтения файлов проекта, и даже если добавить в permissions все команды для чтения(типа find, cat, head, tail, cd и т.п.), то скрипты, которые он генерирует, все равно их не проходят, потому что он почти к каждой команде добавляет что-нибудь вроде >/dev/null, и это типа считается записью в файл, требующей ручного аппрува. Если же установить Claude с NPM и запустить в терминале VSCode, то становится доступен режим /sandbox, но и он полностью не решает проблему: редиректы в /dev/null теперь проходят, но ручной аппрув все еще требуется если скрипт объявляет переменную и она expanded в ходе его выполнения(Contains simple_expansion. Do you want to proceed?).

Andrew42 Автор
24.06.2026 15:59Для ускорения да, это неочевидный плюс изоляции, но это действительно так, когда понятен потенциальный убыток, легко отпустить агент в свободное плавание. Нередко запускаю несколько агентов параллельно для разных проектов.

evgeny_boger
24.06.2026 15:59Docker Sandbox - это ж проприетарная штука, исходников нет, хочет аккаунт на докер.ком для работы.
Пользуясь случаем, порекламирую свой https://github.com/wirenboard/agent-vm
эфемерная микровм, стартует за две секунды, монтируют текущую директорию и всё
внутри сразу нормальный дебиан (ну или чего хотите, там OCI image)
докер внутри можно запускать
умеет публиковать порты на локалхосте сама, как wsl/lima
фильтрует гитхаб, доступ только к заданным репозиториям, реквизитов внутри нету
прокидывает аутентификацию клода, кодекса и всего остального нормально, т.е. через поддельный OAuth
умеет весь трафик vm заворачивать в системный прокси
cd "моя директория" && npx @wirenboard/agent-vm claude

Andrew42 Автор
24.06.2026 15:59Вы описали сейчас Docker sbx по функционалу и это звучит здорово. Круто, что опенсорс;
А есть возможность настроить не системный, а просто прокси снаружи VM? Например, через локальный докер контейнер
И аналогичный вопрос, как и комментатору выше, что насчет Cursor с интерфейсом?

Sap_ru
24.06.2026 15:59Я игрался с подобными конфигурация на виртуалке и выснилось, что в тяжёлых окружениях возникакет проблема с ообъёмом памяти. Выделяемая виртуалке память не возвращается системе пока виртуалка работает. В результате, чтобы быстро работали тяжёлые среды нужно выделять реального много памяти с основного хоста, но тогда основной хост начинает тормозить! А если виртуалок запущено несколько, то все становится совсем плохо, даже если они не исполняют тяжёлые задачи одновременно.
С контейнерами такой проблемы нет так как память общая, и если тяжёлые задачи исполняются последовательно, то всё работает быстро. Плюс у контейнеров файловый кэш общий, что на больших проектах прямо очень сильно ускоряет работу.
Andrew42 Автор
24.06.2026 15:59А можете, пожалуйста, поделиться кейсами, что за тяжелое окружение? Возможно, всем вместе интересно будет подумать над решением

Sap_ru
24.06.2026 15:59На C++ / Qt, прямо очень заметно. Там чем больше памяти, тем лучше. И файловый кэш там тоже рулит даже на очень быстрых дисках.
Но и на большом и сложном проекте Java+JavaFx было заметно при полной пересборке.
А что там думать? Это принципиальное ограничение. Возвращать (больше) неиспользуемую память из виртуальных машин и выделять больше на ходу больше, при необходимости, только VmWare может, на сколько я знаю. С остальными можно только поиграться с файлами подкачки, но так себе путь.

evgeny_boger
24.06.2026 15:59Выделяемая виртуалке память не возвращается системе пока виртуалка работает
так вроде возвращается без всяких проблем. По крайней мере через libkrun

Sap_ru
24.06.2026 15:59Да, теоритически, через virtio-balloon, если оно на KVM. Но когда я попытался это в реальности использовать... Там такой шаманизм и столько ограничений, что это просто не работает.
Там нужен Guest Agent на витруалке. Это агент должен работать и должен быть настроен. Но даже если всё правильно сделать, то памzть не освобождается, так как d Linux она совршенноо всегда и полностью занята файловым кэшем! То есть нужно принудительно кэш сбрасывать. Это уже отдельное шаманств, и это плохо для производительности. Но есть ещё и засада в том, что дальше в зависимости от настроек кэш либо не растёт и виртуалка начинает работать медленне (а на фига мы ей память выделали тогда?), или кэш пытатся разрастись и отобрать память у хоста обратно. И поверх этого ещё и виртуальная память работает и всякие эффекты даёт.
kenomimi
Заведение отдельной виртуалки с чистым окружением (без посторонних и продовых секретов) будет лучшим вариантом. После полной заливки делаем снапшот, и дальше пусть разносит ее сколько хочет - код в гитлабе, отдельные папки в бекапе, а остальное восстанавливается из снепшота. И агент не должен иметь доступа к проду, вообще - он коммитит, а дальше мы ручками проливаем на прод с другой машины или из гитлаба.
Из докера пускать тоже вариант, но он намного более сложный, неудобный и хрупкий.
Andrew42 Автор
Вы отлично описали два полярных подхода, но полноценные виртуальные машины для меня заметно снижали комфорт использования, в статье как раз описан промежуточный вариант, удобно как в докере, надежно, как в виртуалке.
Sap_ru
Но нужно будет прикрутить своий прокси с политиками, настроить firewall (достаточно неочевидным образом, так как он должен работать поверх виртуалки), настроить иньекцию стокенов (тоже нетривиально), настроить доступ к дискам, каким-то образом всё это мониторить.
Да,ну на фиг такое счастье!
Andrew42 Автор
Вы имеете в виду выстраивание изоляции и инъекции секретов своими руками?
Rubiorif
Так в этом и суть инструмента, он сам все проксирует и настраивает под капотом
Sap_ru
Он дже добавляет секреты тольков очень ограниченный набор сервисов, разве нет?
Andrew42 Автор
Все верно, из коробки поддерживается MITM-инъекция для ограниченного набора сервисов, однако, рабочий MITM прокси, который будет поддерживать абсолютно все сервисы, это прям большая головная боль. Как обсуждали ниже, частично это решается выдачей прав агенту с ограниченным доступом.
Rubiorif
Полноценная виртуалка жрет слишком много ресурсов и времени на старт
Andrew42 Автор
Еще отдельная боль для меня была монтирование директорий, не все всегда все видит