FreeBSD virtual environment management and repository

2020-10 upd: we reached the first fundraising goal and rented a server in Hetzner for development! Thank you for donating !

Использование CBSD совместно с DFS (Distributed File System)

Общая информация

Одной из отличительных особенностей CBSD от остальных современных оберток по управлению jail и bhyve на платформе FreeBSD является отсутствие жесткой привязки к файловой системе ZFS, что влечет определенный оверхед с точки зрения кода, когда вы используете только ZFS, но делает CBSD более универсальным инструментом, который вы можете использовать в более широких ситуациях.

Одна из таких ситуаций - использование различных embedded платформ с очень небольшим количеством ресурсов где файловая система ZFS является избыточной и прожорливой, что делает ее малоэффективной на различных Raspberry PI и аналогичных решений. С противоположной стороны минимализма находятся большие и масштабные гиперконвергентные инсталляции с применением NAS/SAN и распределенных систем хранения данных, с использованием внешних хранилищ, подключаемых по протоколу NFS, iSCSI или таких файловых систем, как ClusterFS и Ceph.

Здесь будут освещены вопросы использования CBSD в подобных инсталляциях и описаны Howto-style записи по применению.

Общее требование при использовании CBSD на DFS, характерное для любых реализаций, это выключение zfsfeat и hammerfeat опции в 'cbsd initenv-tui' и необходимость выносить на общее хранилище следующих каталогов:

  • ~cbsd/jails-data: каталог с данными контейнера или виртуальной машины
  • ~cbsd/jails-system: системный каталог с дополнительной системной информацией, относящейся к контейнеру или виртуальной машине
  • ~cbsd/jails-rcconf: каталог используется, когда окружение переходит в режим unregister
  • ~cbsd/jails-fstab: каталог используется для хранения fstab файлов

Если рабочий каталог (workdir) проинициализирован в /usr/jails это, соответственно, каталоги:

/usr/jails/jails-data
/usr/jails/jails-system
/usr/jails/jails-rcconf
/usr/jails/jails-fstab

Вы можете перенести на DFS указанные локации и смонтируете в одной точке все окружения, однако авторы рекомендуют разделять ресурсы на индивидуальные окружения. Например, для контейнера jail1, экспортировать и монтировать непосредственно данные jail1, отдельные от других:

/usr/jails/jails-data/jail1-data
/usr/jails/jails-system/jail1
/usr/jails/jails-fstab/jail1

Это позволит вам оптимизировать работу файловых систем между окружениями и снизить потенциальное влияние деятельности одного окружения на другое - например, если окружение jail1 очень аггресивно использует лок на файловой системе, это будет влиять и на jail2 в случае, когда вы монтируете /usr/jails/jails-data, тогда как различные сессии и mount для /usr/jails/jails-data/jail1-data и /usr/jails/jails-data/jail2-data будут независимы. Кроме этого, в этом случае вы можете использовать разные источники монтирования - ресурсы jail1 могут находится на одном DFS сервере, а jail2 - на другом. Для этого, в CBSD присутствует механизм хуков для монтирования и размонтирования, о чем написано ниже.

Остальные каталоги, такие как bases вы также можете поместить на общее хранилище чтобы сэкономить место. Однако, гораздо более эффективно базовые файлы контейнера хранить локально, что с параметром baserw=0 по отношению к контейнерам гарантирует работу базовых утилит и библиотек со скоростью локального диска и отсутствием возможных сетевых проблем.

Общие хранилища дают легкий способ миграции окружений с нулевым копированием. Так, вы можете перевести контейнера в состояние unregister на одной ноде:

node1:

% cbsd junregister jname='*'

И зарегистрировав, без какого-либо копирования начать использовать на другой:

node2:

% cbsd jregister jname='*'

Known issues.

На некоторых DFS, таких как NFSv3 и GlusterFS, требуется дополнительная настройка в pkg.conf для корректной работы локинга:

 % echo "NFS_WITH_PROPER_LOCKING = true;" >> /usr/local/etc/pkg.conf

Хуки CBSD для работы с DFS

Если вы выходите за рамки кейса, когда все данные окружений расположены на локальной файловой системе ZFS/UFS, перед вами встает вопрос предвартительного монтирования ресурса, содержащего данные окружения. Для этого, в CBSD используются параметры mnt_start и mnt_stop, в которых вы указываете кастомный скрипты, работающие при старте и при останове окружения. Это может быть любой executable скрипт, для успешной работы с CBSD которого нужно соблюсти несколько правил:

  • Ваш скрипт должен быть устойчив к вторичному монтированию. Например, вы стартовали окружение, затем остановили и запустили вновь. Ваш скрипт не должен монтировать поверх предыдущего монтирования еще раз - эта проверка и это поведение на совести вашего скрипта - проверяйте факт монтирования
  • Ваш скрипт должен завершиться с кодом 0 при успехе или ненулевым кодом при фатальных проблемах
  • Время работы вашего хука неограничено - избегайте ситуации, когда ваш скрипт может висеть вечно
  • CBSD запускает скрипт с определенными аргументами для передачи некоторой полезной информации. Ваш скрипт должен обрабатывать опции через getopt чтобы принять их. Это следующие ключи:
    -ddata - путь к каталогу данных окружения;
    -ffstab - путь к каталогу fstab (актуально в основном для jail);
    -jjname - непосредственно имя вашего окружения;
    -rrcconf - путь к каталогу rcconf;
    -ssysdata - путь к каталогу sysdata;

