IT заметки по программированию
IT заметки по программированию
IT заметки по программированию
IT заметки по программированию

Создание кластера etcd с TLS с помощью Ansible в Ubuntu 22

Развернем кластер etcd из трех нод.

Общение между нодами будет по TLS протоколу.

На управляющем сервере (локальном компьютере) имеем следующую структуру файлов-директорий:

ansible.cfg:

Указываем путь к файлу инвентаря, повышаем привилегии.

inventory/hosts:

Список нод, на которых будут развернуты экземпляры etcd.

Предварительно должен быть настроен доступ по ssh с помощью ключей.

playbook.yaml — тут будут все задачи по развертыванию кластера.

Ниже представлен полный playbook.yaml. Дальше разберем его содержимое посекционно.

Сначала на текущем сервере создаем сертификаты для TLS обмена данными между нодами кластера.

Создаем директорию для сертификатов:

Генерируем приватные ключи для каждой ноды:

Здесь через переменную {{ groups[‘etcd’] }} — получаем все элементы группы ‘etcd’ из инвентарного файла.

Создание приватных ключей и запросов на подпись сертификата выполняется с помощью модулей openssl_privatekey и openssl_csr соответственно.

Атрибут force: True гарантирует, что приватный ключ генерируется заново, даже если он уже существует.

Генерация запроса на подпись сертификата:

Мы указываем, что данный сертификат может быть использован в механизме цифровой подписи для аутентификации сервера. Этот сертификат ассоциируется с именем хоста (берем IP хоста из инвентаря через переменную hostvars[item].ansible_host), но при проверке необходимо также рассматривать приватные и локальные кольцевые IP-адреса каждого узла в качестве альтернативных имен.

В кластере etcd узлы шифруют сообщения с помощью публичного ключа получателя. Чтобы убедиться в подлинности публичного ключа, получатель упаковывает публичный ключ в запрос на подпись сертификата (CSR) и просит доверенный объект (например, ЦС) подписать CSR. Поскольку мы контролируем все узлы и ЦС, которым они доверяют, нам не нужно использовать внешний ЦС, и мы можем выступать в качестве собственного ЦС. В этом шаге мы будем действовать в качестве собственного ЦС, что означает, что нам нужно будет генерировать приватный ключ и самоподписанный сертификат, который будет функционировать в качестве ЦС.

Затем воспользуйтесь модулем openssl_csr для генерирования нового запроса на подпись сертификата. Это похоже на предыдущий шаг, но в этом запросе на подпись сертификата мы добавляем базовое ограничение и расширение использования ключа, чтобы показать, что данный сертификат можно использовать в качестве сертификата ЦС:

Воспользуемся модулем openssl_certificate для самостоятельной подписи CSR:

Далее мы будем подписывать CSR каждого узла. Это процесс аналогичен тому, как мы использовали модуль openssl_certificate для самостоятельной подписи сертификата ЦС, но вместо использования поставщика selfsigned мы будем использовать поставщика ownca, который позволяет добавлять подпись с помощью нашего собственного сертификата ЦС.

В этом шаге мы подписали CSR каждого узла с помощью ключа ЦС. В следующих шагах мы настроим собственно etcd кластер и скопируем соответствующие файлы сертификатов на каждый управляемый узел, чтобы etcd смог получить доступ к соответствующим ключам и сертификатам для настройки подключений TLS.

 

Далее сгенерируем .pem сертификаты (понадобятся в дальнейшем для HAProxy) — это всего навсего объединение двух файлов сертификата и приватного ключа:

 

А пока создадим на узлах директории для бинарников etcd, скачаем нужную версию, настроим права доступа к директириям:

Каждая задача использует модуль; для этого набора задач мы используем следующие модули:

  • file: для создания каталога /opt/etcd/bin и последующей настройки разрешений файлов для бинарных файлов etcd и etcdctl.
  • get_url: для загрузки тарбола в формате GZIP на управляемые узлы.
  • unarchive: для извлечения и распаковки бинарных файлов etcd и etcdctl из тарбола в формате GZIP.
  • lineinfile: для добавления записи в файл .profile.

Поскольку мы запускаем etcd версии 3.x, последняя команда lineinfile устанавливает для переменной среды ETCDCTL_API значение 3.

Может показаться, что самым быстрым способом запуска etcd с помощью Ansible может быть использование модуля command для запуска /opt/etcd/bin/etcd. Однако этот способ не сработает, поскольку он будет запускать etcd в качестве активного процесса. Использование модуля command будет приводить к зависанию Ansible в ожидании результата, возвращаемого командой etcd, чего никогда не произойдет. Поэтому в этом шаге мы обновим наш плейбук для запуска нашего бинарного файла etcd в качестве фоновой службы.

Ubuntu 22 использует systemd в качестве инит-системы, что означает, что мы можем создавать новые службы, записывая юнит-файлы и размещая их внутри каталога /etc/systemd/system/.

Создадим в каталоге files файл службы etcd.service со следующим содержимым:

Этот юнит-файл определяет службу, которая запускает исполняемый файл в /opt/etcd/bin/etcd, уведомляет systemd о завершении инициализации и перезапускается при каждом случае сбоя.

Далее нам нужно добавить в наш плейбук задачу, которая будет копировать локальный файл files/etcd.service в каталог /etc/systemd/system/etcd.service для каждого управляемого узла. Мы можем сделать это с помощью модуля copy.

Далее останавливаем службу перед внесением изменений.

Создаем директорию для хранения данных:

Создаем директорию для хранения конфигурации etcd:

Копирование сертификатов с локальной машины на ноды etcd:

 

Копируем .pem сертификаты

 

Генерируем из jinja2 шаблона файл конфига для каждой ноды:

Файл конфига содержит настройки кластера и параметры активации TLS.

Шаблон конфига etcd.conf.yaml.j2:

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

И наконец запускаем службу etcd:

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

должно вывести:

https://89.169.167.221:2379 is healthy: successfully committed proposal: took = 26.505599ms
https://130.193.52.254:2379 is healthy: successfully committed proposal: took = 27.199004ms
https://89.169.174.35:2379 is healthy: successfully committed proposal: took = 39.359524ms

кол-во строк — равно количеству нод в кластере.

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

Затем откроем терминал любого другого узла и выполним:

Должно вывести:

А следовательно — кластер успешно работает!

 

 

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *