SSD Nodes Learn 🎉 VPS от $5.50/мес
Руководства Matt ConnorАвтор: Matt Connor · Обновлено 2026-08-13

FreeBSD jails или Docker: в чем ключевая разница

Разбираем фундаментальные отличия технологий изоляции. Узнайте, почему FreeBSD jails запускают полноценную ОС, а Docker использует слоистые образы и один процесс.

Сравнение FreeBSD jails и Docker containers в одном абзаце

FreeBSD jails и Docker containers решают одну и ту же задачу, используя разные подходы. Оба решения запускают изолированные пользовательские окружения на одном общем ядре, поэтому ни одно из них не является виртуальной машиной. Разница заключается в наполнении. Docker container запускает один процесс из слоистого образа, загруженного из реестра. Jail запускает полноценное пользовательское окружение FreeBSD: собственную /etc, свои скрипты автозагрузки rc, собственную базу данных pkg и любое количество процессов. Почти все остальные различия, описанные на этой странице, вытекают из этого фундаментального отличия.

SSD Nodes не предоставляет образы FreeBSD. Вы не можете арендовать сервер с FreeBSD на этой платформе, и нижеприведенный текст не является руководством по установке для оборудования, которое можно здесь приобрести. Это сравнение двух моделей изоляции, написанное для того, чтобы вы могли определить, какая из них подходит для конкретной рабочей нагрузки, и чтобы вы могли понимать конфигурации команд FreeBSD без догадок.

Что такое jail на самом деле

Технология Jails появилась в FreeBSD 4.0 в марте 2000 года, что делает её старше cgroups и примерно на десятилетие старше Docker. Механизм основан на одном системном вызове ядра. jail(8) берет дерево каталогов и запускает внутри него процессы, присваивая им идентификатор jail, после чего ядро блокирует фиксированный набор операций для любого процесса с этим идентификатором. Процесс внутри jail не видит процессы за его пределами, не может монтировать или размонтировать файловые системы, загружать модули ядра и привязываться к сетевым адресам, которые не были назначены данному jail. Здесь нет отдельных типов пространств имен для изучения или выбора функций: ограничения применяются единым блоком и настраиваются параметрами в конфигурации jail.

На хосте команда jls выводит список запущенных jail, а jexec web sh открывает оболочку внутри jail с именем web.

Вы создаете jail, помещая пользовательское окружение FreeBSD (userland) в каталог. Базовая система выполняет это за вас:

sudo bsdinstall jail /usr/local/jails/containers/web

Эта команда загружает дистрибутив базовой системы для вашего релиза и выполняет стандартные шаги после установки, поэтому вы задаете пароль root и выбираете часовой пояс точно так же, как на новом сервере. Результатом будет установка FreeBSD, расположенная в папке. Затем вы описываете её в /etc/jail.conf:

web {
  host.hostname = "web.example.internal";
  path = "/usr/local/jails/containers/web";
  ip4.addr = "10.0.0.10";
  exec.start = "/bin/sh /etc/rc";
  exec.stop = "/bin/sh /etc/rc.shutdown";
  mount.devfs;
}

Запустите его, а затем проверьте:

sudo service jail start web
jls

jls теперь должен отобразить web с JID, именем хоста и IP-адресом. Если jail не появился, запустите sudo jail -c web напрямую. Команда применит ту же конфигурацию в интерактивном режиме и выведет параметр, который не удалось принять, вместо того чтобы оставить информацию об ошибке в выводе службы.

Строка, которую стоит прочитать дважды, — это exec.start = "/bin/sh /etc/rc". Запуск jail выполняет стандартный загрузочный скрипт FreeBSD внутри него, поэтому jail запускает все службы, включенные в его собственном файле /etc/rc.conf. У Docker-контейнера нет аналогичного этапа, так как он запускает процесс entrypoint образа и завершается, когда этот процесс останавливается.

Как доставляется ПО: образы и реестры против пользовательского окружения, которое вы наполняете сами

Это разница, которую вы ощущаете в первый же день.

В Docker вы указываете имя программы и получаете её. docker pull nginx загружает послойный образ с адресацией по содержимому, который кто-то другой собрал и протестировал, а docker compose up -d запускает его с подключенными томами и сетью. Реестр — это и есть продукт. Основная ценность рабочего процесса Docker заключается в том, что тысячи проектов публикуют готовые к работе образы, что делает запуск Docker на VPS быстрой задачей, а не полноценным проектом.

FreeBSD не предоставляет публичного реестра образов jail по умолчанию. Вы создаете пустое пользовательское окружение и устанавливаете в него ПО так же, как настраивали бы обычный сервер. Это требует больше ввода команд. Но это и более прозрачный подход, так как в jail работает именно то, что поместил туда pkg из того же набора пакетов, который использует хост.

Инструменты сокращают время работы. BastilleBSD — популярный менеджер jail, доступный в виде пакета:

sudo pkg install bastille
sudo sysrc bastille_enable=YES
sudo bastille setup
sudo bastille bootstrap 15.1-RELEASE

bastille setup настраивает сеть, хранилище и межсетевой экран за вас. bastille bootstrap загружает релиз один раз, и каждый последующий jail использует его повторно. FreeBSD 15.1 — текущий производственный релиз, вышедший в июне 2026 года; подставьте версию, которую используете вы.

Создание jail выполняется одной командой, а его наполнение — еще одной:

sudo bastille create web 15.1-RELEASE 10.17.89.10/24
sudo bastille pkg web install nginx
sudo bastille service web nginx start
sudo bastille console web

bastille console web предоставляет оболочку для входа внутри jail, а bastille list показывает, что существует на хосте. Чтобы повторить сборку, шаблоны Bastille хранят шаги в файле и применяют их к jail — это максимально близкий аналог Dockerfile в данном мире. Шаблон воспроизводится для каждого jail. Ничего не приходит в готовом виде.

Честный итог краток. Docker предоставляет вам чужие сборки. Jails предоставляют вам возможность выполнить установку самостоятельно. Если ПО из вашего списка поставляется только в виде образа контейнера, это решает вопрос до того, как будут рассмотрены другие критерии.

Состояние и обновления: изменения в ZFS

Docker намеренно разделяет состояние. Файловая система контейнера является временной, ваши данные хранятся в именованном томе (named volume) или bind mount, а обновление выполняется через docker compose pull с последующим docker compose up -d. Контейнер заменяется, и всё, что вы не поместили в том, удаляется. Это преимущество, если вы следуете правилам, и инцидент с потерей данных, если вы о них забыли. Именно поэтому выбор между bind mounts и именованными томами имеет такое большое значение в стеке Compose.

Jail не разделяет состояние, и ZFS — причина, по которой это работает. Весь jail представляет собой один набор данных (dataset):

sudo zfs snapshot zroot/jails/containers/web@pre-upgrade
sudo pkg -j web upgrade
sudo zfs rollback zroot/jails/containers/web@pre-upgrade

Проверьте реальное имя набора данных с помощью zfs list перед выполнением этой команды; путь выше соответствует структуре, используемой в руководстве. Снимок (snapshot) создается примерно за секунду и почти не занимает места, пока содержимое jail не изменится. Если обновление нарушает работу сервиса, откат (rollback) возвращает всё пользовательское окружение в исходное состояние, включая базу данных пакетов и конфигурационные файлы, которые вы правили вручную в 2 часа ночи. В Docker нет встроенного аналога, так как его модель предполагает, что вам это никогда не потребуется.

zfs clone — это вторая половина процесса. Клон снимка — это новый доступный для записи jail, который использует общие неизмененные блоки с родительским объектом. Поэтому копия jail объемом 3 GB для тестирования почти ничего не занимает на диске, пока вы не начнете вносить в нее изменения. Именно так администратор FreeBSD создает jail, «идентичный продуктивному», для отработки обновления.

Обновление базовой системы выполняется отдельно от пакетов. Для jail, содержащего собственную копию пользовательского окружения:

sudo freebsd-update -b /usr/local/jails/containers/web fetch install

«Тонкие» (thin) jails позволяют избежать повторения этой работы. Они монтируют одну общую базовую систему в режиме только для чтения через nullfs и предоставляют каждому jail небольшой собственный слой для записи. Таким образом, вы обновляете базу один раз, и каждый jail видит результат. Bastille создает «тонкие» jails по умолчанию.

Сети: опубликованные порты против выбора адресации

Docker самостоятельно управляет сетью и требует от вас публикации исключений. Контейнеры попадают в bridge, они взаимодействуют друг с другом по имени сервиса в пользовательской сети, а -p 8080:80 открывает один из них для хоста. Docker записывает собственные правила фильтрации пакетов для реализации этого механизма, именно поэтому опубликованный порт контейнера игнорирует ufw.

