Konfiguracja IP failover w oparciu o keepalived

Przykładowa konfiguracja – dwa serwery: SerwerTestowy oraz SerwerTestowy2.
Na obu serwerach został zainstalowany system Debian 9. Jeden adres dodatkowy: 172.168.0.1

W pierwszej kolejności należy przygotować w panelu Klienta unikalne adresy URL, po wywołaniu których nastąpi przekierowanie adresu IP z jednego serwera na drugi.

  1. Z menu wybieramy opcję „Adresacja IP”:
  2. Przy serwerze, do którego jest przypisany nasz adres dodatkowy, należy wybrać Utwórz link.
  3. Tworzymy akcję przeniesienia adresu – operację wykonujemy kolejno dla obu serwerów:
    Do SerwerTestowy

    oraz do SerwerTestowy2
  4. W panelu zostały stworzone dwa adresy URL:

Po wywołaniu pierwszego URL:
https://panel.atman.pl/addr-move-link-execute/[TOKEN] adres IP 172.16.0.1 zostanie przypisany do SerwerTestowy. Po wywołaniu drugiego URL podany IP zostanie przypisany do serwera SerwerTestowy2. Utworzone adresy URL można wywoływać z poziomu dowolnego klienta HTTP (np. wget czy curl).

Rozpoczynamy od konfiguracji adresacji IP na serwerach. Adresy podstawowe powinny zostać skonfigurowane przy instalacji automatycznej. Jeśli do serwera w czasie instalacji był przypisany adres dodatkowy, to został on również skonfigurowany przez nasz instalator.

Poniżej zawartość plików /etc/network/interfaces dla obu serwerów.

Konfiguracja dla serwera SerwerTestowy może wyglądać jak poniżej (interfejs publiczny dla serwera to eth1):

auto eth1
iface eth1 inet static
        address 192.168.0.227
        netmask 255.255.255.254
        gateway 192.168.0.226

iface eth1 inet static
        address 172.16.0.1
        netmask 255.255.255.255

Konfiguracja dla serwera SerwerTestowy2 (interfejs publiczny dla serwera to eth0).:

auto eth0
iface eth0 inet static
        address 192.168.0.110
        netmask 255.255.255.254
        gateway 192.168.0.111

iface eth0 inet static
        address 172.16.0.1
        netmask 255.255.255.255

Proszę zwrócić uwagę, że adres dodatkowy 172.16.0.1 został skonfigurowany jednocześnie na obu serwerach. Taka konfiguracja jest poprawna – domyślnie każdy serwer znajduje się w izolowanym VLAN-ie i komunikacja na poziomie warstwy drugiej między serwerami nie jest możliwa (mówimy tutaj o interfejsach sieci publicznej). Dodatkowo taka konfiguracja ułatwia uruchamianie usług redundantnych powiązanych z danym adres IP (który jest aktywny na obu serwerach). Jeśli z jakiegoś powodu taka konfiguracja jest niepożądana, adres IP można odpowiednio aktywować/dezaktywować przy zmianie stanu keepalived MASTER/BACKUP (niniejsza instrukcja nie zawiera takich przykładów) i w tym przypadku konieczne jest dodanie poniższego wpisu do pliku /etc/sysctl.conf.

net.ipv4.ip_nonlocal_bind=1

Zmiany można wprowadzić wydając polecenie:

sysctl -p

Taka zmiana pozwala na nasłuchiwanie aplikacji na nieistniejących adresach IP.

apt-get update
apt-get install keepalived

Plik konfiguracyjny /etc/keepalived/keepalived.conf na serwerze SerwerTestowy:

vrrp_instance ECO {
    interface eth1
    state MASTER
    priority 101

    virtual_router_id 10
    unicast_src_ip 192.168.0.227
    unicast_peer {
        192.168.0.110
    }

    authentication {
        auth_type PASS
        auth_pass zmienmnie
    }

    notify_master /etc/keepalived/eco-ip-failover-master.sh
}

Plik konfiguracyjny /etc/keepalived/keepalived.conf na serwerze SerwerTestowy2:

vrrp_instance ECO {
    interface eth0
    state MASTER
    priority 100

    virtual_router_id 10
    unicast_src_ip 192.168.0.110
    unicast_peer {
        192.168.0.227
    }

    authentication {
        auth_type PASS
        auth_pass zmienmnie
    }

    notify_master /etc/keepalived/eco-ip-failover-master.sh
}

W obu plikach zdefiniowana jest jedna instancja VRRP o nazwie ECO. Określone są interfejsy, przez które odbywać ma się komunikacja (odpowiednio eth1 i eth0). Dla obu instancji wybrany jest stan MASTER. Przy uruchamianiu keepalived przeprowadzi proces wyboru, w którym jeden z serwerów zostanie wyznaczony do roli MASTER, a drugiemu zostanie przypisana rola BACKUP. Za pomocą parametru priority można określić, który serwer ma być preferowany jako master (wyższa wartość). Parametr virtual_router_id musi być identyczny na obu serwerach.

Kolejne parametry unicast_src_ip oraz unicast_peer pozwalają na ustawienie adresów IP obu serwerów. Keepalived domyślnie wykorzystuje multicast do komunikacji – niestety wykorzystanie multicastu do komunikacji w sieci publicznej w infrastrukturze ECO nie jest możliwe. Konfiguracja powyższych parametrów umożliwia komunikację unicast między serwerami.

