Установка и настройка кластера Consul Hashicorp на Linux Ubuntu

Обновлено Обновлено: Опубликовано Опубликовано:

Используемые термины: Consul, Ubuntu.

В данной инструкции мы рассмотрим установку и настройку кластера системы обнаружения сервисов Consul. Он будет состоять из трех нод, каждая из которых будет под управлением операционной системы Linux Ubuntu версии 20.04 (также протестировано на Debian 11).

Подготовка сервера

Выполним предварительные операции по настройке наших серверов. На каждой ноде выполняем данные действия.

1. Установка дополнительных пакетов

Обновляем список пакетов:

apt update

Выполняем команду:

apt install unzip wget

* где:

  • unzip — необходим для распаковки архивов.
  • wget — утилита для загрузки файлов по сети.

2. Настраиваем время

Задаем часовой пояс:

timedatectl set-timezone Europe/Moscow

* в данном примере мы задаем московское время. Полный перечень возможных вариантов можно получить командой: timedatectl list-timezones.

Устанавливаем утилиту для синхронизации времени: 

apt install chrony

Запускаем ее в качестве сервиса: 

systemctl enable chrony

3. Настройка имени серверов

Для сервера консул важно, чтобы серверы были доступны по именам. Предположим, что наши серверы имеют следующие названия и IP-адреса:

  1. consul01.dmosk.local (192.168.0.15)
  2. consul02.dmosk.local (192.168.0.20)
  3. consul03.dmosk.local (192.168.0.25)

Тогда вводим команды.

а) Сервер 1:

hostnamectl set-hostname consul01.dmosk.local

б) Сервер 2:

hostnamectl set-hostname consul02.dmosk.local

в) Сервер 3:

hostnamectl set-hostname consul03.dmosk.local

Чтобы серверы могли обращаться друг к другу по именам, мы должны либо зарегистрировать их в локальной системе DNS, либо добавить на каждом сервере записи в файл hosts:

vi /etc/hosts

192.168.0.15 consul01.dmosk.local consul01
192.168.0.20 consul02.dmosk.local consul02
192.168.0.25 consul03.dmosk.local consul03

Проверить доступность серверов по имени можно с помощью команды ping. На каждом из серверов введем:

ping consul01

ping consul02

ping consul03

4. Настройка безопасности

Открываем порты в брандмауэре:

iptables -I INPUT -p tcp --match multiport --dports 8300,8301,8302,8500,8600 -j ACCEPT

iptables -I INPUT -p udp --match multiport --dports 8301,8302,8600 -j ACCEPT

* подробное описание портов есть на странице Что такое Consul.

Для сохранения правил используем утилиту iptables-persistent:

apt install iptables-persistent

netfilter-persistent save

Установка и запуск Consul

Выполним установку компонентов, настройку кластера и его запуск.

Установка

Установка будет выполнена путем копирования бинарного файла. Для начала перейдем на страницу загрузки программного продукта и посмотрим его последнюю версию.

Для некоторых стран, доступ на сайт hashicorp может быть заблокирован. В этом случае, можно воспользоваться VPN/прокси или скачать установочный файл на компьютере, который находится в другой стране.

После подставим нужную версию в переменную (для нашего удобства):

CONSUL_VER="1.17.1"

* на момент обновления инструкции, последняя версия была 1.17.1.

После загружаем архив с бинарником:

wget https://releases.hashicorp.com/consul/${CONSUL_VER}/consul_${CONSUL_VER}_linux_amd64.zip

И распаковываем его в каталог /usr/bin:

unzip consul_*_linux_amd64.zip -d /usr/bin/

Проверяем, что приложение может запускаться в наших системах:

consul -v

Мы должны увидеть что-то на подобие:

Consul v1.17.1
Revision 19041f20
Protocol 2 spoken by default, understands 2 to 3 (agent will automatically use protocol >2 when speaking to compatible agents)

Можно переходить к настройке.

Настройка

Создаем учетную запись, от которой будет работать консул:

useradd -r -c 'Consul DCS service' consul

* в данном примере мы создадим учетную запись consul, которая будет системной. Также мы добавим небольшой комментарий.

Создаем каталоги для приложения консул:

mkdir -p /var/lib/consul /etc/consul.d

И выставим на них нужные права: 

chown consul:consul /var/lib/consul /etc/consul.d

chmod 775 /var/lib/consul /etc/consul.d

* в данном примере мы указали, что владельцем данных каталогов будет созданная учетная запись consul. Права будут полные у владельца, остальные смогут читать данные.

Сгенерируем ключ для консула на любой из нод кластера:

consul keygen

Мы получим последовательность символов, например: 

wHFWVHTstpfh08ZflUs4FD2FAMueraoCN2LyqmeLxV0=

Полученный ключ присваиваем в качестве значения переменной на всех нодах:

CONSUL_TOKEN=wHFWVHTstpfh08ZflUs4FD2FAMueraoCN2LyqmeLxV0=

* где wHFWVHTstpfh08ZflUs4FD2FAMueraoCN2LyqmeLxV0= нужно заменить на тот ключ, который был сгенерирован на вашем сервере.

Также на наших кластерных серверах создадим переменные с указанием всех нод:

CONSUL_SERVER1=consul01.dmosk.local

CONSUL_SERVER2=consul02.dmosk.local

CONSUL_SERVER3=consul03.dmosk.local

Создаем конфигурационный файл для консулов:

cat <<EOF > /etc/consul.d/config.json
{
     "bind_addr": "0.0.0.0",
     "bootstrap_expect": 3,
     "client_addr": "0.0.0.0",
     "datacenter": "dc1",
     "node_name": "$(hostname)",
     "data_dir": "/var/lib/consul",
     "domain": "consul",
     "enable_local_script_checks": true,
     "dns_config": {
         "enable_truncate": true,
         "only_passing": true
     },
     "enable_syslog": true,
     "encrypt": "${CONSUL_TOKEN}",
     "leave_on_terminate": true,
     "log_level": "INFO",
     "rejoin_after_leave": true,
     "retry_join": [
         "${CONSUL_SERVER1}",
         "${CONSUL_SERVER2}",
         "${CONSUL_SERVER3}"
     ],
     "server": true,
     "start_join": [
         "${CONSUL_SERVER1}",
         "${CONSUL_SERVER2}",
         "${CONSUL_SERVER3}"
     ],
    "ui_config": { "enabled": true }
}
EOF

* мы используем команду для создания конфигурационного файла с указанием переменных, созданных ранее. Это делается для нашего удобства работы, чтобы вводить одну и ту же команду на всех нодах.
** где:

  • bind_addr — адрес, на котором будет слушать наш сервер консул. Это может быть IP любого из наших сетевых интерфейсов или, как в данном примере, все.
  • bootstrap_expect — минимально ожидаемое количество серверов в кластере. Consul будет ждать, пока данное число серверов не станет доступным, только после этого загрузит кластер.
  • client_addr — адрес, к которому будут привязаны клиентские интерфейсы.
  • datacenter — привязка сервера к конкретному датацентру. Нужен для логического разделения. Серверы с одинаковым датацентром должны находиться в одной локальной сети.
  • node_name — имя ноды, на которой запускается сервис.
  • data_dir — каталог для хранения данных.
  • domain — домен, в котором будет зарегистрирован сервис.
  • enable_local_script_checks — разрешает на агенте проверку работоспособности сервисов.
  • dns_config — параметры для настройки DNS.
  • enable_syslog — разрешение на ведение лога.
  • encrypt — ключ для шифрования сетевого трафика. В качестве значения используем сгенерированный ранее. Должен быть одинаковый на всех участниках кластера.
  • leave_on_terminate — при получении сигнала на остановку процесса консула, корректно отключать ноду от кластера.
  • log_level — минимальный уровень события для отображения в логе. Возможны варианты "trace", "debug", "info", "warn", and "err".
  • rejoin_after_leave — по умолчанию, нода покидающая кластер не присоединяется к нему автоматически. Данная опция позволяет управлять данным поведением.
  • retry_join — перечисляем узлы, к которым можно присоединять кластер. Процесс будет повторяться, пока не завершиться успешно.
  • server — режим работы сервера.
  • start_join — список узлов кластера, к которым пробуем присоединиться при загрузке сервера.
  • ui_config — конфигурация для графического веб-интерфейса.

Посмотреть итоговую конфигурацию можно командой:

cat /etc/consul.d/config.json

Проверяем корректность конфигурационного файла:

consul validate /etc/consul.d

Мы должны увидеть:

...
Configuration is valid!

* также мы можем увидеть некоторые предупреждения. Например:

  • Node name "consul01.dmosk.local" will not be discoverable via DNS due to invalid characters. Появляется в случае, если мы разрешаем имя сервера в адрес не с помощью внутренней DNS, а при помощи файла hosts.
  • bootstrap_expect > 0: expecting 3 servers. Отображается, если у нас еще настроены не все участники кластера.

В завершение настройки создадим юнит в systemd для возможности автоматического запуска сервиса:

vi /etc/systemd/system/consul.service

[Unit]
Description=Consul Service Discovery Agent
Documentation=https://www.consul.io/
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=consul
Group=consul
ExecStart=/usr/bin/consul agent \
    -config-dir=/etc/consul.d
ExecReload=/bin/kill -HUP $MAINPID
KillSignal=SIGINT
TimeoutStopSec=5
Restart=on-failure
SyslogIdentifier=consul

[Install]
WantedBy=multi-user.target

Перечитываем конфигурацию systemd:

systemctl daemon-reload

Система установлена, настроена и готова к запуску.

Запуск и проверка

Стартуем наш сервис:

systemctl start consul

Также разрешаем автоматический старт при запуске сервера:

systemctl enable consul

Смотрим текущее состояние работы сервиса:

systemctl status consul

Мы должны увидеть состояние:

...
Active: active (running) since ...
...

Состояние нод кластера мы можем посмотреть командой:

consul members

А данной командой можно увидеть дополнительную информацию:

consul members -detailed

