Создаём Consul кластер в Vagrant

Vagrant logo

Для двух последних постов про Consul мне пришлось делать простую, но при этом нудную вещь: создавать Консул-кластер руками. Все три виртуальные машины. Дважды. То есть нужно было создать три VM, на каждую скачать Consul, распаковать, узнать IP адрес, скопировать файл настроек… В общем, скука.

С другой стороны, создание контейнеров в Docker — без пяти минут маленьких виртуальных машин — полностью автоматизировано. Есть Dockerfile для конфигурации одного контейнера, есть docker-compose для целой стайки. В общем, красота. Вот бы существовало что-нибудь похожее для конфигурации хостов целиком.

И похожее, оказывается, существует. Оно называется Vagrant, и там даже есть свой Vagrantfile для конфигураций. Почти как в Докер.

Что такое Vagrant

Согласно официальной документации, Vagrant — это инструмент для создания и конфигурации виртуальных сред. Виртуальных машин, другими словами. Если вдруг нам требуется создать и настроить виртуальную машину для разработки, тестов или каких-нибудь задач в продакшене, то можно либо сделать её руками (и забыть через неделю, что именно и как там настраивалось), либо занести шаги настроек в Vagrantfile и потом создавать хосты пачками. А ещё Vagrantfile можно хранить в git, тем самым отслеживая почему и как он менялся, делиться им с коллегами по цеху или даже тестировать конфигурацию хоста локально, прежде чем развернуть его в продакшен-облаке. Ведь тот же Vagrantfile, который пять минут назад создавал VM в VirtualBox, с минимальными изменениями можно использовать, чтобы развернуть её в AWS, Google или Azure.

План на сегодня

Так как я уже два раза создавал кластер из трёх практически идентичных машин, есть очень большая вероятность, что это случится и в третий раз. Так что почему бы не автоматизировать процесс?

А что, создадим Vagrantfile, а он сам развернёт три виртуальные машины в VirtualBox, установит и настроит Consul агентов, и сделает из них кластер. Романтика.

Что нам потребуется

Для игр в кластер и автоматизацию нам понадобятся Vagrant и VirtualBox. Процесс установки там простой, а закачки — вообще тривиальный. Работать я буду на Маке, но на Windows и основных породах Линукса процесс был бы точно таким же.

Шаг 0. Создаём пустую VM

Для создания виртуальной машины нам нужен Vagrantfile. С него и начнём:

Тут всё просто: init создаёт новый файл. Дальше идёт имя бокса — ubuntu/xenial64. Бокс (box) — это то, на базе чего создавать машину. Как базовый образ в Docker. В нашем случае это 64-битная Ubuntu 16.04 LTS. Наконец, так как init очень любит добавлять комментарии в Vagrantfile, а я — нет, --minimal параметр оставит в файле только полезное.

Итак, делаем в консоли vagrant up и через минуту-другую у нас будет полностью рабочая Убунта:

Vagrant использует VirtualBox в качестве провайдера для своих машин, но вообще-то это можно менять. Например, для Google Compute Engine я бы добавил такой параметр --provider=google.

После того, как машина запустилась, в неё можно зайти по SSH:

Шаг 1. Настраиваем VM

Теперь пришло время для настройки Консул-агентов, и логично начать с Консул-сервера. Вот, что нам нужно сделать с виртуальной машиной:

  1. Дать ей вменяемое название, например consul-server.
  2. Скачать и распаковать бинарники с Consul.
  3. Задать статический IP адрес (иначе как остальные члены кластера будут находить сервер?).
  4. Зарегистрировать и запустить Consul как Ubuntu сервис.

Шаг 1.1. Задаём имя хоста

Для этого придётся лезть в Vagrantfile. Для начала, вот что для нас создал init --minimal:

Чтобы задать имя хоста, нужно добавить всего одну написанную на Ruby строку:

Теперь перезапускаем машину через vagrant reload, заходим по SSH ещё раз и любуемся результатом:

Шаг 1.2. Устанавливаем Consul через shell

Следующий шаг немного сложнее. В определённых кругах процесс  настройки сервера называется провиз.. провижин… provisioning… настройкой. Процесс настройки сервера называется настройкой, да. Вагрант умеет делать это разными способами.  Например, shell провижинер (ну не учился я на переводчика) — запускает шелл-файл. file — просто копирует файл или папку с хоста туда, куда скажут. Есть ещё ansible, chef и даже puppet провижинеры,  которые делают вообще всё, что угодно.

Мне настраивать линуксовый хост проще с шелла, так что его и будем использовать:

path указывает на скрипт с инструкциями, который тоже нужно создать:

Правда, если мы снова вызовем vagrant reload — ничего не изменится. Всё потому, что Vagrant настраивает машину только при запуске. Но его можно переубедить, выполнив vagrant reload --provision (или vagrant provision, если перезапуск не нужен). Запускаем, ждём, и вот он, установленный Consul:

Шаг 1.2.1. Опционально: делаем скрипт настроек идемпотентным

Есть старый джедайский трюк, который позволяет запускать скрипт с настройками несколько раз, и тот оказывается достаточно умным, чтобы не переустанавливать всё то, что уже установлено. Такой скрипт называется идемпотентным. Это очень удобно. Ведь если скрипт — в процессе разработки, то перезапускать его приходится часто.

Прямо сейчас настройки сводятся к следующему:

  • установить unzip
  • установить consul

Если provision.sh научить не переустанавливать ни то, ни другое, он станет и идемпотентней, и удобней. И это тоже просто сделать:

Шаг 1.3. Задаём статический IP

Легкотня. Две строки в Vagrantfile и магия готова. Тут важно не перестараться и выбрать адрес из правильного диапазона.

