OSEN-НИЙ SAAALEСкидка 50% на виртуальный хостинг и VDS
до 30.11.2025 Подробнее
Выберите продукт

HashiCorp Nomad на VDS: альтернатива Kubernetes, jobs/allocations и сервис‑дискавери с Consul

Хотите оркестрацию контейнеров и сервисов без сложности Kubernetes? Покажу, как развернуть Nomad на облачных VDS, подключить Consul для service discovery, писать jobs, читать allocations, настроить канареечные обновления и отладку продакшена на минимальных ресурсах.
HashiCorp Nomad на VDS: альтернатива Kubernetes, jobs/allocations и сервис‑дискавери с Consul

Nomad — это лёгкий планировщик и оркестратор рабочих нагрузок (контейнеры, бинарники, системные службы), который отлично чувствует себя на небольших и средних кластерах облачных VDS. В паре с Consul он обеспечивает надёжный service discovery, проверки здоровья и сегментацию сервисов. В статье разберём архитектуру Nomad+Consul, развёртывание на VDS, напишем первый job, посмотрим на allocations, включим обновления без простоя и обсудим, когда Nomad практичнее Kubernetes.

Зачем Nomad на VDS и когда он выигрывает у Kubernetes

Если вашей команде нужен управляемый планировщик без высокой цены за сложность, Nomad — отличный выбор. Он проще в установке, требует меньше системных компонентов, работает с контейнерами и просто с исполняемыми файлами, а в связке с Consul закрывает discovery и health‑checks. На типичном VDS Nomad стартует быстрее и потребляет меньше памяти, чем большинство Kubernetes‑дистрибутивов, при этом оставляя контроль над топологией, обновлениями и отказоустойчивостью.

Идеальный сценарий: 3 VDS под Nomad server, 2–5 VDS под Nomad client, Consul агент на каждом узле. Этого достаточно для продовых нагрузок с высокой доступностью планировщика.

Архитектура Nomad + Consul в минимуме

Роли Nomad

  • Nomad server — хранение состояния кластера (Raft), планирование, координация. Рекомендуется нечётное число узлов (3 или 5) с параметром bootstrap_expect.
  • Nomad client — исполнитель задач; именно на клиентах создаются allocations. Клиенты подключаются к серверам и тянут план задания.

Consul: service discovery и здоровье

Consul запускается агентом на каждом узле. Он публикует сервисы, поддерживает проверки здоровья, даёт DNS/API‑интерфейсы для поиска. Nomad интегрируется с Consul через секцию service в job‑описании, автоматически создавая записи и health‑checks.

Сети и порты

  • Nomad: 4646/tcp (HTTP API/UI), 4647/tcp (RPC), 4648/tcp+udp (gossip/serf).
  • Consul: 8500/tcp (HTTP API/UI), 8300/tcp (server RPC), 8301/tcp+udp (LAN serf), 8302/tcp+udp (WAN serf).

В проде ограничьте публичный доступ к HTTP/UI только через административный доступ (VPN, bastion), а RPC/serf держите в приватной сети между VDS.

Минимальная архитектура Nomad и Consul: серверы, клиенты и порты сети

Подготовка VDS

Предположим Ubuntu 22.04/24.04, root‑доступ и внутренние IP между узлами.

sudo apt update
sudo apt install -y curl gnupg2 lsb-release apt-transport-https ca-certificates

Откройте только необходимые порты. Пример с UFW:

sudo ufw default deny incoming
sudo ufw default allow outgoing
# SSH
sudo ufw allow 22/tcp
# Nomad
sudo ufw allow 4646/tcp
sudo ufw allow 4647/tcp
sudo ufw allow 4648
# Consul
sudo ufw allow 8500/tcp
sudo ufw allow 8300/tcp
sudo ufw allow 8301
sudo ufw allow 8302
sudo ufw enable

Проверьте, что внутренние адреса узлов доступны друг другу по указанным портам, а UI/HTTP не торчат в публичный интернет без необходимости. Если вы только начинаете с сетевой сегментацией для контейнеров, пригодится материал про настройку Docker и iptables/nftables.

Установка Consul и Nomad

Поставим из официального репозитория пакетов:

curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update
sudo apt install -y consul nomad docker.io

