Сервісів у вас уже з десяток, серверів — три-п’ять. Контейнери запускаються через docker compose на кожній машині окремо, деплой — це ssh і скрипт, який знає лише одна людина. Сервер падає — сервіси на ньому лежать, доки хтось не перекине їх руками.
Логічний наступний крок — оркестратор. І тут усі радять Kubernetes. Але для команди з двох-трьох розробників без окремого платформного інженера він часто стає новим джерелом болю: десяток компонентів, власні абстракції на кожен чих, оновлення кластера як окремий проєкт. Частина ресурсів скромних серверів іде на сам control plane, а не на ваші застосунки.
Для такого масштабу ми ставимо Nomad. Він закриває ту саму задачу — «запусти мені ці сервіси, стеж за ними, перезапускай і оновлюй без простою» — і при цьому влазить у голову за кілька днів.
Що ми робимо
Типова схема на 3–10 серверах (виділені OVH чи Hetzner або віртуалки на Proxmox):
- Nomad-сервери — три вузли з консенсусом Raft. Вони планують, де що запускати. Один сервер теж працює, але тоді він — єдина точка відмови.
- Nomad-клієнти — решта машин, на яких крутяться ваші задачі. На маленьких кластерах серверна й клієнтська роль часто живуть на одних вузлах.
- Consul — каталог сервісів і перевірки здоров’я. Кожен сервіс реєструється сам, і інші знаходять його за ім’ям, а не за IP.
- Traefik — вхідний проксі. Читає каталог Consul і сам будує маршрути: новий сервіс з’явився — Traefik уже знає, куди слати трафік. Сертифікати Let’s Encrypt випускає теж він.
- Секрети — Nomad Variables для простих випадків або Vault, якщо потрібні динамічні паролі до бази, ротація й аудит.
- Prometheus і Grafana — метрики Nomad, Consul, Traefik і самих застосунків, алерти.
Сервери створюємо через Terraform, налаштовуємо Ansible, а job-файли Nomad лежать у тому ж репозиторії інфраструктури. Так увесь кластер описаний кодом, і його можна відтворити з нуля.
Чому Nomad і як він працює
Nomad — це один бінарник. Сервер і клієнт — той самий файл, різниця лише в конфігу. Його можна оновити, просто замінивши файл і перезапустивши службу по черзі на кожному вузлі.
Задачі описуються в HCL — читається простіше, ніж стос YAML-маніфестів. Ось шматок job-файлу з canary-деплоєм:
group "api" {
count = 3
update {
max_parallel = 1
canary = 1
auto_promote = true
auto_revert = true
}
service {
name = "shop-api"
port = "http"
tags = ["traefik.enable=true"]
check {
type = "http"
path = "/health"
interval = "10s"
timeout = "2s"
}
}
}
Що тут відбувається: під час оновлення Nomad спершу піднімає одну нову копію поруч зі старими. Якщо перевірка /health проходить, копії замінюються по одній. Якщо нова версія не стартує — Nomad сам повертає попередню. Ніхто не прокидається вночі, щоб робити відкат.
Окрім Docker, Nomad вміє запускати звичайні бінарники через драйвери exec (з ізоляцією) і raw_exec (без неї). Це рятує, коли частина системи — старий Java-сервіс чи Go-бінарник, який нема сенсу пакувати в контейнер.
Traefik ми зазвичай ставимо окремою службою systemd на вхідних вузлах, а не задачею всередині Nomad. Так вхід у систему не залежить від планувальника: навіть якщо кластер поводиться дивно, проксі живий і віддає те, що може.
Деплой із GitLab CI — це збірка образу і nomad job run з тегом нового образу. Перед цим nomad job plan показує, що саме зміниться. Токен CI має права лише на свій namespace, а не на весь кластер.
Компроміси, про які варто знати
Екосистема менша. Для Kubernetes є Helm-чарт майже на все — від Redis до повного стека моніторингу. Для Nomad такі речі часто пишемо самі. Job-файл на 40 рядків — не трагедія, але це робота.
Ліцензія. У 2023 році HashiCorp перевела Nomad, Consul, Vault і Terraform з MPL на BSL. Для запуску у власній інфраструктурі це зазвичай нічого не змінює. Обмеження стосуються тих, хто хоче продавати конкурентний продукт на їхній основі. Але знати про це треба, і в нових проєктах ми розглядаємо OpenTofu замість Terraform та OpenBao замість Vault.
Коли таки потрібен Kubernetes. Якщо команда вже знає k8s, якщо ви плануєте десятки серверів і сотні сервісів, якщо потрібні оператори для баз даних чи готові чарти від постачальника — беріть Kubernetes. Для невеликого кластера є k3s: це повноцінний Kubernetes, тільки легший у встановленні. Ми чесно скажемо, коли Nomad — неправильний вибір.
І ще одне: бази даних ми зазвичай тримаємо поза оркестратором — на окремих машинах чи LXC з реплікацією й бекапами. Nomad чудово керує stateless-сервісами. Із даними краще не гратися.
Що ви отримуєте
- Кластер Nomad + Consul із трьома серверами, що переживає втрату вузла.
- Traefik на вході з автоматичними сертифікатами й маршрутами з каталогу Consul.
- Job-файли для ваших сервісів у Git, з rolling або canary-деплоєм і автовідкатом.
- Пайплайн у GitLab CI: збірка, перевірка плану, деплой.
- Секрети в Nomad Variables або Vault, а не в
.envна серверах. - Prometheus і Grafana з дашбордами по кластеру та алертами.
- Код Terraform і Ansible, щоб відтворити кластер з нуля.
- Документацію: як задеплоїти новий сервіс, як оновити кластер, що робити, коли падає вузол.
- Доступи адміністратора — кластер ваш, а не наш.
Якщо ваші сервіси переросли docker compose, а Kubernetes здається забагато, напишіть нам. Розберемо, що у вас крутиться, і скажемо, чи підійде Nomad — або що краще взяти натомість.