
Наш web-проект требует довольно сложного окружения, так как используется многосерверная архитектура. Поэтому нам было жизненно важно автоматизировать подготовку такого окружения. Для решения этой задачи мы используем Vagrant и Chef Solo.

Vagrant идеально подошёл для создания окружения разработчика. Разработчику достаточно сделать клон Vagrant-проекта, и выполнить команду «vagrant up». Все остальное делается автоматически: скачивание образа виртуальной машины (если его нет на машине разработчика), запуск виртуальной машины с настроенными сетевыми параметрами и общими каталогами, запуск системы управления конфигурацией. Это обеспечивает единое окружение для всех разработчиков, что очень важно для больших команд или сложных проектов.

Почему был выбран Chef, а не другая система управлениями конфигурациями (серьезно смотрели только на Puppet):
- большое community;
- много готовых рецептов;
- рецепты написаны на Ruby;
- предсказуемый порядок выполнения рецептов (в отличие от Puppet);
- поддерживается в Vagrant.
Chef Solo — это open-source версия Chef-клиента, которая позволяет использовать рецепты без Chef-сервера (рецепты должны быть физически расположенны на этой же машине). Chef Solo бесплатен, но имеет ряд ограничений по сравнению с клиент-серверным Chef'ом. Например, нет возможности использовать в рецептах поиск серверов по условиям.
Почему был выбран Chef Solo, а не клиент-серверный Chef:
- бесплатно (у нас больше 5 серверов, но еще не тысячи);
- безопасно (данные о наших серверах не хранятся на чужих серверах);
- просто (работа с локальными файлами вместо консольных команд Chef-серверу);
- сохраняется возможность легкого перехода на Chef-сервер (если серверов станет слишком много).
Chef Solo позволил полностью автоматизировать установку и настройку проекта на новом сервере. Разворачивание боевого сервера для нашего приложения обычно занимает около 10-15 минут (в зависимости от сложности рецептов).
Для управления серверами предназначен следующий проект. Из каталога данного проекта запускаются виртуальные машины с помощью Vagrant, а также выполняется подготовка настоящих серверов. В данном проекте уже добавлен один виртуальный сервер (demo), на котором устанавливается свежая версия nginx.
Структура проекта:
- cookbooks/: каталог чужих рецептов, загруженных извне и неподлежащих редактированию. Подробнее.
- data_bags/: каталог для хранения дополнительных данных, доступных из рецептов. Подробнее.
- environments/: каталог окружений. Под окружением понимается определенный набор настроек, применяемых для сервера, разворачиваемого с указанием данного окружения. Именно тут разделяются настройки development/production. Для возможности использования таких окружений необходима версия Chef Solo не ниже 11.6.0 и версия Vagrant не ниже 1.3.0. Подробнее.
- nodes/: файлы с атрибутами серверов. Для каждого сервера здесь должен присутствовать файл с именем равным его IP-адресу, содержащий значения атрибутов сервера, а также список ролей и рецептов, которые необходимо применить к серверу. Подробнее.
- roles/: каталог ролей. Под ролью понимается определенный набор настроек, применяемых для сервера, которому назначена данная роль. Серверу может быть назначено несколько ролей. Подробнее.
- site-cookbooks/: каталог своих рецептов. Содержит рецепты, написанные собственноручно для обеспечения специфических требований (например, деплой рабочих проектов). Этот каталог указывается в файлах «solo.rb» и «Vagrantfile» в качестве дополнительного хранилища рецептов.
- deploy.sh: скрипт для подготовки боевого сервера (подробности ниже).
- install.sh: скрипт для установки Chef Solo и его запуска на боевом сервере (подробности ниже).
- solo.rb: конфигурационный файл Chef Solo.
- Vagrantfile: файл настроек Vagrant. В нем перечисляются все виртуальные сервера.
Чтобы развернуть новый виртуальный сервер для разработки необходимо:
- В «Vagrantfile» связать имя сервера (например, «frontend») с его IP-адресом (например, «10.2.2.100»).
- В каталоге «nodes» создать JSON-файл атрибутов нового сервера (например, «10.2.2.100.json»).
- Запустить виртуальную машину командой «vagrant up» с указанием имени машины (например, «vagrant up frontend»). При первом запуске будет запущен Chef Solo, который выполнит все рецепты, указанные в соответствующем JSON-файле атрибутов. При этом будет использовано окружение «development» (это указано в «Vagrantfile»).
Чтобы поднять новый боевой сервер необходимо:
- В каталоге «nodes» создать JSON-файл атрибутов нового сервера (например, «23.144.12.15.json»).
- Запустить скрипт «deploy.sh» с указанием пользователя и IP сервера (например, " ./deploy.sh root@23.144.12.15"). Скрипт «deploy.sh» внутри себя осуществляет SSH-подключение к серверу, поэтому все дополнительные параметры, указанные при запуске этого скрипта, будут использованы в качестве параметров команды «ssh» (это важно при входе по ключу). Под Windows мы запускаем этот скрипт в Git Bash, так как для его выполнения нужны некоторые *nix-команды, которых нет в «cmd.exe».
Скрипт «deploy.sh» выполняет следующие действия:
- подключается к серверу через SSH;
- архивирует весь каталог проекта и передает архив через SSH на сервер;
- распаковывает архив на сервере в каталог "~/chef";
- запускает скрипт установки «install.sh».
Скрипт «install.sh» выполняет следующие действия:
- проверяет, установлен ли Chef Solo, и при необходимости устанавливает его. На серверах мы используем Ubuntu, поэтому для других систем возможно потребуется поправить команды для установки Chef.
- запускает Chef Solo с указанием конфигурационного файла «solo.rb» и JSON-файла настроек сервера. При этом будет использовано окружение «production» (это указано в «solo.rb»).
Кроме первоначальной подготовки сервера часто возникает необходимость обновить его конфигурацию. Например, нужно обновить некоторые пакеты, выложить новую версию приложения или применить последние изменения в рецептах. Для виртуального сервера эту операцию выполняет команда «vagrant provision #имя_машины#». Для боевого сервера нужно повторно запустить "./deploy.sh root@#ip_сервера#".
Скрипты «deploy.sh» и «install.sh» написаны по мотивам статьи Chef Solo tutorial: Managing a single server with Chef.
Вместо «deploy.sh» можно посмотреть на knife-solo, но у него есть несколько недостатков по сравнению с предложенным способом:
- на машину, с которой осуществляется подготовка сервера, придется ставить Chef;
- для работы под Windows требуется cygwin+rsync (нетривиальная настройка);
- установка Chef на сервере осуществляется через Opscode Installer, у которого есть проблемы с установкой некоторых gem-пакетов (эта проблема решается указанием своего скрипта установки).
Вот так, с помощью нехитрых приспособлений, можно относительно просто разворачивать виртуальные сервера для разработки и боевые сервера для рабочих проектов. Надеюсь, моя статья окажется кому-нибудь полезной.