Добавьте пользователя Nomad в группу Docker для драйвера docker:

sudo usermod -aG docker nomad
sudo systemctl enable --now docker

Consul: конфигурация сервера и клиента

На трёх серверных узлах создайте каталог и базовый конфиг:

sudo mkdir -p /etc/consul.d
sudo mkdir -p /var/lib/consul
sudo chown -R consul:consul /var/lib/consul

Пример /etc/consul.d/server.hcl (на каждом server‑узле поменяйте IP в retry_join и advertise_addr):

server = true
node_name = "consul-server-1"
datacenter = "dc1"
data_dir = "/var/lib/consul"
bind_addr = "0.0.0.0"
advertise_addr = "10.0.0.11"
client_addr = "127.0.0.1"
bootstrap_expect = 3
grpc_port = 8502
retry_join = ["10.0.0.11", "10.0.0.12", "10.0.0.13"]
ui_config { enabled = true }

На клиентских узлах Consul‑агент без роли сервера:

server = false
node_name = "consul-client-1"
datacenter = "dc1"
data_dir = "/var/lib/consul"
bind_addr = "0.0.0.0"
advertise_addr = "10.0.0.21"
client_addr = "127.0.0.1"
retry_join = ["10.0.0.11", "10.0.0.12", "10.0.0.13"]

Запуск и проверка:

sudo systemctl enable --now consul
consul members

Ожидаем в выводе все серверы и клиенты в статусе alive.

Nomad: конфигурация серверов

Создайте каталоги и простую конфигурацию:

sudo mkdir -p /etc/nomad.d
sudo mkdir -p /var/lib/nomad
sudo chown -R nomad:nomad /var/lib/nomad

Пример /etc/nomad.d/server.hcl (на каждом server‑узле корректируйте advertise):

datacenter = "dc1"
region = "global"
data_dir = "/var/lib/nomad"
bind_addr = "0.0.0.0"
server {
  enabled = true
  bootstrap_expect = 3
}
advertise {
  http = "10.0.0.11:4646"
  rpc  = "10.0.0.11:4647"
  serf = "10.0.0.11:4648"
}
consul {
  address = "127.0.0.1:8500"
  auto_advertise = true
  server_service_name = "nomad-server"
  client_service_name = "nomad-client"
}

Запустите Nomad‑серверы:

sudo systemctl enable --now nomad
nomad server members

Статус должен показать лидера и последователей. Если лидера нет — проверьте bootstrap_expect и сетевую связность.

Nomad: конфигурация клиентов

На клиентских узлах используем Docker‑драйвер. Пример /etc/nomad.d/client.hcl:

datacenter = "dc1"
region = "global"
data_dir = "/var/lib/nomad"
bind_addr = "0.0.0.0"
client {
  enabled = true
  network_interface = "eth0"
  node_class = "general"
  options = {
    "docker.auth.config" = "/root/.docker/config.json"
  }
}
plugin "docker" {
  config {
    volumes {
      enabled = true
    }
    allow_privileged = false
  }
}
consul {
  address = "127.0.0.1:8500"
}

Запустите клиентов и убедитесь, что они подключились:

sudo systemctl restart nomad
nomad node status

Вы увидите список узлов с их node_class, ресурсами и состоянием.

Виртуальный хостинг FastFox
Виртуальный хостинг для сайтов
Универсальное решение для создания и размещения сайтов любой сложности в Интернете от 95₽ / мес

Первый job: сервис на Nginx

Создадим простой сервис с двумя репликами и health‑check в Consul. Файл web.nomad.hcl:

job "web" {
  datacenters = ["dc1"]
  type = "service"
  group "web" {
    count = 2
    network {
      port "http" { to = 80 }
    }
    task "nginx" {
      driver = "docker"
      config {
        image = "nginx:1.27-alpine"
        ports = ["http"]
      }
      service {
        name = "web"
        port = "http"
        check {
          type     = "http"
          path     = "/"
          interval = "5s"
          timeout  = "2s"
        }
      }
      resources {
        cpu    = 200
        memory = 128
      }
    }
  }
  update {
    max_parallel     = 1
    min_healthy_time = "10s"
    healthy_deadline = "2m"
    stagger          = "30s"
  }
}

