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 чтобы принять их. Это следующие ключи:
-d data - путь к каталогу данных окружения; -f fstab - путь к каталогу fstab (актуально в основном для jail); -j jname - непосредственно имя вашего окружения; -r rcconf - путь к каталогу rcconf; -s sysdata - путь к каталогу 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/