Как видите, использование этих параметров с возможностью создавать кастомные сценарии для подключения внешних хранилищ, дает вам возможность использовать сценарии, о которых не слышал ни один белый человек, например: iSCSI, Infiniband, GELI, HASTD и тд.

В качестве рабочего примера посмотрите на скрипт для работы с NFSv4 в следующем параграфе.

Кроме этого, вам может быть полезно знать о возможности кастомных операций по клонированию - например, если вы контроллируете ваш внешний сторедж и он может выполнять операции по копированю данных на своей стороне, вы можете избежать высокой нагрузки на сеть при обычном копировании информации, а сделать моментальный клон средствами внешнего накопителя. Подробнее об этом сценарии смотрите здесь и здесь.

CBSD и NFSv4

Использование CBSD и jail на NFSv4

У нас есть отдельный NFS сервер на базе FreeBSD и есть отдельный сервер с CBSD, который будет хранить jail на NFS сервере.

IPv4 адрес NFS сервера: 172.16.0.1, IPv4 адрес сервера CBSD: 172.16.0.100

Данные jail на NFS сервере будут располагаться в каталоге /nfs

Сконфигурируем NFSv4 сервер:

В /etc/exports опишем пути для экспорта:

/nfs -alldirs -maproot=root 172.16.0.100
V4: / 172.16.0.100

Если NFS сервер использует ZFS, не забудьте включить sharenfs опцию на необходимом пуле. Например, если корневая система ZFS это zroot/ROOT/default, то экспорт NFS включается через следующую команду:

% zfs set sharenfs=on zroot/ROOT/default

В /etc/rc.conf добавим необходимые для запуска NFS-сервера службы, выполнив команды:

sysrc -q nfsv4_server_enable="YES"
sysrc -q nfscbd_enable="YES"
sysrc -q nfsuserd_enable="YES"
sysrc -q mountd_enable="YES"
sysrc -q nfsuserd_enable="YES"
sysrc -q rpc_lockd_enable="YES"

Создадим пустые каталоги для jail1, который будет на NFS:

mkdir -p /nfs/data/jail1 /nfs/fstab/jail1 /nfs/rcconf/jail1 /nfs/system/jail1

После перезагрузки NFS сервера или служб, NFSv4 сервер готов к работе.

Со стороны CBSD, нам необходимо монтировать данные контейнера через следующие команды:

% mount_nfs -o vers=4 172.16.0.1:/nfs/data/jail1 /usr/jails/jails-data/jail1-data
% mount_nfs -o vers=4 172.16.0.1:/nfs/fstab/jail1 /usr/jails/jails-fstab/jail1
% mount_nfs -o vers=4 172.16.0.1:/nfs/rcconf/jail1 /usr/jails/jails-rcconf/jail1
% mount_nfs -o vers=4 172.16.0.1:/nfs/system/jail1 /usr/jails/jails-system/jail1

Вы можете использовать файл /etc/fstab с опцией 'late' для монтирования каталогов при старте ноды, либо использовать automount ( autofs(5) )

Однако в этом примере мы продемонстрируем работу опции mnt_start с внешним кастомным скриптом для монтирования файловых систем. Скрипт присутствует как рабочий пример и лежит в каталоге /usr/local/cbsd/share/examples/env_start/nfsv4. Он довольно прост. А также использует конфигурационный файл, в котором вы можете отредактировать динамические настройки под ваше окружение.

Скопируем конфигурационный файл и поправим IP адреса:

% cp -a /usr/local/cbsd/share/examples/env_start/nfsv4/env_start_nfs.conf ~cbsd/etc/
% vi ~cbsd/etc/env_start_nfs.conf

В нашем примере файл будет выглядеть следующим образом:

NFS_SERVER="172.16.0.1"
NFS_SERVER_ROOT_DIR="/nfs"
MOUNT_RCCONF=0
MOUNT_FSTAB=1
MOUNT_NFS_OPT="-orw -overs=4 -ointr -orsize=32768 -owsize=32768 -oacregmax=3 -oacdirmin=3 -oacdirmax=3 -ohard -oproto=tcp -otimeout=300"

Создаем jail через cbsd jconstruct-tui:

Не забываем, что мы создаем контейнер с именем jail1, укажем его в качестве jname.

Поскольку скрипт для параметра mnt_start мы будем использовать без модификации, укажем его непосредственно в /usr/local/cbsd/share/examples/env_start/nfsv4/env_start_nfs.sh:

Теперь, при операциях, требующих наличия данных контейнера (например jstart, jcreate), CBSD будет вызывать этот скрипт.

Если вы используете несколько CBSD серверов, вы можете легко выполнять перерегистрацию контейнера с одного физического сервера на другой через junregister команду на одном сервере и jregister на другом:

node1 % cbsd junregister jname='jail*'     // на ноде, где зарегистрированы jail
node2 % cbsd jregister jname='jail*'       // на другой ноде

И мигрировать таким образом ваши окружения, распределяя и маcштабируя нагрузку на ваш кластер более ровно.

CBSD и GlusterFS


WIP. Короткий HowTo доступен здесь: CBSD и GlusterFS


CBSD и CEPH


WIP/