Hashicorp Consul предоставляет набор возможностей, среди которых обнаружение сервисов, балансировка нагрузки, управление конфигурацией распределенных сервисов.
Именно последний пункт меня интересует, так как уже неоднократно в моей практике встает вопрос о центральном хранилище конфигов и секретов.
Что я хочу:
Consul Agent
в состоянии server leader
VPS
где будет мое приложение и Consul Agent
в состоянии client
, чтобы мое приложение получало конфиги от Consul Agent
Больше статей в документации по Hashicorp Consul, а на странице Client Libraries & SDKs, представлен список клиенских библиотек для разных языков программирования.
Я сделал небольшой пример того как может выглядеть структура конфигов (подсмотрел я ее на работе, ребята достаточно грамотно ее выстроили).
Например, сделаем такую структуру директорий:
Теперь посмотрим на внутренние ключи директории 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
Consul Agent
запущенный в режиме сервера, хранит состояние кластера и участвует в кворуме
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 нужен для авторизированного доступа - чтобы не было чужих в нашем кластере.
При первом запуске, на сервере 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 ******
Где:
description
- описание токенаnode-identity
- идентификация агента <node_name:datacenter>
token
- токен полученный на предыдщем шагеУстановка одного бинарника не так уж и трудна, однако конфигурирование потребовало вникнуть в теорию Hashicorp Consul
. На данный момент использованием Consul KV
доволен. Со временем затрону остальные части Consul Agent
.