2020-10 upd: we reached the first fundraising goal and rented a server in Hetzner for development! Thank you for donating !
Цели проекта
CBSD разрабатывалась с точки зрения user-friendly, с учетом удобств для пользователя при интерактивной работе. Вы можете спросить - что ж, интерактивные диалоги - это прекрасно. Но что, если у вас стоит задача построить масштабируемый кластер, где виртуальными машинами будет управлять логика более высокого уровня и по этой причине, нам нет нужды в интерактивных командах - может ли CBSD чем-то быть вам полезной в этом случае?
В этой статье описан пример создания и управления кластером CBSD через асинхронный интерфейс с использованием минималистического и быстрого брокера на базе net/beanstalkd. Вместо beanstalkd может выступать любой брокер, такой как ActiveMQ, ZeroMQ, RabbitMQ или Kafka. Условно, назовем это низким уровенем управления виртуальными машинами, который обеспечивает доставку и возвращение результата при управлении виртуальными машинами, такие как создание ВМ, добавление диска, создание снапшота, миграция, клонирование, изменение VNC порта и тд. На более высоком уровне может быть ваше приложение (контроллер).
Здесь мы будем использовать множественные рабочие окружения CBSD, когда часть ресурсов может быть проинициализирована в одном каталоге, другая - в другом. Это открывает широкие возможности при построении pool-binded методов размещения виртуальных машин. Pool binded кластер означает, что все сервисы или виртуальные машины кластера будут привязаны к тому или иному пулу, который может переходить от одного сервера к другому при аварийных ситуациях, при работе DRS или обслуживания оборудования. Таким образом, это может стать базой для построения 'shared nothing cluster' на базе FreeBSD и CBSD.
Построение отказоустойчивого кластера будет описано в более расширенной статье, здесь мы ограничимся лишь множественными рабочими окружениями CBSD, чтобы продемонстрировать работу асинхронного интерфейса через брокер. Предполагаем, что CBSD уже установлена и настроена на сервере. Нам необходим сервис beanstalkd, выступающий в качестве общей шины для всех агентов. Давайте запустим его в jail на нашем сервере. Для этого создаем jail с произвольным именем, в котором будет запущен beanstalkd, например bs1 (назначьте контейнеру корректный рабочий IP адрес, он нам потребуется):
cbsd jconstruct-tui cbsd pkg jname=bs1 mode=update cbsd pkg jname=bs1 mode=install net/beanstalkd cbsd sysrc jname=bs1 beanstalkd_enable=YES cbsd jstart bs1
Затем, проинициализируем два независимых окружения (в настоящем кластере это могут быть разные пулы и их, разумеется, может быть больше), например в /pool1 и /pool2 директориях:
env workdir=/pool1 /usr/local/cbsd/sudoexec/initenv
на вопрос изменения rc.conf файла, отвечайте 'n', эта инициализация не должна модифицировать ваши основные конфигурационные файлы.
на вопрос включения NAT ( nat_enable: Enable NAT for RFC1918 networks? ) отвечайте 'нет' - у вас он уже должен работать в основной системе.
Тоже самое повторите для второго окружения:
env workdir=/pool2 /usr/local/cbsd/sudoexec/initenv
с аналогичными ответами.
Теперь, CBSD может работать в этих окружениях через переменную workdir, например:
env workdir=/pool1 cbsd jconstruct-tui env workdir=/pool2 cbsd jconstruct-tui
и тд.
Каждое окружение будет обслуживать небольшой агент (назовем его bs_router) который будет подключаться к beanstalkd и обрабатывать запросы. Склонируем его:
cd /root git clone https://github.com/cbsd/bs_router.git /root/bs_router
Пример написан на golang, поэтому для сборки проекта нам потребуется go:
pkg install -y lang/go
Собираем:
cd bs_router setenv GOPATH /root/bs_router go get go build cp -a bs_router /usr/local/sbin
Теперь скопируем конфигурационный файл и откорректируем для каждого пула:
cp -a config.json /usr/local/etc/pool1.json cp -a config.json /usr/local/etc/pool2.json
В обоих файлах измените:
- uri - с 127.0.0.1:1130 на адрес jail, в котором установлен и запущен beanstalkd, например: 172.16.0.3:1130 (если контейнер bs1 имеет IP 172.16.0.3)
- cbsdenv - в файле pool1.json это будет /pool1, в файле pool2.json - /pool2
- tube - на какую трубу подписываемся, для pool1.json пусть это будет "cbsd_pool1", для pool2.json - cbsd_pool2
- reply_tube_prefix какую трубу используем для ответов, для pool1.json пусть это будет: cbsd_pool1_result_id, для pool2.json - cbsd_pool2_result_id
Запускаем оба агента с указанием конфигурационного файла:
/usr/local/sbin/bs_router -config /usr/local/etc/pool1.json /usr/local/sbin/bs_router -config /usr/local/etc/pool2.json
Все, теперь все, что мы будем отправлять в beanstalk очередь с соответствующим именем и соответствующем payload в формате json, будет передано CBSD и получен ответ.
В качестве примера, склонируем семпл клиента к нашему агенту CBSD, который будет подключаться к beanstalkd и слать запросы:
cd /root git clone https://github.com/cbsd/bs_router-client.git cd bs_router-client setenv GOPATH /root/bs_router-client go get go build
В результате получили бинарный файл bs_router-client, который можно теперь использовать для отправки и приеме задач в разные окружения CBSD. Посмотрите на каталог bin.jail и bin.bhyve, в которых находятся примеры использования.
Работая с cloud образами, есть смысл сначала 'прогреть' все образы, чтобы создание первой виртуальной машины не тормозило процесс, например для pool1 это можно сделать так:
env workdir=/pool1 cbsd fetch_iso keepname=0 conv2zvol=1 cloud=1 dstdir=default
После этой команды, вы сможете воспользоваться результатом выполнения скриптов /root/bs_router-client/bin.bhyve/bcreate.sh и /root/bs_router-client/bin.bhyve/bstart.sh без промедления.