Запуск и базовая проверка:

nomad job run web.nomad.hcl
nomad status web
nomad alloc status <alloc-id>

Секция service автоматически зарегистрирует сервис в Consul, а allocations покажут, где и как выполняются задачи: ID, узел, ресурсы и состояние health‑checks.

Allocations: как читать и отлаживать

Allocation — это конкретный запуск задачи на клиентском узле. При сбое Nomad создаёт новую allocation согласно политике reschedule или пересоздаёт её на другом узле по стратегии update. Основные команды:

nomad status <job>
nomad alloc status <alloc-id>
nomad alloc logs -stderr <alloc-id>
nomad alloc exec -task nginx <alloc-id> sh -c "nginx -t"

При системных ошибках смотрите journalctl -u nomad и journalctl -u consul, а также наличие ресурсов (CPU, RAM, диски) на проблемном узле.

Service discovery с Consul

В нашем примере регистрацией занимается Nomad. Для доступа приложений используйте DNS‑имя вида web.service.consul (или через локальный DNS‑форвардер). Health‑checks отражаются в Consul и влияют на балансировку, если вы используете прокси‑уровень (например, L7‑шлюз). Типовые приёмы:

  • Несколько портов? Объявляйте их в секции network и сопоставляйте в service.
  • Горизонтальное масштабирование? Меняйте count, Nomad выполнит постепенное обновление по правилам update.
  • Разные классы узлов? Используйте node_class и constraint, чтобы направлять конкретные сервисы на подходящие VDS.

Запуск и проверка Nomad job, статус allocations и health‑checks Consul в терминале

Канареечные и безопасные обновления

Nomad поддерживает канареечные релизы без сторонних операторов. Достаточно добавить canary и флаги авто‑промоции/отката:

update {
  canary           = 1
  max_parallel     = 1
  auto_promote     = true
  auto_revert      = true
  min_healthy_time = "15s"
  healthy_deadline = "3m"
}

Проверяйте метрики и логи канареек через alloc logs и health‑checks в Consul. Если канарейка не проходит, Nomad сам откатит релиз.

Размещение и ограничения: meta/constraints/affinity

Чтобы направлять задачи на нужные узлы, используйте constraint по атрибутам узла и метаданным клиента. Например, ограничим деплой на класс узлов general:

constraint {
  attribute = "${node.class}"
  operator  = "="
  value     = "general"
}

Атрибуты узла (CPU архитектура, ядра, ОС) доступны через attr.*. Для мягких предпочтений пригодится affinity с весами, без жёсткой блокировки планировщика.

Хранилище и тома

Nomad предлагает host volumes и интеграции с внешними системами через CSI. Для локальных данных используйте host_volume с явным монтированием:

volume "media" {
  type      = "host"
  read_only = false
  source    = "/srv/media"
}

group "app" {
  volume "media" { read_only = false }
  task "svc" {
    driver = "docker"
    config { image = "busybox:1.36" }
    volume_mount {
      volume      = "media"
      destination = "/data"
      read_only   = false
    }
  }
}

Помните о жизненном цикле: allocations эфемерны. Для состояния — внешний сторедж или отказоустойчивая СУБД, а локальные тома — только для кешей и временных данных.

Безопасность: TLS, ACL и изоляция

Минимальные практики для прод‑кластера:

  • Включите TLS для Nomad и Consul: подпишите серверные/клиентские сертификаты и укажите директории в tls‑секциях конфигов. Если нужна проверенная цепочка, оформите SSL-сертификаты GlobalSign.
  • Настройте ACL: в Consul — политики и токены для сервисов; в Nomad — политики для операторов/CI. Храните токены в секретах, включайте ротацию.
  • Сегментируйте сеть: RPC/serf только по приватным IP VDS, UI доступен через VPN или промежуточный bastion.
  • Ограничьте драйвер Docker: allow_privileged = false, секкомп‑профили, cgroup‑лимиты CPU/RAM, no-new-privileges в образах. Для усиления песочницы рассмотрите изоляцию контейнеров gVisor/Firecracker.

FastFox SSL
Надежные SSL-сертификаты
Мы предлагаем широкий спектр SSL-сертификатов от GlobalSign по самым низким ценам. Поможем с покупкой и установкой SSL бесплатно!

Наблюдаемость и алерты

Nomad и Consul отдают метрики и события. Начните с базового:

  • Системные логи: journalctl -u nomad -f, journalctl -u consul -f.
  • События задания: nomad status <job>, nomad alloc status.
  • Здоровье сервисов: consul catalog services, consul health state critical.

Далее подключайте скраппер метрик и дешборды, чтобы видеть лаги планировщика, неуспешные размещения и деградации health‑checks.

Три типичные ошибки и как их избежать

  • Открытый UI в интернет. Держите client_addr для HTTP интерфейсов на 127.0.0.1 и проксируйте доступ по VPN.
  • Недостаточно прав Docker. Добавьте пользователя nomad в группу docker, проверьте сокет и права.
  • Сеть контейнеров. Ясно задавайте network и порты. Если нужен host‑network, учитывайте конфликты портов на узле.

Nomad против Kubernetes: прагматичный взгляд

Nomad выигрывает, когда важны простота, малый накладной расход и единый планировщик для разных типов задач (контейнеры, бинарники, systemd). Kubernetes даёт огромную экосистему и гибкость, но требует больше компетенций и ресурсов. На VDS с умеренными нагрузками Nomad разворачивается за часы, обновляется предсказуемо и прозрачно масштабируется. Если вы не используете сложные паттерны вроде обширных CRD, сложных CNI и сложной сетевой политики — Nomad будет эффективнее по TCO.

Практический мини‑план кластера на VDS

  • 3 VDS x 2 vCPU, 4 GB RAM, SSD — роли server Nomad/Consul.
  • 2–5 VDS x 2–4 vCPU, 4–8 GB RAM — роли client с Docker.
  • Приватная подсеть для RPC/serf, ограничение публичных портов фаерволом.
  • Резервные копии /var/lib/nomad и /var/lib/consul (осторожно с снапшотами Raft — делайте консистентные).

Отладка планирования

При неожиданных отказах размещения используйте объяснение планировщика:

nomad job run -check-index web.nomad.hcl
nomad plan web.nomad.hcl
nomad eval status <eval-id>

Смотрите причины отказов: несоответствие constraint, нехватка CPU/RAM/диска, конфликт портов, невалидный образ.

Чеклист перед продом

  • Включён TLS и ACL в Nomad/Consul, с ротацией ключей.
  • UI закрыты во внешнюю сеть, доступ только через VPN/бастион.
  • Описаны update/reschedule стратегии в jobs, протестирован откат.
  • Настроены бэкапы и мониторинг критичных метрик планировщика и количества критичных health‑checks.
  • Есть staging‑кластер или namespace для предварительного прогона.

Итоги

Nomad на VDS даёт производительный и прозрачный оркестратор с минимальной операционной сложностью. В связке с Consul вы получаете полноценный service discovery, health‑checks и гибкое планирование. Начните с малого: три сервера, пара клиентов, один сервис с канарейкой. Когда нагрузка и команда вырастут, масштабируйтесь горизонтально, не меняя базовый стек и привычки эксплуатации.

Поделиться статьей

Вам будет интересно

rclone serve: S3/WebDAV/HTTP как универсальный шлюз к Object Storage OpenAI Статья написана AI (GPT 5)

rclone serve: S3/WebDAV/HTTP как универсальный шлюз к Object Storage

Покажем, как превратить Object Storage в универсальный сервис с rclone serve: отдача по HTTP, WebDAV и S3, настройка VFS‑кэша и TT ...
fscrypt на ext4: практическое шифрование каталогов на VDS и сравнение с LUKS OpenAI Статья написана AI (GPT 5)

fscrypt на ext4: практическое шифрование каталогов на VDS и сравнение с LUKS

Разбираем нативное шифрование ext4 с fscrypt: чем оно отличается от LUKS на уровне диска, когда какой подход использовать на VDS, ...
Podman Quadlet: rootless systemd на VDS — практическое руководство OpenAI Статья написана AI (GPT 5)

Podman Quadlet: rootless systemd на VDS — практическое руководство

Quadlet превращает .container/.pod в systemd‑юниты. В связке с rootless Podman и systemd --user это чистый и безопасный способ дер ...