Данная статья предназначена для тех, кто использует или планирует начать использовать систему управления конфигурацией Opscode Chef.
Основная задача внедрения любой системы управления конфигурацией, будь то Chef, Puppet или что-то еще, — повторяемо воспроизводить и обновлять окружение всех сред, использующихся при разработке ПО (dev, CI, QA, stage, production). Отсюда следует, что само описание конфигурации необходимо однозначно хранить и обновлять. К сожалению, возможности по версионированию, которые есть в Chef, достаточно ограничены. Поэтому в связке с Chef в последнее время стали активно использовать Librarian. Но перед тем, как рассказать о нем, поговорим немного о кукбуках.
Кукбуки (более подробно о том, что это такое, можно прочитать здесь) можно разделить на 3 вида:
В вашем проекте все кукбуки могут лежать в папке cookbooks под управлением системы контроля версий. И если для собственных кукбуков это единственный разумный способ, то для кукбуков первых двух видов это решение кажется достаточно странным. По той простой причине, что проверять обновление, управлять зависимостями и обновлять такие кукбуки вам придется в „ручном“ режиме. Помимо всего прочего, если вы возьмете кукбук и просто добавите его в папку cookbooks, вспомнить потом, откуда вы его взяли, будет крайне непросто. Кукбуки с GitHub можно хранить как git submodules, но это не решает большинства проблем, которые здесь перечислены.
Более того, если какой-то из используемых вами кукбуков имеет зависимости (они прописаны в файле metadata.rb кукбука), то добавлять зависимости в проект вам придется вручную.
Все эти проблемы можно избежать, если использовать Librarian. Это инструмент, который помогает управлять зависимостями и версиями ваших кукбуков.
Есть еще похожий проект, который делает почти то же самое, — Berkshelf. Он появился позже Librarian, тянет с собою кучу зависимостей, имеет в 2 раза меньше инсталляций (судя по rubygems), но зато чуть лучше документирован. Выбор одного из них — исключительно дело вкуса. В любой момент можно перейти на другой инструмент, потому что файлы описания зависимостей у них идентичны. Мы используем Librarian, но то, что написано дальше, практически полностью актуально и для Berkshelf.
Представим себе очень простой проект, в котором используется совсем немного кукбуков. Начнем использовать librarian с помощью команды
Добавим в наш файл одну строчку и выполним
Данная команда поставит все необходимые кукбуки в папку cookbooks и создаст файл
Мы храним локальные для проекта кукбуки в папке inhouse-cookbooks. Это те кукбуки, которые специфичны именно для этого проекта. В
Также в
Такая комбинация возможностей позволяет легко и удобно всегда собирать одни и те же кукбуки в папке cookbooks.
Надо четко понимать, что актуальный «срез» всех кукбуков хранится в файле Cheffile.lock, а файл Cheffile является только «подсказкой» о том, как Cheffile.lock собирать, и его одного для версионирования кукбуков недостаточно. Если у вас нет Cheffile.lock, то в зависимости от того, в какое время вы выполнили команду
Более того, если вы явно укажете версии необходимых вам кукбуков, обновление кукбуков станет гораздо более сложным.
Но что делать, если необходимо обновить какой-то кукбук? Например, мы узнали, что вышла версия кукбука lvm, с какими-то нужными нам изменениями. Тогда мы делаем следующее:
Данная команда обновит кукбук lvm на последний доступный. Более того, она обновит все зависимости кукбука lvm, если это будет необходимо. Мы рекомендуем после этого делать
Можно это понимать еще и так: Cheffile — это описание необходимых требований к версиям кукбуков на текущий момент, а Cheffile.lock — это срез, удовлетворяющий этим требованиям на текущий момент.
И еще один момент, который не стоит забывать, при работе с librarian. Каждый раз перед тем, как залить какой-то рецепт на chef-server, необходимо делать
Возможно, такой подход может показаться несколько сложным, но он того стоит. Ведь он гарантирует всегда актуальный срез кукбуков, автоматическое управление зависимостями, а также гибкость использования локальных кукбуков, кукбуков с сайта Opscode и кукбуков из различных git-репозитариев, в том числе с гитхаба.
Основная задача внедрения любой системы управления конфигурацией, будь то Chef, Puppet или что-то еще, — повторяемо воспроизводить и обновлять окружение всех сред, использующихся при разработке ПО (dev, CI, QA, stage, production). Отсюда следует, что само описание конфигурации необходимо однозначно хранить и обновлять. К сожалению, возможности по версионированию, которые есть в Chef, достаточно ограничены. Поэтому в связке с Chef в последнее время стали активно использовать Librarian. Но перед тем, как рассказать о нем, поговорим немного о кукбуках.
Кукбуки (более подробно о том, что это такое, можно прочитать здесь) можно разделить на 3 вида:
- кукбуки с сайта community.opscode.com;
- кукбуки с GitHub и других мест;
- собственные кукбуки проекта.
В вашем проекте все кукбуки могут лежать в папке cookbooks под управлением системы контроля версий. И если для собственных кукбуков это единственный разумный способ, то для кукбуков первых двух видов это решение кажется достаточно странным. По той простой причине, что проверять обновление, управлять зависимостями и обновлять такие кукбуки вам придется в „ручном“ режиме. Помимо всего прочего, если вы возьмете кукбук и просто добавите его в папку cookbooks, вспомнить потом, откуда вы его взяли, будет крайне непросто. Кукбуки с GitHub можно хранить как git submodules, но это не решает большинства проблем, которые здесь перечислены.
Более того, если какой-то из используемых вами кукбуков имеет зависимости (они прописаны в файле metadata.rb кукбука), то добавлять зависимости в проект вам придется вручную.
Все эти проблемы можно избежать, если использовать Librarian. Это инструмент, который помогает управлять зависимостями и версиями ваших кукбуков.
Есть еще похожий проект, который делает почти то же самое, — Berkshelf. Он появился позже Librarian, тянет с собою кучу зависимостей, имеет в 2 раза меньше инсталляций (судя по rubygems), но зато чуть лучше документирован. Выбор одного из них — исключительно дело вкуса. В любой момент можно перейти на другой инструмент, потому что файлы описания зависимостей у них идентичны. Мы используем Librarian, но то, что написано дальше, практически полностью актуально и для Berkshelf.
Представим себе очень простой проект, в котором используется совсем немного кукбуков. Начнем использовать librarian с помощью команды
init
, которая создает начальный файл Cheffile
— в нем будет храниться описание используемых вами кукбуков.$ librarian-chef init
create Cheffile
$ cat Cheffile
site 'http://community.opscode.com/api/v1'
Добавим в наш файл одну строчку и выполним
librarian-chef install
$ cat Cheffile
site 'http://community.opscode.com/api/v1'
cookbook 'lvm'
$ librarian-chef install
Installing lvm (0.8.6)
Данная команда поставит все необходимые кукбуки в папку cookbooks и создаст файл
Cheffile.lock
.$ ls cookbooks
lvm
$ cat Cheffile.lock
SITE
remote: http://community.opscode.com/api/v1
specs:
lvm (0.8.6)
DEPENDENCIES
lvm (>= 0)
Мы храним локальные для проекта кукбуки в папке inhouse-cookbooks. Это те кукбуки, которые специфичны именно для этого проекта. В
Cheffile
мы добавляем следующее:cookbook 'project42',
:path => 'inhouse-cookbooks/project42'
Также в
Cheffile
можно ссылаться на конкретные ревизии кукбуков в гите.cookbook "postgresql",
:git => "git@github.com:express42-cookbooks/postgresql.git",
:ref => "0.1.4"
cookbook "newrelic",
:git => "git@github.com:heavywater/chef-newrelic.git",
:ref => "b2309495b367da4bfe6f1761876b5d58e2455d6a"
Такая комбинация возможностей позволяет легко и удобно всегда собирать одни и те же кукбуки в папке cookbooks.
Надо четко понимать, что актуальный «срез» всех кукбуков хранится в файле Cheffile.lock, а файл Cheffile является только «подсказкой» о том, как Cheffile.lock собирать, и его одного для версионирования кукбуков недостаточно. Если у вас нет Cheffile.lock, то в зависимости от того, в какое время вы выполнили команду
librarian-chef install
, Cheffile.lock у вас получится разным. Даже если вы зафиксируете явно все версии используемых кукбуков в Cheffile (чего делать категорически не советуется), то кукбуки, которые соберутся по зависимостям, могут отличаться.Более того, если вы явно укажете версии необходимых вам кукбуков, обновление кукбуков станет гораздо более сложным.
Но что делать, если необходимо обновить какой-то кукбук? Например, мы узнали, что вышла версия кукбука lvm, с какими-то нужными нам изменениями. Тогда мы делаем следующее:
$ librarian-chef update lvm
Данная команда обновит кукбук lvm на последний доступный. Более того, она обновит все зависимости кукбука lvm, если это будет необходимо. Мы рекомендуем после этого делать
git diff Cheffile.lock
, чтобы убедиться, что поменялось ровно то, что вы хотели. Кстати, если вы пропишете в Cheffile версию для какого-то кукбука, от которого зависит lvm, то lvm может и не обновиться, и вам долго придется гадать, почему это происходит.Можно это понимать еще и так: Cheffile — это описание необходимых требований к версиям кукбуков на текущий момент, а Cheffile.lock — это срез, удовлетворяющий этим требованиям на текущий момент.
И еще один момент, который не стоит забывать, при работе с librarian. Каждый раз перед тем, как залить какой-то рецепт на chef-server, необходимо делать
git pull
и librarian-chef install
. Потому что если кто-то залил более свежий рецепт, в вашей локальной папке cookbooks автоматически ничего не поменяется.Возможно, такой подход может показаться несколько сложным, но он того стоит. Ведь он гарантирует всегда актуальный срез кукбуков, автоматическое управление зависимостями, а также гибкость использования локальных кукбуков, кукбуков с сайта Opscode и кукбуков из различных git-репозитариев, в том числе с гитхаба.