Этот пост получился в результате моего ознакомления с Otto, одним из последних продуктов Hashicorp, о котором уже была обзорная статья на хабре.
Мой пост носит более практический характер. Я решил поднять на otto стандартный проект, чтобы сразу не наткнуться на тонкости настройки, а чтобы было интересно, выбрал Drupal 8, вышедший недавно.
Последняя версия, отмеченная тегом — 0.1.2 от 20.10.2015. Забегая вперед, скажу, что у меня не получилось сходу настроить MySQL на ней, а еще, заглянув в CHANGELOG, решил попробовать master ветку из-за Layered Dev Environments.
Otto 0.1.3-dev требует Vagrant 1.7.99+, так как стабильная версия 1.7.4, это значит, что Vagrant тоже нужен из master ветки.
Компиляция обоих проектов хорошо описана на страницах otto и vagrant, мне хватило полчаса, чтобы поставить golang, настроить gopath и скомпилировать оба проекта без знания Go и Ruby.
Главное не забыть добавить
Перезапускаем терминал, проверяем, что у нас запускаются dev-версии: 'vagrant version', 'otto version'.
Скачаем Drupal 8:
Appfile — основной файл конфигурации otto для проекта, должен быть в корне проекта.
Вообще его может вообще не быть, тогда otto сам определит требования к окружению, в котором может запуститься приложение. Логика определения типа приложения проще некуда, например, проект будет определен как php, если в корне есть файлы *.php
Первая команда, которая нужна в otto — 'otto compile'. Она анализирует проект и его Appfile, после чего генерирует дерево в папке .otto, содержащее всю информацию о конфигурации dev и deploy окружений.
Документация советует не править руками содержимое этой папки. Но смотреть можно и нужно.
Также будет сгенерирован .ottoid — уникальный идентификатор вашего приложения, по которому otto будет отслеживать его деплой, хранить историю, использовать его как зависимость и т.д.
К этому моменту наше окружение описано и готово к развертыванию.
Следующее, что нужно — развернуть локальное dev окружение на локальной машине.
По сути, otto dev — то же самое, что vagrant up.
Интересна концепция слоев, они очень похожи на слои Docker: при первом запуске 'otto dev' виртуальное окружение Vagrant будет настраиваться последовательно, делая снимок после каждого шага. Слои описаны в типе приложения. Всё это позволяет сильно сократить время пересоздания dev окружения. Таким образом, мы получаем мгновенный запуск готового окружения даже при полном пересоздании виртуальной машины. Разница между перезапуском и пересозданием машины ('otto dev halt && time otto dev' и 'otto dev destroy && time otto dev') составляет около 5 секунд.
Судя по changelog, vagrant этот функционал не получит, по крайней мере в следующей версии, зато в Vagrant появится функционал для создания snapshots.
Посмотреть слои можно командой 'otto dev layers':
В результате, в случае PHP приложения, otto должен выдать дальнейшие инструкции:
Что мы получили с автоматической настройкой?
Для работы Drupal критически не хватает MySQL.
Простейший способ добавить MySQL: указать зависимость. Создадим Appfile в корне проекта:
Этот конфиг явно указывает тип приложения (php) и добавляет MySQL как зависимость.
Несмотря на то, что ссылка в source невалидная, otto ее поймет, есть и другие форматы source.
Есть способ добавить mysql еще проще, но он неправильный, я скажу о нем в недостатках.
Appfile mysql описывает зависимое приложение как Docker-контейнер, путь к образу контейнера и параметры запуска. В результате мы получим запущенный контейнер внутри Vagrant, благодаря Consul он будет доступен по адресу mysql.service.consul (внутри виртуалки) с юзером и паролем root:root. Настроенный по умолчанию Consul существенно облегчает использование Docker, можно не разбираться в тонкостях настройки service discovery, а просто пользоваться.
Зависимостью может быть любое другое приложение, но настоятельно рекомендуется, чтобы оно имело .ottoid файл, который позволит otto понять, что он запускает, даже если приложение будет переименовано.
Зависимости в данный момент не поддерживают версионность (в будущем обещают добавить), это значит, что при каждом 'otto compile' у вас есть шанс получить не то, что вы ожидали, поэтому стоит форкнуть зависимости себе или положить на локальной машине.
Делаем 'otto compile', 'otto dev destroy', 'otto dev' — получаем машину, готовую к запуску Drupal. Осталось запустить в ней сервер.
Заходим в виртуалку по SSH. Выполняем указанную выше команду запуска встроенного в PHP web-сервера, я не вижу ничего плохого в запуске под root на 80 порту на dev:
После этого можно заходить открывать в браузере IP адрес, который выдал 'otto dev', можно его получить явно, выполнив 'otto dev address'.
Видно, что код местами довольно прототипный. Например, в Vagrantfile используется bash для разворачивания окружения, а не ansible или что-то подобное.
Я заглянул в код App type php, нашел там определение того, что запускаемое приложение — wordpress (по наличию файла wp-config.php), единственное отличие от стандартного php приложения — автоматическое добавление mysql в зависимости. То есть сейчас можно указать в Appfile 'type = «wordpress»' или сделать 'touch wp-config.php', чтобы получить mysql, но, конечно, так делать не стоит.
Судя по issue tracker проекта, best practices еще не готовы и не совсем понятно, как будут готовиться. Например, в случае PHP, есть Hashicorp, которые не знают особенностей окружения PHP проектов и программисты PHP, которые не знают Go и не могут отправить pull request.
Митчелл Хашимото, автор Otto, предлагает всем заинтересованным писать на Github предложения с улучшениями, ссылки на статьи с настройкой правильного окружения, а Hashicorp позаботится об их интеграции в продукт. Мне кажется, что позже появятся абстракции, которые дадут возможность широкому кругу не-go программистов помогать в развитии продукта.
До команд 'otto infra' и 'otto deploy' я не добрался, но узнал, что сейчас они поддерживают только AWS и что для php проектов dev-окружение отличается от deploy-окружения, в первом случае предлагается запускать встроенный в PHP сервер, во втором поднимается apache2 с mod-php.
Otto в данный момент не дает возможность кастомизировать Vagrantfile dev-окружения через Appfile. Смотрим .otto/compiled/app/dev/Vagrantfile, оказывается, в нем прописаны параметры монтирования /vagrant, несовместимые с NFS. Исправляем строку на что-то вроде:
Следующий 'otto compile' затрет эти изменения.
Единственный способ сделать правильно: полностью переопределить Vagrantfile, используя application type = «custom», но в таком случае вся магия автонастройки окружения пропадает.
Я сделал для себя вывод, что Otto еще не готов для полноценного использования, на что в общем-то намекает версия продукта 0.1. Тем не менее продукт очень интересный и уже сейчас имеет преимущества по сравнению с Vagrant, а все недостатки объясняются новизной Otto, разработчики о них знают и имеют планы по устранению.
Сейчас непонятно, как создавать свои слои, когда слои появятся в Otto полноценно, для меня это будет достаточной причиной, чтобы перейти на него с Vagrant'а.
Мой пост носит более практический характер. Я решил поднять на otto стандартный проект, чтобы сразу не наткнуться на тонкости настройки, а чтобы было интересно, выбрал Drupal 8, вышедший недавно.
Установка
Последняя версия, отмеченная тегом — 0.1.2 от 20.10.2015. Забегая вперед, скажу, что у меня не получилось сходу настроить MySQL на ней, а еще, заглянув в CHANGELOG, решил попробовать master ветку из-за Layered Dev Environments.
Otto 0.1.3-dev требует Vagrant 1.7.99+, так как стабильная версия 1.7.4, это значит, что Vagrant тоже нужен из master ветки.
Компиляция обоих проектов хорошо описана на страницах otto и vagrant, мне хватило полчаса, чтобы поставить golang, настроить gopath и скомпилировать оба проекта без знания Go и Ruby.
Главное не забыть добавить
export PATH="$GOPATH/bin:$PATH"
Перезапускаем терминал, проверяем, что у нас запускаются dev-версии: 'vagrant version', 'otto version'.
Настройка NFS
Напрямую к otto не относится, но, узнав об ужасной тормознутости стандартных virualbox shared folders, осознал необходимость настроить NFS.
На Ubuntu достаточно установить пакеты nfs-common nfs-kernel-server и добавить в /etc/sudoers несколько строк, чтобы Vagrant не спрашивал пароль при каждом запуске, подробнее в документации.
Для Windows есть сторонние решения для запуска NFS сервера и прикручивания его к Vagrant.
NFS работает только если определена хотя бы одна сеть private network. Это касается только Virtualbox.
На Ubuntu достаточно установить пакеты nfs-common nfs-kernel-server и добавить в /etc/sudoers несколько строк, чтобы Vagrant не спрашивал пароль при каждом запуске, подробнее в документации.
sudoers для Ubuntu 15.10
В Ubuntu 15.10 перестали срабатывать правила из текущей документации, которые работали в 14.04, в Vagrant 1.7.4 не включен pull request с исправленными правилами:
Cmnd_Alias VAGRANT_EXPORTS_ADD = /usr/bin/tee -a /etc/exports
Cmnd_Alias VAGRANT_NFSD_CHECK = /etc/init.d/nfs-kernel-server status
Cmnd_Alias VAGRANT_NFSD_START = /etc/init.d/nfs-kernel-server start
Cmnd_Alias VAGRANT_NFSD_APPLY = /usr/sbin/exportfs -ar
Cmnd_Alias VAGRANT_EXPORTS_REMOVE = /bin/sed -r -e * d -ibak /*/exports
Cmnd_Alias VAGRANT_EXPORTS_REMOVE_2 = /bin/cp /*/exports /etc/exports
%sudo ALL=(root) NOPASSWD: VAGRANT_EXPORTS_ADD, VAGRANT_NFSD_CHECK, VAGRANT_NFSD_START, VAGRANT_NFSD_APPLY, VAGRANT_EXPORTS_REMOVE, VAGRANT_EXPORTS_REMOVE_2
Для Windows есть сторонние решения для запуска NFS сервера и прикручивания его к Vagrant.
NFS работает только если определена хотя бы одна сеть private network. Это касается только Virtualbox.
Подготовка проекта
Скачаем Drupal 8:
git clone https://github.com/drupal/drupal.git drupal8
cd drupal8
Appfile
Appfile — основной файл конфигурации otto для проекта, должен быть в корне проекта.
Вообще его может вообще не быть, тогда otto сам определит требования к окружению, в котором может запуститься приложение. Логика определения типа приложения проще некуда, например, проект будет определен как php, если в корне есть файлы *.php
otto compile
Первая команда, которая нужна в otto — 'otto compile'. Она анализирует проект и его Appfile, после чего генерирует дерево в папке .otto, содержащее всю информацию о конфигурации dev и deploy окружений.
Документация советует не править руками содержимое этой папки. Но смотреть можно и нужно.
Также будет сгенерирован .ottoid — уникальный идентификатор вашего приложения, по которому otto будет отслеживать его деплой, хранить историю, использовать его как зависимость и т.д.
К этому моменту наше окружение описано и готово к развертыванию.
otto dev
Следующее, что нужно — развернуть локальное dev окружение на локальной машине.
По сути, otto dev — то же самое, что vagrant up.
Layered Dev Environments
Интересна концепция слоев, они очень похожи на слои Docker: при первом запуске 'otto dev' виртуальное окружение Vagrant будет настраиваться последовательно, делая снимок после каждого шага. Слои описаны в типе приложения. Всё это позволяет сильно сократить время пересоздания dev окружения. Таким образом, мы получаем мгновенный запуск готового окружения даже при полном пересоздании виртуальной машины. Разница между перезапуском и пересозданием машины ('otto dev halt && time otto dev' и 'otto dev destroy && time otto dev') составляет около 5 секунд.
Судя по changelog, vagrant этот функционал не получит, по крайней мере в следующей версии, зато в Vagrant появится функционал для создания snapshots.
Посмотреть слои можно командой 'otto dev layers':
$ otto dev layers
consul
php5.6
В результате, в случае PHP приложения, otto должен выдать дальнейшие инструкции:
$ otto dev
IP address: 100.66.143.21
A development environment has been created for writing a PHP app.
You can access the environment from this machine using the IP address above.
For example, if you start your app with 'php -S 0.0.0.0:5000', then you can
access it using the above IP at port 5000.
Что мы получили с автоматической настройкой?
- Ubuntu 12.04 (на данный момент нельзя выбирать базовый образ системы)
- Consul
- PHP 5.6 (otto устанавливает PHP не из стандартного репозитория, а из PPA)
- Composer
Для работы Drupal критически не хватает MySQL.
Dependencies
Простейший способ добавить MySQL: указать зависимость. Создадим Appfile в корне проекта:
application {
name = "drupal8"
type = "php"
dependency {
source = "github.com/hashicorp/otto/examples/mysql"
}
}
Этот конфиг явно указывает тип приложения (php) и добавляет MySQL как зависимость.
Несмотря на то, что ссылка в source невалидная, otto ее поймет, есть и другие форматы source.
Есть способ добавить mysql еще проще, но он неправильный, я скажу о нем в недостатках.
Appfile mysql описывает зависимое приложение как Docker-контейнер, путь к образу контейнера и параметры запуска. В результате мы получим запущенный контейнер внутри Vagrant, благодаря Consul он будет доступен по адресу mysql.service.consul (внутри виртуалки) с юзером и паролем root:root. Настроенный по умолчанию Consul существенно облегчает использование Docker, можно не разбираться в тонкостях настройки service discovery, а просто пользоваться.
Зависимостью может быть любое другое приложение, но настоятельно рекомендуется, чтобы оно имело .ottoid файл, который позволит otto понять, что он запускает, даже если приложение будет переименовано.
Зависимости в данный момент не поддерживают версионность (в будущем обещают добавить), это значит, что при каждом 'otto compile' у вас есть шанс получить не то, что вы ожидали, поэтому стоит форкнуть зависимости себе или положить на локальной машине.
Делаем 'otto compile', 'otto dev destroy', 'otto dev' — получаем машину, готовую к запуску Drupal. Осталось запустить в ней сервер.
otto dev ssh
Заходим в виртуалку по SSH. Выполняем указанную выше команду запуска встроенного в PHP web-сервера, я не вижу ничего плохого в запуске под root на 80 порту на dev:
sudo php -S 0.0.0.0:80
После этого можно заходить открывать в браузере IP адрес, который выдал 'otto dev', можно его получить явно, выполнив 'otto dev address'.
Недостатки
Сырой код
Видно, что код местами довольно прототипный. Например, в Vagrantfile используется bash для разворачивания окружения, а не ansible или что-то подобное.
Я заглянул в код App type php, нашел там определение того, что запускаемое приложение — wordpress (по наличию файла wp-config.php), единственное отличие от стандартного php приложения — автоматическое добавление mysql в зависимости. То есть сейчас можно указать в Appfile 'type = «wordpress»' или сделать 'touch wp-config.php', чтобы получить mysql, но, конечно, так делать не стоит.
Окружения не проработаны
Судя по issue tracker проекта, best practices еще не готовы и не совсем понятно, как будут готовиться. Например, в случае PHP, есть Hashicorp, которые не знают особенностей окружения PHP проектов и программисты PHP, которые не знают Go и не могут отправить pull request.
Митчелл Хашимото, автор Otto, предлагает всем заинтересованным писать на Github предложения с улучшениями, ссылки на статьи с настройкой правильного окружения, а Hashicorp позаботится об их интеграции в продукт. Мне кажется, что позже появятся абстракции, которые дадут возможность широкому кругу не-go программистов помогать в развитии продукта.
Dev отличается от prod
До команд 'otto infra' и 'otto deploy' я не добрался, но узнал, что сейчас они поддерживают только AWS и что для php проектов dev-окружение отличается от deploy-окружения, в первом случае предлагается запускать встроенный в PHP сервер, во втором поднимается apache2 с mod-php.
Dev плохо кастомизируется
Otto в данный момент не дает возможность кастомизировать Vagrantfile dev-окружения через Appfile. Смотрим .otto/compiled/app/dev/Vagrantfile, оказывается, в нем прописаны параметры монтирования /vagrant, несовместимые с NFS. Исправляем строку на что-то вроде:
config.vm.synced_folder '/home/popstas/projects/site/drupal8', "/vagrant", type: "nfs"
Следующий 'otto compile' затрет эти изменения.
Единственный способ сделать правильно: полностью переопределить Vagrantfile, используя application type = «custom», но в таком случае вся магия автонастройки окружения пропадает.
Выводы
Я сделал для себя вывод, что Otto еще не готов для полноценного использования, на что в общем-то намекает версия продукта 0.1. Тем не менее продукт очень интересный и уже сейчас имеет преимущества по сравнению с Vagrant, а все недостатки объясняются новизной Otto, разработчики о них знают и имеют планы по устранению.
Сейчас непонятно, как создавать свои слои, когда слои появятся в Otto полноценно, для меня это будет достаточной причиной, чтобы перейти на него с Vagrant'а.
caballero
Рискую показаться занудой, но такое впечатление что количество инструментариев скоро превысит количество ПО для которого оные создаются. Типа количество гаечных ключей скоро будет превышать количество гаек.
popstas
Да, такое впечатление, что скоро любую задачу можно будет решить, установив нужный софт и написав правильный конфиг, но даже если это одна строчка (например, как добавление mysql в зависимости), чтобы понять, что и куда надо написать, нужно потратить больше времени, чем сделать то же самое руками.
С другой стороны, становится возможным то, чего раньше нельзя было добиться: повторяемость, переносимость и всё такое.
Вообще, конечно, необходимость менеджера менеджера виртуальных машин для упрощения жизни программиста сомнительна, если надо понимать, как это все работает.