Шаг 1.4. Запускаем Consul в качестве Ubuntu сервиса

Это немного тяжело, но без автозапуска ведь весь пример будет бесполезен.

Чтобы превратить Consul в сервис Убунты, его нужно зарегистрировать в systemd. Можно скачать заготовку настроек сервиса отсюда, а затем скопировать её в /etc/systemd/system/ папку гостевой машины. Затем, так как consul теперь будет запускаться под root, по-хорошему его нужно перенести из домашней папки куда-нибудь в /usr/local/bin.

Чтобы не уводить фокус статьи в сторону, я опущу большинство деталей и оставлю только пару важных моментов (но все сырцы всё равно есть на github).

  1. Работая с VirtualBox, Vagrant монтирует папку с Vagrantfile к гостевой машине к /vagrant . Я использовал это поведение в provision.sh, чтобы скопировать скачанный ранее consul.service к остальным сервисам гостевой оси:
  2. В том же consul.service Consul агент запускается с опцией, заставляющей его искать свои настройки в /etc/systemd/system/consul.d/. Это просто прекрасно, так как теперь я могу создать какой-нибудь init.json на лету и скопировать его в ту папку для каждого из агентов. Для сервера это будет выглядеть так:
  3. Наконец, сервис нужно запустить. Это всего лишь ещё одна строка в Vagrantfile (но можно было бы и в provision.sh:

Шаг 1.5. Пробный запуск

Если вы ещё не спите, то самое время запустить vagrant reload --provision и зайти на 192.168.99.100:8500 в самом лучшем из браузеров (скоро это снова будет IE, муа-ха-ха!):

Consul сервер созданный Vagrant

Теперь там живёт Consul server, настоящий и рабочий. Машину с ним можно остановить, удалить, надругать или совершить иное непотребство, но потом снова выполнить vagrant up и у нас снова появится рабочий Consul сервер. Это чудесно.

Шаг 2. Добавляем машин в кластер

Vagrantfile может описывать несколько машин. Это же Ruby, там хоть hello world пиши. Дополнительные машины задаются через функцию define:

Прежде чем мы начнём создавать компанию Consul серверу, уже запущенную VM стоит удалить при помощи vagrant destroy -f.

Затем, думаю, стоит немного развлечь себя рефакторингом. Ведь обычные Консул-агенты похожи на Консул-сервер практически один-в-один. Перенеся общую часть в отдельную функцию, можно избежать греха копипасты.

При помощи этой функции воссоздать Консул-сервер можно в одну строку:

А теперь только посмотрите, как просто добавить ещё две машины в наш уютный кластер:

Ну здорово же! Мы создаём виртуальные машины в цикле! Когда это перестало быть офигенным?

Но на всякий случай убедимся, что кластер действительно работает:

Consul кластер в Vagrant

Да, всё работает. Кластер из трёх машин создался за несколько минут в полностью автоматическом режиме. Мне больше не придётся делать это вручную.

Здесь должно было быть заключение…

Но в полночь оно в голову не лезет.

Разве что такое наблюдение. Я сужу по себе, конечно, но почему-то автоматизировать создание хостов — тяжело. И дело даже не в технологической части проблемы, а чисто в психологии. Машины же большие, как можно вообще пытаться их создавать не руками? И почему-то всегда кажется, что каждая машина — уникальная. Штучный товар.

Потом машина начинает жить своей жизнью. Софт на ней устаревает, появляется надобность создать похожую машину для чего-нибудь ещё, или мигрировать в другое облако, но уже никто не помнит, что на ней установлено, и как вообще она работает.

С другой стороны, если машину создавать из файла конфигурации — это меняет всё. Хосты становятся предсказуемыми, документированными, а создавать их можно где угодно и пачками. И Вагрант делает это возможным.

У меня на работе есть примеры как из одного, так и из другого лагеря. Например, CI сервера создаются программно и из конфигурации. Если нужно что-то обновить — я просто обновляю конфигурацию, удаляю старые сервера, и добавляю новые.

С другой стороны, образ виртуальных машин для тестов создавался руками год назад. Мой страшный сон — что его нужно будет пересоздать на свежем Windows Server. Какие сертификаты там должны быть, какие протоколы включены — я уже без понятия.

Все исходники к этому посту можно найти на гитхабе.

Создаём Consul кластер в Vagrant: 2 комментария

  1. Здоровский набор статьей по консулу, спасибо

    Не уловил только — в статье кластер консула ставился локально?
    1) Если нет, непонятно почему не использовать для оркестрации описанные в статье тулы (ansible, chief) которые для этого и предназначены?
    2) по ходу в твоей схеме на ремоут хост машине можно поставить не сам консул, а докер контейнер с консулом, а порт 8500 прокинуть на хост машину

  2. Пожалуйста!
    Весь кластер физически находился на локальной машине, в трёх виртуальных убунтах на VirtualBox. Ansible можно было бы использовать для конфигурации (Vagrant его поддерживает), но всё-таки фокус был именно на Vagrant, так что не в этот раз. Тут даже консул оказался почти случайно — просто он и логически связывает с предыдущим постом, и кластер с ним выглядит лучше и убедительнее, чем просто hello-world.
    И да, с родным докер контейнер с консулом и docker-compose этот кластер тоже можно сделать. У меня в каком-то посте докерный консул даже мелькал (нашёл — http://dotsandbrackets.com/multi-host-docker-network-without-swarm-ru/, правда, тот контейнер всё равно в виртуалке. Но с проброшенным 8500м портом!).
    Но опять же, весь фокус был на виртуальных машинах и vagrant. Даже если этот фокус получился смазанным 🙂

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *