До основного вмісту

Consul: service discovery і розподілена конфігурація

Хмара та DevOps · · 5 хв читання
Ілюстрація до статті «Consul: service discovery і розподілена конфігурація»

Коли сервісів на серверах стає більше десятка, файл /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 server3 чи 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 налаштоване за розкладом — стан кластера не відновити з нізвідки.

Часті питання

Чому кількість серверних вузлів Consul має бути непарною, а не парною?

Протоколу Raft потрібна чітка більшість голосів, щоб домовитися про стан кластера, а за парної кількості серверів мережа під час розриву може поділитися на дві однакові за розміром групи, і жодна з них не набере більшості для безпечної роботи. Непарна кількість завжди дає чітку більшість на одному боці, тому кластер продовжує працювати і лишається узгодженим навіть після втрати вузла.

Чи замінює Consul балансувальник навантаження, чи перед сервісами все одно потрібен окремий проксі?

Ні, Consul відстежує, які інстанси живі і де вони перебувають, але сам трафік не маршрутизує і не балансує. Зворотному проксі, API-шлюзу чи клієнтській бібліотеці все одно доводиться читати цей каталог і вирішувати, який інстанс обробить конкретний запит — Consul лише віддає актуальний перелік, а саме рішення про маршрутизацію лишається поза ним.

Як швидко Consul перестає надсилати трафік на сервіс після того, як той почав провалювати health check?

Щойно перевірка поспіль повідомляє про помилку, а не один раз випадково, Consul позначає інстанс як critical і одразу прибирає його адресу з відповідей DNS і API. Усе, що покладається на свіжий запит — проксі, балансувальник, інший сервіс, — просто перестає отримувати цей інстанс, і перемикання відбувається автоматично, без того, щоб людина спершу помітила збій за зростанням помилок у клієнтів.

Чи обов'язкова приватна мережа на кшталт VPN-mesh для роботи Consul, чи агенти можуть спілкуватися напряму через публічний інтернет?

Суворо обов'язковою вона не є, проте робота через відкритий інтернет ризикована без ретельно налаштованих списків доступу і шифрування, оскільки gossip-трафік і API спершу не розраховані на публічний інтернет. Запуск агентів поверх уже приватної мережі, наприклад mesh-VPN між вузлами, — стандартний безпечний підхід, який повністю прибирає цей трафік із публічного інтернету.

Чи була стаття корисною?
← Назад до бази знань Поставити питання підтримці