Перейти к основному содержимому

Задание 2: Развертывание защищенного кластера etcd для Pangolin

По итогам выполнения данной лабораторной работы вы научитесь устанавливать сервис etcd из RPM-пакета на узлах кластера и настраивать его параметры, а также конфигурацию сервиса systemd. Вы сможете подключать SSL-сертификаты для защиты сетевого трафика, выполнять первоначальный запуск с проверкой работоспособности кластера, а также настраивать встроенную аутентификацию и ролевую модель доступа.

Развертывание etcd на узлах кластера​

Внимание!

При использовании менеджеров пакетов дистрибутивов Linux версии предоставляемых пакетов могут быть значительно устаревшими, поэтому для эксплуатации рекомендуется установка из прекомпилированных бинарных файлов. В рамках этой лабораторной работы используется проверенная версия 3.5.12 в формате RPM.

  1. Распространите установочный RPM-пакет с узла srv1 на остальные узлы будущего кластера:

    [student@srv1 ~]$ ls -l etcd-3.5.12-3.red80.x86_64.rpm
    [student@srv1 ~]$ scp etcd-3.5.12-3.red80.x86_64.rpm srv2:~/
    [student@srv1 ~]$ scp etcd-3.5.12-3.red80.x86_64.rpm srv3:~/

    Ожидаемый результат: успешное копирование файла.

  2. Установите пакет etcd на узле srv1:

    [student@srv1 ~]$ sudo dnf install -y etcd-3.5.21.x86_64.rpm

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

Конфигурация etcd для кластера из трех узлов​

Этап 1: Начальная настройка первого узла (srv1):

  1. Ознакомьтесь со стандартным конфигурационным файлом /etc/etcd/etcd.conf. Большинство параметров в нем закомментировано.

  2. Задайте базовую конфигурацию для запуска отдельного узла. Эта конфигурация позже будет изменена:

    [student@srv1 ~]$ vi /etc/etcd/etcd.conf
    ETCD_NAME="srv1"
    ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379"
    ETCD_ADVERTISE_CLIENT_URLS="http://srv1:2379"
    ETCD_LISTEN_PEER_URLS="http://0.0.0.0:2380"
    ETCD_INITIAL_ADVERTISE_PEER_URLS="http://srv1:2380"
    ETCD_INITIAL_CLUSTER_TOKEN="single"
    ETCD_INITIAL_CLUSTER="srv1=http://srv1:2380"
    ETCD_INITIAL_CLUSTER_STATE="new"
    ETCD_DATA_DIR="/var/lib/etcd"
    ETCD_ELECTION_TIMEOUT="5000"
    ETCD_HEARTBEAT_INTERVAL="1000"
    ETCD_ENABLE_V2="true"

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

    • ETCD_NAME: Уникальное имя члена кластера (обычно совпадает с именем хоста);
    • ETCD_LISTEN_PEER_URLS: URL для связи между узлами etcd;
    • ETCD_LISTEN_CLIENT_URLS: URL для клиентских подключений (через etcdctl или Patroni);
    • ETCD_INITIAL_CLUSTER: Список всех участников кластера в формате имя=peer_URL;
    • ETCD_INITIAL_CLUSTER_STATE: new для создания нового кластера, existing для присоединения к существующему.
  3. Настройте сервис systemd для запуска от имени пользователя postgres с повышенным приоритетом ввода-вывода:

    [student@srv1 ~]$ sudo sed -i.bak \
    -e 's/^.*User=.*$/User=postgres/' \
    -e 's/^.*ExecStart.*$/ExecStart=\/bin\/bash -c "GOMAXPROCS=$(nproc) ionice -c2 -n0 \/usr\/bin\/etcd"/' \
    /usr/lib/systemd/system/etcd.service
  4. Измените владельца рабочего каталога etcd:

    [student@srv2 ~]$ sudo chown -R postgres:postgres /var/lib/etcd/
  5. Перезагрузите конфигурацию systemd, активируйте и запустите сервис:

    [student@srv1 ~]$ sudo systemctl daemon-reload
    [student@srv1 ~]$ sudo systemctl enable --now etcd
    [student@srv1 ~]$ sudo systemctl status etcd

    Ожидаемый результат: сервис активен (active (running)).

  6. Проверьте состояние единственного узла кластера:

    [student@srv1 ~]$ etcdctl --endpoints=http://$(hostname -i):2379 -w table member list

    Ожидаемый результат: Таблица с одной строкой, содержащей информацию об узле srv1.

Этап 2: Добавление второго узла (srv2):

  1. Установите etcd и настройте сервис systemd на узле srv2 (команды аналогичны шагам для srv1). Убедитесь, что каталог данных принадлежит пользователю postgres.

  2. Вернитесь на узел srv1 и добавьте srv2 в кластер:

    [student@srv1 ~]$ etcdctl --endpoints=http://$(hostname -i):2379 member add srv2 --peer-urls="http://srv2:2380"
    Внимание!

    Команда выведет переменные среды, которые необходимо использовать для конфигурации srv2.

  3. На узле srv2 замените содержимое /etc/etcd/etcd.conf на значения, полученные на предыдущем шаге. Ключевые параметры:

    ETCD_NAME="srv2"
    ETCD_INITIAL_CLUSTER="srv1=http://srv1:2380,srv2=http://srv2:2380"
    ETCD_INITIAL_CLUSTER_STATE="existing" # Узел присоединяется к существующему кластеру
    ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379"
    ETCD_ADVERTISE_CLIENT_URLS="http://srv2:2379"
    ETCD_LISTEN_PEER_URLS="http://0.0.0.0:2380"
  4. Перезапустите etcd на srv2 и проверьте состояние кластера с любого узла:

    [student@srv1 ~]$ etcdctl --endpoints=http://<IP-Address1>:2379,http://<IP-Address2>:2379 -w table member list
    [student@srv1 ~]$ etcdctl --endpoints=http://<IP-Address1>:2379,http://<IP-Address2>:2379 -w table endpoint health

    Ожидаемый результат: В списке членов кластера два узла, оба имеют статус healthy.

Этап 3: Добавление третьего узла (srv3):

Процедура аналогична добавлению srv2:

  1. Установите etcd и настройте сервис.
  2. С узла srv1 или srv2 выполните etcdctl member add.
  3. Настройте конфигурационный файл srv3 с полученными параметрами, указав ETCD_INITIAL_CLUSTER_STATE="existing".
  4. Запустите сервис и проверьте состояние трех-узлового кластера.
Внимание!

Для отказоустойчивости рекомендуется использовать кластеры с 3, 5 или 7 узлами. Кластер из трех узлов может выдержать отказ одного узла, сохраняя кворум.

Подключение SSL-сертификатов к etcd​

