суббота, 15 ноября 2014 г.

Собрались как-то packer, docker и puppet...

Построение docker-контейнеров из Dockerfile отличный путь, но непереносимый.

Что если после окончания разработки мы захотим перенести наше окружение один в один на production без использования контейнеров?

Понадобится переписывать Dockerfile на нечто другое, в зависимости от провайдера.

Но можно этого избежать, если сразу строить docker-контейнер с помощью packer.io без Dockerfile. Тогда всё что нужно будет сделать, это заменить (или добавить) секцию builders в конфиге packer, и он построит идентичное окружение на поддерживаемом провайдере.

А так как поддерживается docker, amazon, digitalocean, vagrantbox, parallels и virtualbox — скорее всего, нам этих возможностей хватит.

Packer поддерживает несколько средств для provisioning, shell скрипт, ansible,  chef и прочие, но так как моя инфраструктура уже построена на puppet, и писать скрипты повторно мне лень, буду использовать его.

Первое что нам понадобится, это автоматическое подписывание сертификатов puppet. Если у вас еще не настроено, укажите в
autosign.conf домен которому мы будем доверять, например
*.mydomain
Я также, доставляю ряд файлов через транспорт puppet, поэтому мне необходимо добавить в fileserver.conf
[files]
  ...
  allow *.mydomain

Теперь при получении запроса от клиента из домена mydomain puppet master будет доверять этому сертификату, подпишет его, и разрешит отправлять туда файлы.


Второе, нам необходимо создать условия для работы puppet agent, для этого мы с помощью shell provisioning установим сам puppet на клиентскую машину:
  "provisioners": [
        {
            "type": "shell",
            "inline": [
                "apt-get -y update",
                "apt-get install -y puppet"
            ]   
И не забудем вписать опции для puppet provisioning:

            "puppet_server": "{{user `puppet_master`}}",
            "prevent_sudo": true,
            "options": "--fqdn={{user `hostname`}}.{{user `domain`}} --waitforcert=10 --verbose",
            "facter": {
                "server_role": "dev_server"
            }
В двойных фигурных скобках {{}} наши переменные для шаблона.

Часть из них мы зашьём в конфиг, например имя домена:
    "variables": {
        ...
        "domain":   "mydomain",

Часть передадим через параметры при построении образа, вот так:

packer build -var 'puppet_master=mymaster.puppet.mydomain.ru' docker.json

Конфиг целиком выложил на github


Всё готово: запускаем построение packer build:

И видим что сертификат puppet сгенерирован,  подписан, и рецепт выполнился.

После окончания работы получаем готовый образ docker:





Которому мы назначили tag из post-processor.


Можно запускать и использовать.

Когда работа будет сделана, и всё отлажено, мы сможем воссоздать это окружение напрямую например на DigitalOcean просто заменив
    "builders": [{
            "type": "docker",

на 
"type": "digitalocean",
и вписав ключи доступа для DO.