Виртуальные ресурсы в Puppet

puppet

 

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

 

Пример будет немного синтетическим. Мне было сложно придумать достаточно короткий пример, при этом демонстрирующий смысл виртуальных ресурсов.  На практике такие примеры с вшитыми именами пользователей встречаются редко. По крайней мере должны :)

 

Имеется сервер с установленным Apache. Установка и настройка производится удобно и модно puppet-классом apache. Для простоты все будем хранить в основном манифесте site.pp. Все появляющиеся проблемы в ходе развития примера актуальны и в случае разнесения кусков логики по модулям.

 

Допустим классу необходим unix-пользователь, в данном примере webUser, домашний каталог которого будет являться document root‘ом для веба. Тогда получим следующий скелет site.pp:

Все просто. Теперь мы решили добавить в нашу инфраструктуру nginx неважно для каких целей. Главное, что ему тоже нужен пользователь webUser для отдачи контента. Добавляем класс:

 

Запускаем:

По понятным причинам оно не работает. Получается, что в одной области виимости у нас два ресурса с одинаковым значением namevar. Решить проблему можно, например, вынеся ресурс пользователя в отдельный класс:

Запускаем – работает:

Предположим, что нам понадобилось добавить нового пользователя cacheUser в папке которого мы будем хранить какой-либо кэш. Этим кэшем пользуется как Apache, так и nginx, поэтому мы добавляем соотвествующего пользователя в класс users:

Далее мы решили добавить php5-fpm и uwsgi, которым нужен webUser, но не нужен cacheUser. В такой ситуацие придется выделять cacheUser в отдельный класс, чтобы подключать его отдельно только в классах apache и nginx. Это неудобно. Тут-то на помощь и приходят виртуальные ресурсы.

Если к определению ресурса добавить знак @:

Ресурс будет считаться виртуальным. Такой ресурс не будет добавляться в каталог агента до тех пор пока мы явно не определим. Из документации:

A virtual resource declaration specifies a desired state for a resource without adding it to the catalog

Поэтому если исполнить код ниже даже при остуствии в системе пользователей webUser и cacheUser они добавлены не будут:

Проверяем:

Пользователи, как и ожидалось, не добавились.

Но следует быть внимательным. Не смотря на то, что виртуальный ресурс не добавляется в каталог это не значит, что следующий код будет работать:

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

Для определения ресурса используется либо space ship оператор < | | > либо с помощью функция realize. Перепишем наш манифест с использованием как одного так и другого синтаксиса:

Функцию realize можно передавать сразу несколько ресурсов, в операторе <| |> можно указывать несколько условий, по котором делается поиск ресурсов для определения.

Помимо синтаксической разница в realize и <| |> имеются отличия и в поведение. Если ресурс с указанным названием не существует realize выдаст ошибку:

 

Оператор <| |> в таком случае ошибку не выдает, потому что он является своего рода надстройкой над функцией realize. В его теле указывается поисковый запрос. Пустой запрос означает “найти все”. Ко всем найденым ресурсам применяется функция realize, именно поэтому если ничего не найдено ошибки не выдается, так как не вызывается realize.

 

Кстати у оператора <| |> есть еще два достаточно хороших применения. Его можно использовать для переопределения состояния ресурса в подключаемом классе. Например:

Исключит файл /etc/apache2.conf для ноды s2.example.com. Используя его с операторами ~> и -> можно, например, уведомить все сервисы о каких-либо изменениях, либо потребовать перед установкой любого пакета добавить все yum репозитории:

 

На мой взгляд основное преимущество виртуальных ресурсов в том, что их можно экспортировать и делать доступными для других агентов. Чтобы экспортировать виртуальный ресурс необходим добавить еще один знак @ перед его описанием. Классический пример из документации Puppet:

В данном примере мы определили виртуальный ресурс sshkey. Оператор <<| |>> выгружает все экспортированные объекты класса Sshkey. Таким образом любой агент, в манифесте которого подключается класс ssh экспортирует свой публичный ключ (@@sshkey), а затем испортирует к себе все ключи, добавленные другими агентами (Sshkey <<| |>>).

 

Экспортируемые ресурсы хранятся в PuppetDB – БД от PuppetLabs. После подключение PuppetDB каждый скопилированный pupet master’ом каталог кладется в базу PuppetDB, которая в свою очередь предоставляет поисковый интерфейс для поиска по каталогам .

 

Ставя @@ и помечая ресурс как экспортируемый мы информируем puppet, что ресурс необходимо добавить в каталог и поставить ему метку exported. Когда puppet master видит оператор <<| |>> он делает поисквый запрос к PuppetDB и добавляет все найденные экспортированные ресурсы подходящие под критерий поиска.

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

 

У этого функционала огромный потенциал и мне достаточно часто приходится им пользоваться. Наверное, одна из наиболее полезных всем – мониторинг. В другой статье напишу как мы используем экспортируемые ресурсы для мониторинга обслуживаемых серверов.

Оставить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *