Когда сервисов на серверах становится больше десятка, файл /etc/hosts и захардкоженные IP-адреса в конфигах перестают работать: адреса меняются при пересоздании VPS, а обновлять их вручную на каждом сервере — гарантированная ошибка рано или поздно. Consul от HashiCorp решает это через service discovery: сервисы регистрируются сами, а остальные находят их по имени через DNS или HTTP API, без единого файла с адресами.
Что делает Consul и когда он нужен
Consul хранит три вещи: каталог сервисов с их адресами и портами, статус health check по каждому инстансу и распределённое key-value хранилище для конфигурации. Приложение спрашивает не «какой IP у сервиса billing», а «дай мне живой адрес сервиса billing» — и получает только те инстансы, которые прошли проверку здоровья.
Consul стоит ставить, когда серверов больше 5-6 и они меняются: добавляются реплики, пересоздаются VPS, меняются IP после миграции. На двух постоянных серверах с одним сервисом на каждом Consul — избыточная сложность, хватит DNS-записи или строки в конфиге.
Архитектура: сервер, агент, каталог сервисов
Consul server и кворум
Серверные узлы хранят состояние кластера через протокол Raft и договариваются о кворуме. Для отказоустойчивости нужно нечётное число серверов: 3 сервера переживают потерю одного, 5 — потерю двух. Один сервер годится только для теста, в продакшене это точка отказа всего кластера.
Consul agent на каждом узле
Агент в режиме client ставится на все остальные серверы — он не хранит состояние кластера, а только регистрирует локальные сервисы и опрашивает их health check, передавая данные серверным узлам через gossip-протокол.
| Роль | Сколько узлов | Задача |
|---|---|---|
| Consul server | 3 или 5 | Кворум, хранение состояния, Raft |
| Consul agent (client) | По одному на каждый рабочий сервер | Регистрация сервисов, health check |
| Consul DNS interface | Встроен в каждый агент | Резолвинг service.consul |
Установка и запуск кластера Consul
Пакет consul ставится из официального репозитория HashiCorp, отдельно для серверных узлов и для агентов.
curl -fsSL https://apt.releases.hashicorp.com/gpg | apt-key add -
apt update && apt install -y consul
consul version
Минимальный конфиг серверного узла задаёт режим server, число серверов в кворуме и адрес для gossip-протокола между узлами.
{
"server": true,
"bootstrap_expect": 3,
"datacenter": "dc1",
"data_dir": "/var/lib/consul",
"bind_addr": "10.10.0.1",
"retry_join": ["10.10.0.1", "10.10.0.2", "10.10.0.3"]
}
Регистрация сервиса и проверка здоровья
Сервис регистрируется файлом определения в каталоге /etc/consul.d — агент подхватывает его при старте или по команде consul reload.
{
"service": {
"name": "billing-api",
"port": 8080,
"check": {
"http": "http://localhost:8080/health",
"interval": "10s",
"timeout": "2s"
}
}
}
Если health check три раза подряд возвращает ошибку, Consul помечает инстанс как critical и перестаёт отдавать его адрес в ответах DNS и API — балансировщик или сосед узнают о падении сервиса за 30 секунд, а не по факту роста 5xx у клиентов.
Service discovery через DNS и распределённая конфигурация через KV
Любой узел с работающим агентом резолвит имя billing-api.service.consul через встроенный DNS-интерфейс на порту 8600 — достаточно прописать Consul как resolver для домена .consul в systemd-resolved или dnsmasq. Ключ-значение хранилище consul kv put/get заменяет отдельный конфиг-сервер: feature-флаги и параметры вроде лимита соединений с базой читаются приложением при старте и обновляются без деплоя.
Consul обычно поднимают поверх уже готовой приватной сети — например, WireGuard mesh между узлами, чтобы gossip-трафик и API не ходили через публичный интернет. Вместе с Nomad Consul закрывает и service discovery, и распределение задач по кластеру одним и тем же набором агентов.
Чек-лист перед продакшеном
- Нечётное число серверных узлов (3 или 5), gossip и RPC-порты закрыты от публичного интернета.
- ACL включены хотя бы в минимальном режиме — Consul без ACL по умолчанию доверяет любому, кто достучался до API.
- Health check настроен для каждого сервиса, а не только сама регистрация — без него мёртвый инстанс продолжает получать трафик.
- Резервное копирование consul snapshot save настроено по расписанию — состояние кластера не восстановить из ниоткуда.