Пример использования keepalived на Linux

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

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

Мы рассмотрим пошаговую процедуру установки keepalived и настройки кластера Master - Slave с плавающим IP-адресом (VIP — virtual ip). Проверку работоспособности сервиса будем выполнять на примере с веб-сервером NGINX.

Также мы не будем привязываться к конкретному дистрибутиву Linux, учитывая разные варианты.

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

Для корректной работы кластера нужно предусмотреть некоторые настройки безопасности системы.

Брандмауэр

Keepalived для обеспечения высокой доступности использует протокол VRRP. Для его работы фаервол должен пропускать трафик для протокола vrrt на широковещательный адрес 224.0.0.18.

В зависимости от утилиты управления брандмауэром наши действия будут отличаться.

а) Для iptables (как правило, в системах на основе deb):

iptables -I INPUT -p vrrp -d 224.0.0.18 -j ACCEPT

Чтобы сохранить правила, можно использовать iptables-persistent:

apt install iptables-persistent

netfilter-persistent save

б) Для firewalld (как правило, в системах на основе rpm):

firewall-cmd --permanent --add-rich-rule='rule protocol value="vrrp" accept'

firewall-cmd --reload

SELinux

Для систем, где используется SELinux (по умолчанию, в RPM) мы можем столкнуться с проблемами запуска скриптов notify.

Иногда, администраторы предпочитают просто отключать SELinux. Для этого нужно ввести несколько команд:

setenforce 0

sed -i 's/^SELINUX=.*/SELINUX=disabled/g' /etc/selinux/config

* первая команда отключит SELinux для текущей загрузки, вторая — для последующих. Подробнее в инструкции Как отключить SELinux.

Но мы также рассмотрим варианты настройки сервера без отключения SELinux. Об этом будет ниже (в разделе с настройкой notify).

Установка

В популярных дистрибутивах Linux keepalived включен в официальный репозиторий и может быть установлен из него. В зависимости от типа Linux действия будут немного отличаться.

а) Для систем на базе Deb (Debian / Ubuntu / Astra Linux):

apt update

apt install keepalived

б) Для систем на базе RPM (Rocky Linux / РЕД ОС):

yum install keepalived

Настройка кластера

Предположим, что есть два сервера nginx, и нам нужно, чтобы пользователи подключались только к одному из них. Мы настроим кластер с плавающим IP-адресом, который будет добавляться на сетевой интерфейс только для одного из серверов.

Если мы работаем на тестовых серверах, на которых нет nginx, выполняем его установку одной из команд:

apt install nginx

yum install nginx

* первая команда для дистрибутивов deb, вторая — rpm.

Создаем конфигурационный файл.

а) На первом сервере:

vi /etc/keepalived/keepalived.conf

global_defs {
    enable_script_security
}

vrrp_script nginx_check {
    script "/usr/bin/curl http://127.0.0.1"
    interval 5
    user nginx
}

vrrp_instance web {
    state MASTER
    interface eth0
    virtual_router_id 254
    priority 100
    advert_int 2
    authentication {
        auth_type PASS
        auth_pass 12345678
    }
    virtual_ipaddress {
        192.168.0.254
    }
    track_script {
        nginx_check
    }
}

б) На втором сервере:

vi /etc/keepalived/keepalived.conf

global_defs {
    enable_script_security
}

vrrp_script nginx_check {
    script "/usr/bin/curl http://127.0.0.1"
    interval 5
    user nginx
}

vrrp_instance web {
    state BACKUP
    interface eth0
    virtual_router_id 254
    priority 50
    advert_int 2
    preempt_delay 30
    authentication {
        auth_type PASS
        auth_pass 12345678
    }
    virtual_ipaddress {
        192.168.0.254
    }
    track_script {
        nginx_check
    }
}

* оба конфигурационных файла отличаются опцией state. На первом сервере мы задаем ей значение MASTER, предполагая, что он будет основным по умолчанию, второму — BACKUP. Также на втором сервере дополнительна указана директива preempt_delay.
** пройдем по разделам:

  • global_defs — задает глобальные настройки. В нашем примере мы разрешаем использование скриптов. В противном случае, keepalived будет возвращать ошибки при использовании скриптов проверки состояния и запуска notify (о нем ниже).
  • vrrp_script — описание процесса проверки сервиса. Мы не ограничены в способах — shell-скрипт должен вернуть 0, если все хорошо или другой код ответа, если все плохо. В данном примере мы отправляем запрос на 80 порт, на котором слушает веб-сервер. Если он работает, то команда вернет правильный код ответа. Однако, nginx может слушать на другом порту и это нужно учитывать. Также есть и другие варианты проверки работы nginx, например, команды killall -0 nginx и pidof nginx. Опция interval указывает на периодичность проверки в секундах; опция user задает пользователя. от которого будет выполняться скрипт.
  • vrrp_instance — настройки для экземпляра сервиса. В нашем примере мы дали название экземпляру web. Вы можете задать свое.