Jail требует выбора модели на начальном этапе, и их существует две.

Shared IP. ip4.addr = "10.0.0.10" добавляет этот адрес к существующему интерфейсу хоста и ограничивает jail этим адресом. У jail нет собственного сетевого стека, поэтому он не может запускать собственный межсетевой экран. Он также не может полноценно привязываться ко всем адресам: ядро переписывает сокет jail, запрашивающий 0.0.0.0, на собственный адрес jail. Два jail не могут одновременно слушать порт 80 на одном и том же адресе, поэтому вы назначаете каждому свой адрес или устанавливаете перед ними reverse proxy.

VNET. Добавьте vnet; в jail, и он получит полноценный сетевой стек: собственные интерфейсы, собственную таблицу маршрутизации, собственные правила межсетевого экрана. Вы соединяете его с хостом через epair — виртуальный кабель, концы которого находятся по обе стороны, а конец со стороны хоста подключается к bridge. Это наиболее близкий аналог того, что предоставляет Docker, и именно этот режим используется в типах jail -V и -B в Bastille.

Проброс порта хоста в jail — это правило перенаправления pf. Bastille автоматизирует это действие:

sudo bastille rdr web tcp 80 80

Здесь нет EXPOSE и автоматической публикации. Ничто не достигнет jail, пока его адрес или правило перенаправления не разрешат это. Это требует больше времени на настройку, но обеспечивает гораздо более «тихий» межсетевой экран.

Ограничения ресурсов: cgroups против rctl

Docker ограничивает контейнер с помощью cgroups, при этом лимиты задаются там же, где описан сам контейнер: --memory=1g --cpus=1.5 в командной строке или соответствующими ключами в файле Compose. Если вы уже храните свой стек в файле Docker Compose на VPS, ограничение находится рядом с сервисом, к которому оно применяется, и перемещается вместе с ним в git.

FreeBSD использует rctl — это подсистема, которую необходимо включить вручную. Учет ресурсов по умолчанию отключен, так как он создает небольшую нагрузку при каждом выделении памяти. Добавьте параметр настройки в /boot/loader.conf и перезагрузитесь:

kern.racct.enable=1

Затем установите правило и отслеживайте его:

sudo rctl -a jail:web:vmemoryuse:deny=1g
rctl -hu jail:web

rctl -hu jail:web выводит текущее использование ресурсов jail в удобном для чтения формате, поэтому вы можете видеть, насколько близко потребление подошло к лимиту, прежде чем произойдет сбой. Действие deny приводит к тому, что запрос на выделение ресурсов сверх лимита завершается ошибкой внутри jail. В результате вы видите ошибку выделения памяти самого приложения, а не сообщение об аварийном завершении процесса на хосте.

Правила, добавленные с помощью rctl -a, исчезают после следующей перезагрузки. Служба rctl во FreeBSD перезагружает их из /etc/rctl.conf, поэтому запишите правило в этот файл и включите службу:

sudo sysrc rctl_enable=YES

Это тот аспект, в котором Docker явно удобнее. Лимит в файле Compose проходит проверку вместе с сервисом, который он ограничивает. Правило rctl — это строка в отдельном файле, ссылающаяся на jail, который определен где-то в другом месте.

Когда ответом является виртуальная машина: bhyve

Jail использует общее ядро с хостом, поэтому некоторые возможности недоступны принципиально. В jail нельзя запустить другую версию ядра, загрузить модуль ядра или выполнить Linux-бинарные файлы так, как это делают Linux-контейнеры. В FreeBSD есть слой совместимости с Linux, linuxulator, но он реализует лишь подмножество системных вызовов Linux и не является универсальным решением для произвольных образов Linux.

bhyve — это гипервизор FreeBSD, и это подходящий инструмент, когда требуется реальная изоляция на уровне машины: другая операционная система, другое ядро или арендатор, с которым вы не хотите использовать общее ядро. Вы платите за это памятью, которая резервируется, а не распределяется динамически, и необходимостью обновлять второе ядро. Это тот же выбор, который вы делаете в Linux между контейнерами и полноценными виртуальными машинами, и именно он определяет, нужен ли вам VPS с поддержкой вложенной виртуализации.

Экосистема — главная причина, по которой большинство команд выбирают Docker