Для защиты трафика в производственном кластере необходимо использовать TLS-шифрование. Мы настроим etcd на использование сертификатов, созданных в предыдущей лабораторной работе.

  1. Остановите сервис etcd на всех узлах:

    [student@srv1 ~]$ for comp in srv{1..3}; do
    ssh $comp sudo systemctl stop etcd
    done
  2. На узле srv1 создайте новую конфигурацию /etc/etcd/etcd.conf, включающую настройки TLS. Обратите внимание на смену протокола с http на https:

    [student@srv1 ~]$ vi /etc/etcd/etcd.conf
    ETCD_NAME="srv1"
    ETCD_LISTEN_CLIENT_URLS="https://0.0.0.0:2379"
    ETCD_ADVERTISE_CLIENT_URLS="https://srv1:2379"
    ETCD_LISTEN_PEER_URLS="https://0.0.0.0:2380"
    ETCD_INITIAL_ADVERTISE_PEER_URLS="https://srv1:2380"
    ETCD_INITIAL_CLUSTER_TOKEN="single"
    ETCD_INITIAL_CLUSTER="srv1=https://srv1:2380,srv2=https://srv2:2380,srv3=https://srv3:2380"
    ETCD_INITIAL_CLUSTER_STATE="new"
    ETCD_DATA_DIR="/var/lib/etcd"
    ETCD_ELECTION_TIMEOUT="5000"
    ETCD_HEARTBEAT_INTERVAL="1000"
    ETCD_ENABLE_V2="true"
    ETCD_LOG_OUTPUTS="/pgerrorlogs/06/etcd/etcd.log"
    # SSL/TLS
    ETCD_CIPHER_SUITES="TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"
    ETCD_TRUSTED_CA_FILE="/pg_ssl/root.crt"
    ETCD_CERT_FILE="/pg_ssl/server.crt"
    ETCD_KEY_FILE="/pg_ssl/server.key"
    ETCD_PEER_TRUSTED_CA_FILE="/pg_ssl/root.crt"
    ETCD_PEER_CERT_FILE="/pg_ssl/server.crt"
    ETCD_PEER_KEY_FILE="/pg_ssl/server.key"
    ETCD_PEER_CLIENT_CERT_AUTH="true"
    EOF
  3. Скопируйте эту конфигурацию на узлы srv2 и srv3, заменив значения ETCD_NAME и соответствующих URLs:

    [student@srv1 ~]$ sed -e '/^ETCD_NAME/s/srv1/srv2/' \
    -e '/^ETCD_ADVERTISE_CLIENT_URLS/s/srv1/srv2/' \
    -e '/^ETCD_INITIAL_ADVERTISE_PEER_URLS/s/srv1/srv2/' \
    /etc/etcd/etcd.conf | ssh srv2 sudo tee /etc/etcd/etcd.conf

    Аналогично для srv3.

  4. Подготовьте каталоги для данных и логов на всех узлах, назначив правильные права:

    [student@srv1 ~]$ for comp in srv{1..3}; do
    ssh $comp sudo rm -rf /var/lib/etcd
    ssh $comp sudo mkdir -p /var/lib/etcd /pgerrorlogs/06/etcd
    ssh $comp sudo chown -R postgres:postgres /var/lib/etcd /pgerrorlogs/06/etcd
    ssh $comp sudo chmod 700 /var/lib/etcd
    ssh $comp sudo chmod 770 /pgerrorlogs/06/etcd
    done
  5. Запустите etcd на всех трех узлах максимально одновременно. Используйте отдельные SSH-сессии или выполните команды в фоновом режиме с минимальной задержкой. На srv1, srv2, srv3 выполните:

    [student@srv1 ~]$ sudo systemctl enable --now etcd

    Ожидаемый результат: Сервис успешно запускается на всех узлах.

Проверка работоспособности защищенного кластера etcd​

Все проверки необходимо выполнять от имени пользователя postgres, так как он является владельцем сертификатов.

  1. Проверьте состояние всех конечных точек (endpoints) кластера:

    [student@srv1 ~]$ sudo su - postgres
    [postgres@srv1 ~]$ ETCDCTL_API=3 etcdctl \
    --endpoints=https://srv1:2379,https://srv2:2379,https://srv3:2379 \
    --cert=/pg_ssl/server.crt \
    --key=/pg_ssl/server.key \
    --cacert=/pg_ssl/root.crt \
    endpoint health -w table --cluster

    Ожидаемый результат: Для всех трех ENDPOINT в колонке HEALTH должно быть значение true.

  2. Получите подробный статус и список членов кластера:

    [postgres@srv1 ~]$ ETCDCTL_API=3 etcdctl ... endpoint status -w table --cluster
    [postgres@srv1 ~]$ ETCDCTL_API=3 etcdctl ... member list -w table

    Ожидаемый результат: В статусе один узел имеет IS LEADER: true, остальные false. В списке членов отображаются все три узла с их PEER и CLIENT адресами.