*** и опишем опции раздела vrrp_instance:

  • state — задает начальное состояние ноды. В нашем случае первая MASTER, вторая BACKUP. Важно отметить, что если в конфигурации будет опция nopreempt, возможен только вариант BACKUP.
  • interface — название сетевого интерфейса, на который будет добавлен VIP адрес, если сервер станет мастером.
  • virtual_router_id — идентификатор VRRP. Может принимать значение от 1 до 255. Должен быть одинаковым для всех узлов, входящих в кластер.
  • priority — приоритет узла. Мастером будет назначен сервер с работающим сервисом и самым высоким приоритетом.
  • advert_int — время в секундах, с которой мастер должен сообщать о себе другим нодам. Если за данное время он не успеет отправить широковещательный сигнал, начнутся выборы другого мастера.
  • preempt_delay — опция позволяет определить поведение мастера при восстановлении сервиса. Задает время в секундах, после которого сервер с более высоким приоритетом заберет обратно себе роль мастера. Стоит отметить, что при наличии опции nopreempt бывшему мастеру не разрешается возвращать свое старое состояние. Опция игнорируется на сервере, где в качестве начального состояния указано MASTER.
  • authentication — данный блок описывает опции авторизации. Так как запросы широковещательные, очень важно использовать аутентификацию. В данном примере используется пароль 12345678.
  • virtual_ipaddress — блок задает VIP.
  • track_script — указываем скрипт, с помощью которого будет проверяться работоспособность сервиса.

Так как для проверки работы сервиса мы используем утилиту curl, убедимся, что она есть в системе, установив ее.

а) Для систем на базе Deb (Debian / Ubuntu / Astra Linux):

apt update

apt install curl

б) Для систем на базе RPM (Rocky Linux / РЕД ОС):

yum install curl

Теперь проверим работу keepalived.

Разрешим автозапуск сервиса и запустим его:

systemctl enable keepalived

systemctl start keepalived

Проверим его состояние командой:

systemctl status keepalived

Теперь командой:

ip a

... мы должны на мастере увидеть дополнительный адрес (в нашем примере 192.168.0.254). Это VIP, назначенный keepalived.

Попробуем на этом же сервере остановить nginx:

systemctl stop nginx

VIP должен оказаться на втором сервере.

Теперь запустим nginx:

systemctl start nginx

Через какое-то время, в соответствии с параметром preempt_delay, VIP вернется.

Автоматизация при смене состояния

Keepalived предусматривает возможность запуска скрипта, который выполняет любые команды при смене состояния с MASTER на BACKUP и наоборот. Рассмотрим подробнее.

В конфигурационные файлы (раздел vrrp_instance) добавим:

vi /etc/keepalived/keepalived.conf

vrrp_instance web {
    ...
    notify /etc/keepalived/notify-web.sh root
}

* при смене состояния должен быть выполнен скрипт /etc/keepalived/notify-web.sh от пользователя root.

Теперь создадим сам скрипт, примерно, такого содержания:

vi /etc/keepalived/notify-web.sh

#!/bin/bash
PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin

SCRIPT_NAME=$0
TYPE=$1
INST_NAME=$2
STATE=$3
PRIOR=$4
ALL_ARGS=$@

case $STATE in
        "MASTER") echo "[$(date)] MASTER UP with prior ${PRIOR}" >> "/var/log/keepalived/${INST_NAME}.log"
                  ;;
        *)        echo "[$(date)] change MASTER. I am slave with prior ${PRIOR}" >> "/var/log/keepalived/${INST_NAME}.log"
                  ;;
esac

* в данном примере мы просто добавляем строку в файл лога. Для сервера, который стал мастером и остальными серверами текст немного отличается. Также обратите внимание на аргументы, которые keepalived передаст скрипту:

  • $0 — путь до скрипта, который запускает (в нашем примере /etc/keepalived/notify-web.sh).
  • $1 — тип vrrp. Может быть GROUP или INSTANCE (как в нашем случае).
  • $2 — имя инстанса или группы. У нас это web.
  • $3 — состояние. Могут быть MASTER, BACKUP, FAULT, * (любое).
  • $4 — приоритет ноды, который указан в конфигурационном файле keepalived.
  • $@ — все вышеперечисленные параметры через пробел.

Разрешив запускать скрипт на выполнение:

chmod +x /etc/keepalived/notify-web.sh

В нашем конкретном случае также нужно создать каталог для логов:

mkdir /var/log/keepalived

Перезапустим keepalived:

systemctl restart keepalived

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

Работа с SELinux

Как было сказано выше, в работе notify могут быть сбои, если система использует SELinux. Для решения проблемы можно использовать разные способы.

1. Изменить контекст безопасности для скрипта

SELinux сверяет контексты безопасности процессов и файлов с политиками доступа. Например, для запуска на выполнение скриптов, файлу должен быть присвоен контекст keepalived_unconfined_script_exec_t. В нашем примере это можно сделать командой:

semanage fcontext -a -t keepalived_unconfined_script_exec_t /etc/keepalived/notify-web.sh

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

restorecon -R -v /etc/keepalived/notify-web.sh

* не забываем поменять /etc/keepalived/notify-web.sh на полный путь к вашему скрипту.

2. Использовать специальный каталог для хранения скриптов

Второй способ может показаться проще. Нужно использовать каталог, для которого уже выставлен контекст keepalived_unconfined_script_exec_t.

Путь до него — /usr/libexec/keepalived. Переносим наш скрипт в него и меняем путь в конфигурационном файле keepalived.

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

Да            Нет