Sekcja authentication pozwala na ustawienie hasła wykorzystywanego do uwierzytelniania komunikacji między serwerami (długość hasła jest ograniczona do 8 znaków). Należy też pamiętać, że hasło jest przesyłane tekstem otwartym.

Ostatni parametr notify_master pozwala na wskazanie skryptu, który ma być uruchamiany po promocji serwera do stanu MASTER. W naszym przykładzie skrypt ten jest wykorzystywany do przełączenie dodatkowego adresu IP na aktualny serwer.

Zadaniem skryptu jest wywołanie przygotowanego wcześniej adresu URL, które spowoduje przełączenie adresu dodatkowego na wskazany serwer. Skrypt może składać się wyłącznie np. z wywołania wygenerowanego adresu URL:

!/bin/sh
curl -s -k https://panel.atman.pl/addr-move-link-execute/[TOKEN]

Może być też bardziej skomplikowany i np. uruchamiać wymagane usługi, czyścić cache, ustawiać adres IP itp.

Poniżej bardziej rozbudowany przykład skryptu eco-ip-failover-master.sh. Skrypt wywołuje wskazany w zmiennej ECOURL adres. Dodatkowo sprawdza status zwrócony przez URL. W przypadku, gdy zwrócony jest jest kod błędu, skrypt próbuje przez kolejną minutę wykonać przełączenie (parametry MAXTRIES * RETRYWAIT).

#!/bin/bash
# Disclaimer: This script is provided "as is" without warranty of any kind
# Oswiadczenie: skrypt ten jest udostepniony bez zadnych gwarancji
#
# NOTE: return codes doesn’t matter for notify scripts - please consider this in your failover logic

# callback URL
ECOURL="https://panel.atman.pl/addr-move-link-execute/[TOKEN]"

# Configuration
MAXTRIES=10
RETRYWAIT=6

if [ ! -x /usr/bin/curl ]
then
        logger "KEEPALIVED: missing curl cli command"
        exit
fi

code=0
retry=1
until [ $retry -gt $MAXTRIES ]
do
        status=$(curl -s -k "$ECOURL")
        # $1 - return code
        set -- $status
        code=$1
        logger "KEEPALIVED IP switch status($retry): $code ($status)"
        ((retry++))
        case "$code" in
                50|51)
                        exit 1
                        ;;
                52)
                        sleep $RETRYWAIT
                        ;;
                20)
                        exit 0
                        ;;
                *)
                        logger "KEEPALIVED IP switch status($retry): unknow code returned"
                        exit 1
        esac
done
logger "KEEPALIVED IP switch status($retry): ABORTED"
exit 1

W naszym przykładzie pod zmienną ECOURL należy podstawić odpowiedni URL z Tokenem widocznym w panelu:

ECOURL="https://panel.atman.pl/addr-move-link-execute/[TOKEN]"

Przykładowe reguły dla iptables.

Dla serwera SerwerTestowy:

iptables -I INPUT -p vrrp -j DROP
iptables -I INPUT -p vrrp -s 192.168.0.110 -j ACCEPT

Dla serwera SerwerTestowy2:

iptables -I INPUT -p vrrp -j DROP
iptables -I INPUT -p vrrp -s 192.168.0.227 -j ACCEPT

Domyślnie w systemach Debian przy instalacji systemu nie są ustawiane żadne reguły iptables, więc powyższe wpisy mogą być zbyteczne.

W pliku /etc/default/keepalived można podać poniższy parametr, który uruchamia tylko podsystem VRRP keepalived:

DAEMON_ARGS="-P"
systemctl enable keepalived.service
systemctl restart keepalived.service

Po uruchomieniu keepalived należy sprawdzić na obu serwerach zawartość pliku /var/log/messages. Powinny tam pojawić się informacje o tym, czy aplikacja uruchomiła się prawidłowo oraz o statusie MASTER/BACKUP.

Przykładowe informacje z pliku log:

Mar  8 00:03:54 SerwerTestowy Keepalived_vrrp[544]: Registering Kernel netlink reflector
Mar  8 00:03:54 SerwerTestowy Keepalived_vrrp[544]: Registering Kernel netlink command channel
Mar  8 00:03:54 SerwerTestowy Keepalived_vrrp[544]: Registering gratuitous ARP shared channel
Mar  8 00:03:54 SerwerTestowy Keepalived_vrrp[544]: Opening file '/etc/keepalived/keepalived.conf'.
Mar  8 00:03:54 SerwerTestowy Keepalived_vrrp[544]: Truncating auth_pass to 8 characters
Mar  8 00:03:54 SerwerTestowy Keepalived_vrrp[544]: Configuration is using : 60829 Bytes
Mar  8 00:03:54 SerwerTestowy Keepalived_vrrp[544]: Using LinkWatch kernel netlink reflector...
Mar  8 00:03:59 SerwerTestowy Keepalived_vrrp[544]: VRRP_Instance(ECO) Transition to MASTER STATE
Mar  8 00:04:00 SerwerTestowy Keepalived_vrrp[544]: VRRP_Instance(ECO) Entering MASTER STATE
Mar  8 00:04:11 SerwerTestowy logger: KEEPALIVED IP switch status(1): 20 (20 OK)