Разработка и тестирование chef кукбуков с помощью инструмента Sparrowdo v2
Здравствуйте! Об инструменте sparrowdo и его применение в разработке сценариев конфигурации chef я писал уже ранее.
Что ж, за это время утекло много воды и я хотел снова немного раскрыть данную тему, собственно поэтому заголовок статьи содержит версию два.
Итак — sparrowdo — система управления конфигурациями написанная на замечательном языке Perl6, активно развивающимся в последнее время. В своей лично работе я нахожу sparrowdo очень удобным и органично сосуществующим с более мощной платформой управления конфигурация — opscode chef. На нескольких конкретных примерах я покажу как я использую chef вместе со sparrowdo. Это пост не будет очень длинным, но надеюсь даст понимание о чем идет речь ;)
Что мы имеем? В силу своей основной профессиональной деятельности мне приходится много писать всяческих chef кукбуков. В нашем проекте активно используется aws сервисы, поэтому создание сервера и установка на нем chef клиента — операция достаточно дешевая и нересурсоемкая, следовательно я могу запросто отлаживать chef рецепты, запуская chef клиента на удаленном сервере по ssh, вместо того что бы использовать более традиционный для таких случаев vagrant
Хорошо, таким образом процесс разработки и отладки кукбуков сводится к тому, что разрабатывая очередную версию рецептов, я обновляю кукбук на chef сервере посредством команды knife upload и запускаю тестируемый кукбук далее на удаленном сервере посредством команды chef-client
(с заданным ран листом). Собственно, вылавливая при этом различные ошибки и падения возникающие при деплое (если выражаться языком документации chef — конвергенции ноды)
При таком раскладе мне очень удобен sparrowdo — который в отличие от chef является push based инструментом управления конфигурациями или, попросту говоря, умеет выполнять свои сценарии на удаленном хосте по ssh.
Как вы уже можете начать догадываться — сценарий в этом случае будет такой — запустить chef клиента на удаленной машине.
Sparrowdo поддерживает модульность — вы можете расширять его базовую функциональность за счет модулей написанных на языке Perl6, поэтому специально для это задачи мною был написан модуль под названием Sparrowdo: Chef: Client
Интерфейс модуля достаточно прост — он предоставляет необходимый минимум для запуска chef клиента —, а именно указание ран листа и опционально задание атрибутов
Вот как будет выглядеть сценарий по запуску кукбука java с установкой атрибута, задающем версию устанавливаемого jdk:
$ cat sparrowfile
module_run 'Chef::Client', %(
run-list => [
"recipe[java]"
],
attributes => %(
java => %(
jdk_version => 7
),
),
log-level => 'info',
force-formatter => True
);
В наших проектах мы используем во основном jdk версии 7, поэтому я выставляю ее через соответствующий chef атрибут, который переопределяет дефолтное значение.
Вот как будет выглядеть отчет sparrowdo при запуске на удаленном сервере:
$ sparrowdo --host=remote.server --ssh_user=centos --ssh_private_key=/home/melezhik/.ssh/foo.pem
running sparrow tasks on remote.server ...
target OS is - centos7
enter module ...
push task plg OK
push task plg OK
set up task box file - /tmp/sparrowdo/task-box8938.json - OK
get index updates from SparrowHub ... OK
public@file is uptodate (0.0.5)
public@bash is uptodate (0.1.4)
running task box from /tmp/sparrow-cache/task-box8938.json ...
[t] set up chef run list and attributes at 2017-04-06 13:35:14
set target content
touch target
target created
set target mode to 644
ok scenario succeeded
ok text match /target (created|deleted)/
ok text has 'set target content'
STATUS SUCCEED
[t] run chef-client
@ runs bash command
[t] run chef-client modules/bash-command/ params: envvars: at 2017-04-06 13:35:14
[2017-04-06T13:35:15+00:00] INFO: Forking chef instance to converge...
Starting Chef Client, version 12.19.36
#
# вывод опущен
#
Chef Client finished, 7/9 resources updated in 38 seconds
ok scenario succeeded
STATUS SUCCEED
Хорошо, это простой пример показывает как мы можем управлять настройками запускаемых сhef кукбуков, выставляя ран лист и различные атрибуты. Приведу далее еще несколько интересных случаев.
тестирование прохождения граничных условий
Не секрет, что большо'е количество задач по управлению конфигрурациями и автоматизации связано с запуском сетевых сервисов. Например у нас есть кукбук, который настраивает и и перезапускает сервер nginx согласно какому-то нетривиальному набору правил. Я думаю, те кто писал подобного рода рецепты часто сталкивались с тем, что их сценарии могут вести себя по-разному относительно разных состояний сервиса в начале. Вот, например я хочу посмотреть что будет, и не упадет ли мой деплой если nginx не будет запущен до выполнения chef рецепта, с помощью sparrowdo, который сам по себе так же является инструментом управления конфигурациями это сделать легко:
$ cat sparrowfile
service-stop 'nginx'
module_run 'Chef::Client', %(
run-list => [
"recipe[nginx-app::configure]"
]
);
Согласитесь — что встраивать остановку nginx внутрь шеф рецептов, только для того, что бы протестировать поведение нашего основного кукбука, было бы не хорошо. А здесь с помощью sparrowdo мы делаем это легко и непринужденно, причем не меняя ничего в коде самого chef кукбука
встроенные post deployment / audit тесты
Часто требуется проверить работу шеф клиента после того, как он отработал. Есть различные варианты решения данной задачи — test-kitchen/ serverspec, goss, chef minitest-handler, inspec у всех у них есть свои плюсы и минусы. Но вот вам еще одна альтернатива — sparrowdo — основной смысл тот же — мы делаем проверки рядом, а точнее внутри sparrowdo сценария, вот одна из моих излюбленных проверок на то, что сервер tomcat запущен и «виден» в списке процессов — практика показывает, что иногда chef не отлавливает ситуации с падением перезапускаемого сервиса и нам необходимо делать это самим:
$ cat sparrowfile
service-stop 'nginx'
module_run 'Chef::Client', %(
run-list => [
"recipe[tomcat-app::configure]"
]
);
task-run 'check tomcat', 'proc-validate', %(
pid_file => '/var/run/tomcat7.pid',
footprint => 'java'
);
необязательные зависимости
И наконец, последний самый простой и очевидный случай (, но от этого его актуальность не теряется) — вам нужно временно поставить дополнительные пакеты и утилиты на тестируемый сервер. Вы не хотите включать это в ваши chef рецепты, потому что напрямую к установке приложений данные зависимости отношения не имеют, но они нужны вам для отладки устанавливаемых приложений, что ж, просто добавим их через sparrowdo, не меняя при этом код написанных вами chef рецептов.
Вот, например специализированный пакет, который нам вряд ли понадобится в продакшене, но
будет необходим, если мы захотим заняться дебаггингом java кода:
package-install 'java-1.7.0-openjdk-debuginfo'
module_run 'Chef::Client', %(
run-list => [
"recipe[java]"
]
);
На этом я заканчиваю. В заключении хочется сказать что в моей личной работе, связанной с ежедневной разработкой десятков кукбуков для сотен различных проектов sparrowdo зарекомендовал себя как отличный инструмент-компаньон существенно ускоряющий и упрощающий разработку и тестирование сценариев chef.
Как обычно, буду рад вопросам и конструктивной критики.