Nomad от HashiCorp это очередной scheduler для управления/ жизненным циклом различных задач запускаемых на группе серверов. Из коробки Nomad имеет драйверы для запуска Docker, rkt, LXC контейнеров и виртуальных машин QEMU-KVM. Так же поддерживается запуск отдельных процессов. Перечень драйверов и их описание.
Лично я рассматриваю Nomad как средство оркестрации Docker-контейнерами. Меня пугает монструозный Kubernetes а нативный Docker-swarm навязывает слишком много своих правил, например не всегда нужные overlay-сети и механизмы балансировки на базе LVS или dns-rr. Пока, что мы используем Puppet для деплоя docker-контейнеров описанных в yaml-файле. Puppet хорошо справляется с задачей созданияобновленияудаления контейнеров но при отказе сервера перераспределить контейнеры на другие ноды уже сложнее, это все такие не его стезя. В общем, мы периодически посматриваем на другие решения и надеемся найти, что то, что даст максимум свободы и при этом не будет иметь переусложненную архитектуру. Nomad — потенциальный кандидат
Коротко о архитектуре
Nomad как и большинство продуктов от HashiCorp поставляется в виде одного бинарного файла. Как и во многих проектах написанных на Go, Nomad может быть запущен с разными ключами и выполнять различные роли.
server — в производственной среды должно быть не меньше трех экземпляров на с ролью server. Экземпляры с этой ролью поддерживают кворум и реплицируют между собой всю информацию о кластере, задачах в нем и т.д. Собственно задача на выполнения(job) передается серверам а те в свою очередь запускают ее на серверах с ролью client.
сlient — рабочие лошадки кластера. Они подключаются к серверам, регистрируются и затем на них выполняются различные задачи запускаемые в кластере.
dev — эта специальная роль совмещающая в себе и server и client. Подходит для дебага или тестирования.
Nomad Client and Server Requirements
Quorum серверов
Интересно, что nomad позиционируется как средство позволяющее управлять миллионом контейнеров на тысячах серверов но при этом на оф. сайте нет информации по настройке производственной среды. Все что есть на тему настройки в их документации это vagrant up
. Я не использую vagrant и по этой причине я и решил написать заметку по настройке похожего на производственный кластера.
Итак, я использую CentOS 7.3 но это совершенно не принципиально в данном случае.
Роль серверов у меня будут выполнять три ноды:
dh01
dh02
dh03
Роль клиентов:
dh04
dh05
Собственно скачиваем любым способом zip с nomad.
Распаковываем и кладем бинарь в /usr/bin/ на всех серверах.
Генерим ключ для авторизации серверов и шифрования передаваемых ими данных:
nomad keygen_x000D_ _x000D_ vvCQqXZoMcPWJtq63D/Zwg==
Далее, я буду использовать systemd-юниты для демонизации и управления процессами nomad.
systemd-юнит для серверов:
vim /usr/lib/systemd/system/nomad-server.service_x000D_ _x000D_ _x000D_ [Unit]_x000D_ Description=Nomad-server_x000D_ After=network.target_x000D_ _x000D_ [Service]_x000D_ StartLimitInterval=20_x000D_ StartLimitBurst=5_x000D_ TimeoutStartSec=0_x000D_ _x000D_ ExecStartPre=/usr/bin/mkdir -p /var/lib/nomad_x000D_ ExecStart=/usr/bin/nomad agent -server -data-dir=/var/lib/nomad -encrypt=vvCQqXZoMcPWJtq63D/Zwg== -bootstrap-expect=3_x000D_ ExecStop=/usr/bin/kill $MAINPID_x000D_ _x000D_ [Install]_x000D_ WantedBy=multi-user.target
Данный unit написан мной самостоятельно и опции запуска nomad тоже выбраны эмпирическим путем, в силу отсутствия документации.
Поясню только, что -bootstrap-expect=3
указывает количество серверов которых нужно дождаться прежде чем конфигурить кластер и выбирать лидера.
Запускам созданный сервис на трех серверах с ролью server:
systemctl daemon-reload_x000D_ systemct start nomad-server
Собираем кластер(выполнить на одном из серверов с запущенным сервисом nomad-server):
[root@dh01] nomad server-join 10.200.77.32 10.200.77.30
10.200.77.32 10.200.77.30 — ip dh02,dh03
Проверяем состояние кластера:
nomad server-members_x000D_ _x000D_ _x000D_ Name Address Port Status Leader Protocol Build Datacenter Region_x000D_ dh01.ruden.local.global 10.200.77.29 4648 alive false 2 0.5.5 dc1 global_x000D_ dh02.ruden.local.global 10.200.77.30 4648 alive false 2 0.5.5 dc1 global_x000D_ dh03.ruden.local.global 10.200.77.32 4648 alive true 2 0.5.5 dc1 global
Подключение клиентов
systemd-юнит для серверов с ролью client:
cat /usr/lib/systemd/system/nomad-client.service _x000D_ _x000D_ _x000D_ [Unit]_x000D_ Description=Nomad-server_x000D_ After=network.target_x000D_ _x000D_ [Service]_x000D_ StartLimitInterval=20_x000D_ StartLimitBurst=5_x000D_ TimeoutStartSec=0_x000D_ _x000D_ ExecStartPre=/usr/bin/mkdir -p /var/lib/nomad_x000D_ ExecStart=/usr/bin/nomad agent -client -data-dir=/var/lib/nomad -servers dh01 dh02 dh03_x000D_ ExecStop=/usr/bin/kill $MAINPID_x000D_ _x000D_ [Install]_x000D_ WantedBy=multi-user.target
systemctl daemon-reload_x000D_ systemct start nomad-client
Клиенты автоматически подключаются к кластеру:
nomad node-status_x000D_ _x000D_ _x000D_ ID DC Name Class Drain Status_x000D_ f3b0df4b dc1 dh05.ruden.local <none> false ready_x000D_ 1f889694 dc1 dh04.ruden.local <none> false ready
Запуск задачи
Генерация скелета файла-описания задачи в котором используется docker-драйвер и запускается контейнер с redis:
nomad init_x000D_ _x000D_ Example job file written to example.nomad
Запуск задачи:
nomad run example.nomad
Статус задач:
nomad status_x000D_ _x000D_ ID Type Priority Status_x000D_ example service 50 running
Естественно на серверах с ролью client в данном конкретном случае должен работать docker-engine )
К сожалению я особо не успел поработать с nomad и не могу пока говорить о плюсах, минусах, надежности и прочем. Пока все на стадии «потыкать палочкой».
Помогла ли вам статья?