Установка и настройка Hashicorp Consul

2023.07.23
Разбираемся в Hashicorp Consul, его устройстве и архитектуре, разворачиваем server-leader и client, пробуем использовать на примере Consul KV.

Hashicorp Consul предоставляет набор возможностей, среди которых обнаружение сервисов, балансировка нагрузки, управление конфигурацией распределенных сервисов.

Именно последний пункт меня интересует, так как уже неоднократно в моей практике встает вопрос о центральном хранилище конфигов и секретов.

Что я хочу:

Больше статей в документации по Hashicorp Consul, а на странице Client Libraries & SDKs, представлен список клиенских библиотек для разных языков программирования.

Consul KV как центральное хранилище конфигов

Я сделал небольшой пример того как может выглядеть структура конфигов (подсмотрел я ее на работе, ребята достаточно грамотно ее выстроили).

Например, сделаем такую структуру директорий:

Пример структуры директорий хранилища конфигов

Теперь посмотрим на внутренние ключи директории databases/mysql/:

Пример содержимого директории конфигов

На странице редактирования у нас есть возможность выбрать и провалидировать вводимое содержимое:

Страница редактирования конкретного конфига

Теперь можно сделать простой GET запрос на клиент Consul Agent:

$ consul kv get -http-addr ip:port -token *** databases/mysql/host
10.8.0.10

Архитектура

Системная архитектура Consul обладает иерархией, но в каждом случае используется один бинарник Consul Agent, упрощенно перечислим элементы:

Есть схема архитектуры из докментации:

Я составил аналогичную упрощенную схему, где видно что приложение ведет общение с Consul Agent Client, который в свою очередь ведет общение с Consul Agent Server*:

Consul Agent ключевой элемент архитектуры, он может быть сервером или клиентом, все зависит от конфигурации. Поэтому сначала рассмотрим как устанавливать и запускать бинарник, а затем как его конфигурировать под наши нужды.

Установка

На странице загрузок можно скачать нужный бинарник (для пользователей из РФ нужен VPN), либо можно самостоятельно скомпилировать из исходников. Для обладателей linux amd64 из РФ и без VPN можно скачать здесь 1.16.0.

На серверах мы будем запускать Consul Agent, далее нам потребуются опции запуска, которые можно узнать так:

$ consul agent -help

Нам нужен отдельный непривелегированный пользователь, от которого будем запускать Consul:

$ sudo adduser app

Я пошел по пути скачивания бинарника, поэтому:

$ curl -LO http://localhost:8002/2023/07/19/consul/files/consul_1.16.0_linux_amd64
$ sudo mv consul /usr/bin/

Теперь нам нужно куда-то расположить конфиг, определить пути хранения данных и логов:

$ sudo mkdir -p /var/lib/consul /etc/consul.d /var/log/consul
$ sudo chown app:app /var/lib/consul /etc/consul.d /var/log/consul
$ sudo chmod 775 /var/lib/consul /etc/consul.d

Дальше нам нужен конфиг:

$ nano /etc/consul.d/config.hcl

Мы знаем что Consul Agent может быть запущен в 3 состояниях (server leader, server follower, client), теперь в зависимости от того в каком состоянии мы запускаем ноду с Consul Agent смотрим раздел Конфигурация.

Провалидировать конфиг можно так:

$ consul validate /etc/consul.d
bootstrap = true: do not enable unless necessary
Configuration is valid!

Теперь добавим конфиг systemd для consul чтобы была автозагрузка:

$ sudo nano /etc/systemd/system/consul.service

И добавим туда следующее:

[Unit]
Description=Consul Agent
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=app   
Group=app   
ExecStart=/usr/bin/consul agent -config-dir=/etc/consul.d -log-rotate-max-files=10 -log-rotate-duration=1d -log-file=/var/log/consul/consul.log
ExecReload=/bin/kill -HUP $MAINPID
KillSignal=SIGINT
TimeoutStopSec=5
Restart=on-failure
SyslogIdentifier=consul

[Install]
WantedBy=multi-user.target

Здесь мы намерено настраиваем логирование в файл и ротацию логов.

Загружаем, стартуем и проверяем статус сервиса:

$ sudo systemctl enable consul.service
$ sudo systemctl start consul.service
$ sudo systemctl status consul.service

Конфигурация

Директивы конфигурационного файла можно узнать в документации. А пока рассмотрим несколько примеров конфигов для разных типов Consul Agent.

Consul Agent'ы должны сплетничать по udp иначе будет периодический обрыв.

Если конфиг ноды содержит несколько IP адресов тогда нужно разрулить вопрос взаимодействия интерфейсов (advertise_addr), например вот обсуждение.

Сервер

Если нужна только одна нода с Consul Agent в состоянии server leader (например для знакомства), то конфига ниже вполне достаточно.

Создаем ноду лидера (bootstrap) с именем consul-server0 в датацентре dc0, включаем веб-интерфейс и ACL (об этом поговорим чуть позже):

node_name = "consul-server0"
server    = true
bootstrap = true
ui_config {
  enabled = true
}
datacenter = "dc0"
data_dir   = "/var/lib/consul"
log_level  = "INFO"
addresses {
  http = "0.0.0.0"
}
connect {
  enabled = true
}
acl {
  enabled = true
  default_policy = "deny"
  enable_token_persistence = true
}

Только одна нода может быть лидером и запущена как bootstrap = true, остальные сервер-ноды должны быть запущены как bootstrap = false.

Клиент

Запустим ноду клиент с именем consult-clien0 в том же датацентре dc0 и укажем адрес для подключения к серверам retry_join:

node_name = "consult-clien0"
server    = false
bootstrap = false
ui_config {
  enabled = true
}
datacenter = "dc0"
data_dir   = "/var/lib/consul"
log_level  = "INFO"
addresses {
  http = "0.0.0.0"
}
connect {
  enabled = true
}
acl {
  enabled = true
  default_policy = "deny"
  enable_token_persistence = true
  tokens {
    agent = "***"
  }
}

retry_join = ["xxx.xxx.xxx.xxx"]
advertise_addr = "{{ GetInterfaceIP `enp3s0` }}"

ACL

ACL нужен для авторизированного доступа - чтобы не было чужих в нашем кластере.

При первом запуске, на сервере Consul необходимо достать SecretID для авторизации (после самого запуска):

$ consul acl bootstrap
AccessorID:       ***
SecretID:         ***
Description:      Bootstrap Token (Global Management)
Local:            false
Create Time:      2023-07-11 18:03:29.888358357 +0000 UTC
Policies:
   00000000-0000-0000-0000-000000000001 - global-management

Теперь для пользователей можно создавать токены через веб-интерфейс:

А для новых Consul Agent'ов через терминал:

$ consul acl token create \
  -description "test agent token" \
  -node-identity "consul-t0:dc0" \
  -token ******

Где:

Послесловие

Установка одного бинарника не так уж и трудна, однако конфигурирование потребовало вникнуть в теорию Hashicorp Consul. На данный момент использованием Consul KV доволен. Со временем затрону остальные части Consul Agent.

В телеграм канале DevOps от первого лица можно оставить комментарий или почитать интересные истории из практики DevOps