Все, что было сказано выше, касается модели работы. Однако выбор большинства команд определяет масштаб инфраструктуры вокруг каждого решения.

Docker предлагает Docker Hub и GHCR, docker compose, Kubernetes для случаев, когда одного сервера становится недостаточно, CI-раннеры с уже настроенной поддержкой контейнеров и инструкции по быстрому запуску в одну команду почти в каждом README. Jails опираются на дерево портов FreeBSD — обширное и тщательно поддерживаемое, но предлагающее гораздо меньший набор готовых к запуску пакетов приложений. Если проект публикует только образ контейнера, при использовании FreeBSD вам придется изучать документацию и собирать компоненты самостоятельно.

Jails оправдывают свое применение в других сценариях. Они нужны, если вы уже используете ZFS и цените возможность создания снимков (snapshots) и отката целого сервиса, если ваши сервисы являются нативными для FreeBSD, если вам требуется полноценное пользовательское окружение (userland) для каждого арендатора вместо одного процесса, или если вы хотите, чтобы ядро, пакетный фильтр, файловая система и документация поддерживались как единая система. Именно это имеют в виду, когда называют FreeBSD целостной ОС. Подробнее об этом можно прочитать в сравнительном обзоре Linux и FreeBSD как серверных платформ и в материале о том, что изменилось во FreeBSD 15 для серверного использования.

Заключительный вывод. Если ваша команда уже работает с Docker, переход на другую технологию потребует реальных затрат, поэтому выгода должна быть очевидной. Не стоит переходить ради качества изоляции: обе модели достаточно близки, и ваша конфигурация значит больше. Переходите, если вам нужен откат целых сервисов на базе ZFS или если вы уже используете FreeBSD.

FAQ

Можно ли запускать Docker-образы в FreeBSD?

Не Linux-образы и не в качестве поддерживаемого решения. В FreeBSD есть поддержка OCI-контейнеров: sudo pkg install -y podman-suite устанавливает Podman, который запускает контейнеры через ocijail — среду выполнения, создающую полноценные jails. Для работы монитора контейнеров требуется смонтировать fdescfs в /dev/fd, а для NAT (network address translation) контейнеров — pf. Лучше всего работают OCI-образы, созданные специально для FreeBSD. Для Linux-образов дополнительно требуется слой совместимости с Linux, при этом по состоянию на август 2026 года порт Podman для FreeBSD всё ещё считается экспериментальным. Если ваш стек состоит из Linux-образов, запускайте его на Linux.

Безопаснее ли FreeBSD jails, чем Docker-контейнеры?

Обе технологии используют одно ядро хоста, поэтому уязвимость в ядре представляет риск для обеих, и ни одна из них не является границей безопасности для заведомо недоверенного кода. Разница заключается в подходе к настройке. Jail изначально запрещает широкий набор операций, которые вы разрешаете по одной. Docker-контейнер стартует с правами root внутри набора пространств имён (namespaces) с ограниченным набором возможностей (capabilities), а дальнейшее усиление защиты остаётся на усмотрение администратора. На практике конфигурация важнее модели: jail с включёнными allow.mount и allow.raw_sockets не безопаснее тщательно настроенного контейнера.

Как создать резервную копию jail?

Создайте снапшот датасета и отправьте его. Используйте sudo zfs snapshot zroot/jails/containers/web@backup, а затем zfs send для передачи снапшота в другой пул или в файл, который можно скопировать с сервера. Поскольку jail хранит всё пользовательское окружение в одном датасете, снапшот фиксирует установленные пакеты и данные в согласованном состоянии, включая все файлы конфигурации, которые вы правили вручную. Это противоположность подходу Docker, где вы делаете резервные копии именованных томов и Compose-файла, а остальное пересобираете из образа.

Нужен ли мне BastilleBSD или достаточно базовой системы?

Базовой системы достаточно, и с неё лучше начинать. jail.conf, jls, jexec и service jail start охватывают всю модель работы, и, освоив их, вы сможете разобраться с любым хостом FreeBSD, не изучая специфические инструменты конкретного администратора. Bastille — это удобная надстройка: она разворачивает релизы, создаёт тонкие jails, применяет шаблоны и прописывает правила перенаправления pf за вас. Сначала изучите базовые команды, а затем добавьте Bastille, когда количество jails сделает ручной ввод команд утомительным.