Настройка аутентификации и ролей в etcd​

Для безопасной работы Patroni с etcd требуется настроить пользователей и роли.

  1. Создайте пользователя root (администратор) и patronietcd (для службы Patroni):

    [postgres@srv1 ~]$ ETCDCTL_API=3 etcdctl \
    --endpoints=https://srv1:2379,https://srv2:2379,https://srv3:2379 \
    --cert=/pg_ssl/server.crt \
    --key=/pg_ssl/server.key \
    --cacert=/pg_ssl/root.crt \
    user add root

    Введите и подтвердите пароль, например, root123.

    [postgres@srv1 ~]$ ETCDCTL_API=3 etcdctl --endpoints=https://srv1:2379,https://srv2:2379,https://srv3:2379 \
    --cert=/pg_ssl/server.crt \
    --key=/pg_ssl/server.key \
    --cacert=/pg_ssl/root.crt \
    user add patronietcd

    Введите и подтвердите пароль, например, patronietcd123.

  2. Создайте роль patroni и предоставьте ей права на чтение и запись в ключевом пространстве /service/*, которое будет использовать Patroni:

    [postgres@srv1 ~]$ ETCDCTL_API=3 etcdctl --endpoints=https://srv1:2379,https://srv2:2379,https://srv3:2379 \
    --cert=/pg_ssl/server.crt \
    --key=/pg_ssl/server.key \
    --cacert=/pg_ssl/root.crt \
    role add patroni
    [postgres@srv1 ~]$ ETCDCTL_API=3 etcdctl --endpoints=https://srv1:2379,https://srv2:2379,https://srv3:2379 \
    --cert=/pg_ssl/server.crt \
    --key=/pg_ssl/server.key \
    --cacert=/pg_ssl/root.crt \
    role grant-permission patroni readwrite '/service/*'
  3. Свяжите роль patroni с пользователем patronietcd:

    [postgres@srv1 ~]$ ETCDCTL_API=3 etcdctl --endpoints=https://srv1:2379,https://srv2:2379,https://srv3:2379 \
    --cert=/pg_ssl/server.crt \
    --key=/pg_ssl/server.key \
    --cacert=/pg_ssl/root.crt \
    user grant-role patronietcd patroni
  4. Включите аутентификацию в кластере etcd:

    [postgres@srv1 ~]$ ETCDCTL_API=3 etcdctl --endpoints=https://srv1:2379,https://srv2:2379,https://srv3:2379 \
    --cert=/pg_ssl/server.crt \
    --key=/pg_ssl/server.key \
    --cacert=/pg_ssl/root.crt \
    auth enable
    Внимание!

    После включения аутентификации все последующие запросы к etcd должны будут предоставлять корректные учетные данные (сертификат или логин/пароль). Для упрощения дальнейшей настройки Patroni в рамках этого курса аутентификацию можно временно отключить командой auth disable, но в реальной эксплуатации она обязательна.

Подведем итоги​

Вопрос 1

Вопрос 1: Взгляните на приведенные команды:

[student@srv1 ~]$ etcdctl --endpoints=http://$(hostname -i):2379 -w table member list
+------------------+---------+------+------------------+------------------+------------+
|        ID        | STATUS  | NAME |    PEER ADDRS    |   CLIENT ADDRS   | IS LEARNER |
+------------------+---------+------+------------------+------------------+------------+
| 98d57be5fdf696bb | started | srv1 | http://srv1:2380 | http://srv1:2379 |      false |
+------------------+---------+------+------------------+------------------+------------+

Выберите верные утверждения о данной ситуации:

Вопрос 2

Какое значение параметра ETCD_INITIAL_CLUSTER_STATE необходимо указать при присоединении нового узла к уже существующему кластеру etcd?

Вопрос 3

После изменения файла /usr/lib/systemd/system/etcd.service (замена User и ExecStart) какая команда должна быть выполнена сразу?