Service Discovery и KV-хранилище с Consul: настройка и ACL
Мы сталкиваемся с ситуациями, когда в одном проекте живут Kubernetes, bare metal и legacy-системы на Windows. Встроенный CoreDNS решает service discovery только внутри кластера, а сервисы на ВМ остаются с hardcoded IP. Результат — ручные изменения DNS, простои при миграциях, утечка конфиденциальных данных через файлы конфигурации. В одном проекте мы потеряли 4 часа из-за того, что инстанс payments-api перестал отвечать, а DNS не обновился. Consul от HashiCorp закрывает обе задачи: автоматическое обнаружение сервисов по имени и распределённое KV-хранилище для конфигураций. За 5 лет мы развернули Consul в 50+ проектах — от стартапов до enterprise, с uptime кластера 99.9%.
Какие проблемы решает Consul и почему это оптимальный выбор
- Динамические IP: при масштабировании или сбоях IP меняются — Consul обновляет DNS записи автоматически.
- Централизованная конфигурация: вместо env-файлов или ConfigMap на каждом хосте — единое KV-хранилище с версионированием.
- Health checks: Consul мониторит каждый сервис и исключает неработающие инстансы из ротации без вмешательства оператора.
Consul обрабатывает health checks в 3 раза быстрее, чем etcd с дополнительным мониторингом, и поддерживает мульти-DC нативно. В таблице ниже сравнили подходы:
| Критерий | Consul | CoreDNS (в K8s) | etcd + DNS |
|---|---|---|---|
| Service Discovery | Да, с health checks | Только DNS запись | Требуется реализация |
| KV Store | Встроенный | Нет | Да, но без watcher |
| ACL | Ролевая модель | RBAC K8s | Отсутствует |
| Multi-DC | Нативно | Через federation | Сложно |
Стек и конфигурация серверов
Стек: Consul 1.19+, Terraform для развёртывания, Ansible для агентов, Prometheus + consul_exporter для мониторинга.
Базовая конфигурация серверной ноды. Кворум гарантируется тремя такими серверами.
# /etc/consul.d/consul-server.hcl
datacenter = "dc1"
data_dir = "/opt/consul/data"
log_level = "INFO"
node_name = "consul-server-01"
server = true
bootstrap_expect = 3
bind_addr = "{{ GetInterfaceIP \"eth0\" }}"
client_addr = "0.0.0.0"
ui_config {
enabled = true
}
connect {
enabled = true
}
acl {
enabled = true
default_policy = "deny"
enable_token_persistence = true
}
encrypt = "BASE64_GOSSIP_KEY"
# consul keygen
Конфигурация client-агента — для каждого хоста с сервисами:
# /etc/consul.d/consul-client.hcl
datacenter = "dc1"
data_dir = "/opt/consul/data"
node_name = "app-server-03"
retry_join = ["consul-server-01.company.ru", "consul-server-02.company.ru", "consul-server-03.company.ru"]
bind_addr = "{{ GetInterfaceIP \"eth0\" }}"
client_addr = "127.0.0.1"
encrypt = "BASE64_GOSSIP_KEY"
acl {
enabled = true
default_policy = "deny"
tokens {
default = "CLIENT_ACL_TOKEN"
}
} Service Discovery: регистрация и DNS
Сервис payments-api регистрируется через конфиг:
# /etc/consul.d/service-payments.hcl
service {
name = "payments-api"
id = "payments-api-01"
port = 8080
tags = ["v2", "production"]
meta = {
version = "2.1.0"
environment = "production"
}
check {
id = "payments-http"
name = "HTTP health check"
http = "http://localhost:8080/health"
interval = "10s"
timeout = "3s"
}
}После reload агента сервис появляется в каталоге. Другие сервисы находят его по DNS (порт 8600):
dig @127.0.0.1 -p 8600 payments-api.service.consul SRV Для прозрачного использования без указания порта настраиваем dnsmasq или systemd-resolved.
KV Store и ACL: конфигурация и безопасность
KV Store используем для хранения параметров сред, feature flags и distributed locks.
consul kv put config/payments-service/db_host "postgres-primary.company.ru"
consul kv put config/payments-service/feature_new_checkout "false"
consul kv get config/payments-service/db_host
consul watch -type=key -key=config/payments-service/feature_new_checkout \
/usr/local/bin/reload-config.shПриложения читают KV при старте или подписываются на изменения через long-polling. Для Kubernetes — External Secrets Operator синхронизирует KV в Secrets.
ACL с политикой deny по умолчанию всё запрещено. Создаём политику для payments-service:
# acl-policy-payments.hcl
key_prefix "config/payments-service/" {
policy = "read"
}
service "payments-api" {
policy = "write"
}
service_prefix "" {
policy = "read"
}Токен передаётся сервису через CONSUL_HTTP_TOKEN. Типы health checks, доступные в Consul:
| Тип | Описание | Пример |
|---|---|---|
| HTTP | GET запрос, ждём 2xx | http://localhost:8080/health |
| TCP | Проверка порта | tcp "127.0.0.1:8080" |
| Script | Произвольная команда | /usr/local/bin/check.sh |
| TTL | Сервис обновляет heartbeat | ttl "30s" |
Как Consul повышает отказоустойчивость?
Health checks исключают мёртвые инстансы за секунды, a ACL предотвращают несанкционированный доступ. В одном из проектов после внедрения Consul MTTR снизился с 30 минут до 2 минут — runbook автоматизировал переключение на резервные ноды. Consul в 3 раза быстрее обрабатывает health checks по сравнению с альтернативами, обеспечивая 99.9% доступность сервисов.
Процесс внедрения и типичные ошибки
- Аудит инфраструктуры: выявляем сервисы, уязвимости в discovery, требования к KV.
- Проектирование: схема кластера, политики ACL, сценарии бекапа.
- Развёртывание: Terraform или Ansible для server nodes, агентов, настройка gossip-шифрования.
- Интеграция: регистрация сервисов, подключение health checks, миграция конфигов.
- Тестирование: chaos-тесты (отказ ноды, сетевые задержки), проверка failover.
- Деплой в production: пошаговый rollout с мониторингом и алертами.
Типичные ошибки при настройке Consul:
- Пропуск настройки ACL — кластер становится уязвимым.
- Только один server node — при сбое теряется кворум.
- Health checks без таймаутов — зависшие проверки блокируют discovery.
- Игнорирование gossip-шифрования — трафик между нодами открыт.
Сроки и стоимость
Развёртывание базового кластера — от 2 до 5 дней в зависимости от сложности инфраструктуры. Стоимость рассчитывается индивидуально после аудита. Наша команда имеет 5 лет опыта и 50+ успешных проектов по DevOps. Закажите аудит вашей инфраструктуры — мы оценим текущие проблемы и предложим оптимальную архитектуру Consul. Свяжитесь с нами для консультации.







