2020-10 upd: we reached the first fundraising goal and rented a server in Hetzner for development! Thank you for donating !
Внимание! Данные страницы описывают CBSD версии 13.0.x. Если вы используете более раннюю версию, рекомендуется сначала обновиться.
Пример интеграции CBSD с MONIT (health-check).
Введение
Если вы посмотрите на список ПО, посвященного управлению jail на FreeBSD, то наверняка отметите, что дефицита в количестве подобного рода утилит нет. Различные jail (актуально и для bhyve/XEN) врапперы предоставляют на любой вкус формат записей директив, команд и аргументов. Однако все они (включая CBSD, конечно), в основном, предлагают одинаковые операции и возможности с незначительными отличиями, а именно: базовые 'создание', 'удаление', 'запуск' и 'остановка' окружений. Но никто не идет дальше: сущности более высокого уровня, такие как контроллер, супервизор, health-check, DRS и т.д. - отсутствуют как класс. Без доработок, это ограничивает круг применения jail/bhyve врапперов до масштабов локаххоста, из-за отсутствия возможности прозрачно использовать деплой на группу физических нод. Этому есть достаточно логичное объяснение - в современных реалиях довольно опрометчиво пытаться решить все проблемы вселенной одним продуктом. Именно поэтому CBSD уделяет большое внимание возможностям интеграции с инструментами, которые расширяют возможности CBSD фреймворка для предоставления пользователям дополнительных возможностей.
В этой главе мы решаем вопрос мониторинга здоровья сервисов в контейнерах или виртуальных машинах с помощью monit, с последующим рестартом окружений при определенных условиях. Основное действующее лицо, обеспечивающее интеграцию - это экспорт CBSD фактов об окружении, являющиеся динамическими данными, а также наличие в CBSD хуков, что позволяет автоматизировать процесс создания и удаления правил monit.
Другие главы этой серии:
- API module: частное облако через API
- VPC с CBSD (vxlan)
- Интеграция CBSD с PHPIPAM (IP менеджмент)
- Пример использования CBSD/bhyve и ISC-DHCPD (посредством pre/post хуков, обслуживаем IP адреса в bhyve)
- Пример использования CBSD/jail и Consul.io (посредством pre/post хуков, регистрируем jail в Consul)
- DRS для CBSD
Почему Monit? Когда в 2021 году мы говорим об автоматическом перезапуске контейнеров в зависимости от определеных условий, на ум сразу приходят такие монструозные Linux-центричные решения, как OpenShift, Kubernetes, Systemd...
В лагере FreeBSD, скорее всего наиболее близко будет использование продукта от HashiCorp под названием Consul. Продукты HashiCorp славятся тем, что имеют крайне хорошую интеграцию между собой: всем известна шайка из закадычных друзей: Nomad, Consul и Vault.
Это неплохой и качественный современный стек, но мы выберем путь минимализма и простоты, где наша задача - выбор не по принципу 'о чем говорят все', а наибее дешевом и легковесном решении поставленной задачи - мониторинг и рестарт сервиса, где функциональностей monit для нас более чем достаточно. Для оценки разницы, достаточно взглянуть хотя бы на разницу потребляемых ресурсов обоих сервисов:
monit | consul | |
размер исполняемого файла: | 425 Kb | 78 Mb |
потребление RAM без чек-правил (default): | 25 Mb | 80 Mb |
Кроме этого, цель статьи - показать саму концепцию, которая леко может быть использована с любыми другими, более массивными инструментами.
Идея и архитектура
monit работает по конфигурационному файлу monitrc, в котором перечислены правила проверок тех или иных событий и реакция на них. Наша задача - при создании контейнера добавлять в рантайме правила, если у контейнера есть что проверять. И соответственно, снимать с мониторинга, когда контейнер остановлен или удаляется. В качестве реакции на неуспешный тест, заставим monit перезагружать контейнер. Это означает, что каждый физический CBSD-хост будет запускать свой уникальный экземпляр monit, работающий только с локальными окружениями. Конечно, мы можем обойтись и одним monit, который будет проверять все, но это будет являться single-point-of-failure, что потребует дополнительных трудозатрат по обеспечению надежности самого внешнего сервиса monit.
Конфигурацию проверок для каждого окружения мы будем сопровождать независимо от общей конфигурации, чтобы правила всегда оставались вместе с окружением, даже если он будет перемещаться с ноды на ноду. Это особенно удобно при использовании деплоя метом CBSDfile, где правила и хук-скрипты могут находится в одном каталоге.
В этом примере мы можем проверять доступность TCP порта или определенного контента по HTTP протоколу, поэтому из всех динамических параметров, от CBSD процессу monit будут нужны лишь два - имя контейнера (для рестарта) и IP адрес, доступность порта на котором и будет проверяться. Для этого заготовим шаблон в каталоге ~cbsd/jails-system/JNAME/monit/ из которого при старте, останове или удалении, будет формироваться или удаляться рабочая конфигурация monit, при обновлении которой, основной процесс monit должен ее перечитать. Простейшая имплементация в качестве примера реализована с использованием shell скриптинга в виде одноименного модуля для CBSD.
Установка и конфигурирование monit
Установим monit через pkg:
pkg install -y monit
Скопируйте пример конфигурационного файла в рабочий и допишите в конце директиву подключения всех конфигурационных файлов в ~cbsd/jails-system/*/monit/monitrc - их будет генерировать модуль. Обратите внимание, что /usr/jails (рабочий каталог CBSD) в вашем случае может отличаться:
cp -a /usr/local/etc/monitrc.sample /usr/local/etc/monitrc echo 'include /usr/jails/jails-system/*/monit/monitrc' >> /usr/local/etc/monitrc
Конфигурирование CBSD
Выполним установку модуля, как описывает страничка проекта:
cbsd module mode=install monit echo 'monit.d' >> ~cbsd/etc/modules.conf cbsd initenv
Скопируем скрипты, которые будут запускаться в качестве destroy/start/stop хуков окружений. Примеры этих скриптов находятся здесь: /usr/local/cbsd/modules/monit.d/share.
mkdir -p /root/share/cbsd-monit cp -a /usr/local/cbsd/modules/monit.d/share/*.d /root/share/cbsd-monit/
В /root/share/cbsd-monit/ у нас теперь находятся три каталога по имени каталогов, которые отрабатывают в CBSD при определенных событиях:
- master_poststart.d - работает после запуска окружения;
- master_create.d - работает при создании нового окружения;
- remove.d - работает при уничтожении окружения;
Внутри каждого каталога находится выполняемый файл monit.sh, который и будет выполнять все действия.
Конечно, вы можете написать собственный, более изящный обработчик вместо этих демонстрационных скриптов. Теперь, если вы не используете свои собственные профили, просто слинкуйте скрипты в каталоги CBSD:
для jail:
ln -sf /root/share/cbsd-monit/master_poststart.d/monit.sh ~cbsd/share/jail-system-default/master_poststart.d/monit.sh ln -sf /root/share/cbsd-monit/master_prestop.d/monit.sh ~cbsd/share/jail-system-default/master_prestop.d/monit.sh ln -sf /root/share/cbsd-monit/remove.d/monit.sh ~cbsd/share/jail-system-default/remove.d/monit.sh
для bhyve:
ln -sf /root/share/cbsd-monit/master_poststart.d/monit.sh ~cbsd/share/bhyve-system-default/master_poststart.d/monit.sh ln -sf /root/share/cbsd-monit/master_prestop.d/monit.sh ~cbsd/share/bhyve-system-default/master_prestop.d/monit.sh ln -sf /root/share/cbsd-monit/remove.d/monit.sh ~cbsd/share/bhyve-system-default/remove.d/monit.sh
При запуске контейнера, скрипт проверяет наличие темплейта в системном каталоге окружения: ~cbsd/jails-system/JNAME/monit/monitrc.tpl. При наличии такового, используется sed для реплейса сигнатуры %%JNAME%% и %%IPV4_FIRST%% в темплейте на значения переменных фактов ${jname} и ${ipv4_first}, создавая итоговый файл ~cbsd/jails-system/JNAME/monit/monitrc. Эотт файл обрабатывается через добавленный нами include из основного конфигурационного файла /usr/local/etc/monitrc. Конечно, вы можете захотеть добавлять и использовать другие факты при необходимости. Кроме генерации конфигурационного файла, скрипты выполняют reload сервиса для применения конфигурации.
На этом настройка monit и CBSD завершена! Нам остается создавать в системном каталоге конфигурацию для monit по проверке тех или иных событий, пользуясь стандартной документацией monit.
Пример
Давайте создадим контейнер с именем lb1, в котором предполагается использование WEB сервера на базе nginx в качестве load-balancer. monit настроим на проверку открытого 80/tcp порта и в случае, если сервис nginx по каким-то причинам не обслуживает этот порт, заставим monit перезагрузить контейнер.
Создадим контейнер с nginx:
cbsd jcreate jname=lb1 pkglist=nginx sysrc=nginx_enable=YES
Скопируем пример для проверки и рестарта контейнера без каких-либо модификаций в каталог ~cbsd/jails-system/lb1/monit/:
mkdir ~cbsd/jails-system/lb1/monit/ cp -a /usr/local/cbsd/modules/monit.d/share/monitrc.tpl ~cbsd/jails-system/lb1/monit/
Запустим контейнер и проверим конфигурацию monit через monit status. Сервис должен иметь задачу с именем контейнера lb1:
cbsd jstart lb1 monit status
Теперь симулируйте отказ в ослуживании nginx, достаточно его просто остановить:
cbsd jexec jname=lb1 service nginx stop
и наблюдайте что произойдет дальше.