Также у нас должен быть доступен веб-интерфейс по адресу: 
http://<IP-адрес любого сервера консул>:8500. Перейдя по нему, мы должны увидеть страницу со статусом нашего кластера.

Аутентификация

При входе на веб-интерфейс или работе из командной строки, мы заметим, что система позволяет выполнять некоторые операции без запроса идентификационных данных, а некоторые действия будут нам недоступны. Для решения проблемы нужно обезопасить систему, настроив ACL.

Включение ACL

Открываем конфигурационные файлы на всех нодах нашего кластера:

vi /etc/consul.d/config.json

Добавляем строки:


  ...
    "ui_config": { "enabled": true },
    "acl": {
        "enabled": true,
        "default_policy": "deny",
        "enable_token_persistence": true
    }
}

* обратите внимание, что строка "ui_config": { "enabled": true }, у нас уже была в конфигурационном файле, но мы добавили запятую в конце, так как это критично для конфига в формате json. Наша добавленная настройка acl запрещает по умолчанию доступ и требует ввода токена безопасности.

Проверяем корректность внесенных настроек:

consul validate /etc/consul.d/config.json

Если ошибок нет, то перезапускаем сервис:

systemctl restart consul

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

В правом верхнем углу веб-панели консула поялась ссылка для входа в систему

Мы идем в правильном направлении.

Работа с токенами

Получаем токен командой:

consul acl bootstrap

* если команда нам вернула ошибку Failed ACL bootstrapping: Unexpected response code: 500 (The ACL system is currently in legacy mode.), то значит, что мы не на всех нодах применили новую настройку. Проверяем, на всех ли серверах кластера внесены соответствующие изменения по добавлению ACL.

Мы получим ответ на подобие:

AccessorID:       af5eaac1-4f0b-d46a-58ba-64ec857dfc4c
SecretID:         59ac7fa8-dca6-e066-ff33-0bf9bb6f466a
Description:      Bootstrap Token (Global Management)
Local:            false
Create Time:      2021-09-01 16:28:58.710545082 +0300 MSK
Policies:
   00000000-0000-0000-0000-000000000001 - global-management

В данном примере 59ac7fa8-dca6-e066-ff33-0bf9bb6f466a — нужный нам для аутентификации SecretID. Возвращаемся в веб-интерфейсу и пробуем войти в систему с использованием данного кода.

Если нам нужно удалить данный токен, вводим команду:

Для работы из командной строки также необходимо авторизоваться. Для этого создаем переменную в системном окружении:

export CONSUL_HTTP_TOKEN=59ac7fa8-dca6-e066-ff33-0bf9bb6f466a

* где 59ac7fa8-dca6-e066-ff33-0bf9bb6f466a, полученный нами SecretID.

Создать новый токен можно командой:

consul acl token create -policy-name global-management

Чтобы увидеть список токенов, вводим:

consul acl token list

Если нам понадобиться удалить токен, мы должны использовать его AccessorID:

consul acl token delete -id 54b5f2bb-1a57-3884-f0ea-1284f84186f5

* где будет удален токен с AccessorID 54b5f2bb-1a57-3884-f0ea-1284f84186f5.

Настройка политики для DNS

После включения ACL наша система перестанет отвечать на запросы DNS. Это связано с политикой блокировки по умолчанию. Для разрешения запросов мы должны создать политику с разрешением данных запросов, получить для ее токен и применить данный токен на всех нодах консула.

На одной из нод создаем файл с политикой:

cd /etc/consul.d/

vi dns-request-policy.txt

node_prefix "" {
  policy = "read"
}
service_prefix "" {
  policy = "read"
}

Создаем политику в консуле:

consul acl policy create -name "dns-requests" -rules @dns-request-policy.txt

Создаем токен безопасности на основе политики:

consul acl token create -description "Token for DNS Requests" -policy-name dns-requests

Мы должны увидеть что-то на подобие:

AccessorID:       b53741e2-7663-eag6-fd67-a64dbd32feb5
SecretID:         42bd65e5-42a5-356b-a81b-60eff20f657
Description:      Token for DNS Requests
Local:            false
Create Time:      2021-09-02 12:37:42.342511655 +0300 MSK
Policies:
   89e42b6b-bbec-5263-bc7b-60f3a604a0d6 - dns-requests

* где SecretID — это нужный нам токен.

На всех компьютерах с consul авторизовываемся:

export CONSUL_HTTP_TOKEN=59ac7fa8-dca6-e066-ff33-0bf9bb6f466a

* где 59ac7fa8-dca6-e066-ff33-0bf9bb6f466a — ранее созданный токен для получения доступа к управлению консулом.

И вводим:

consul acl set-agent-token default 42bd65e5-42a5-356b-a81b-60eff20f657

* где 42bd65e5-42a5-356b-a81b-60eff20f657 — тот SecretID, который мы получили на основе политики, разрешающей запросы DNS.

Читайте также

Вам также может быть интересным:

1. Установка агента Consul и примеры регистрации сервисов.

2. Установка и настройка Consul-template.

# DevOps # Ubuntu # Серверы
Дмитрий Моск — частный мастер
Была ли полезна вам эта инструкция?

Да            Нет