Hlavní navigace

Velká řešení otevřeně: spolehlivá a škálovatelná síť

Jan Baier

Hardware je připraven, operační systém běží. Co teď s tím? Abychom vůbec mohli mluvit o clusteru, potřebujeme zajistit rozkládání zátěže (tzn. load-balancing) a zabezpečení proti výpadku (tzn. failover).

Počáteční nastavení

Chceme-li nabízet nějaké služby na internetu, bude potřeba na serverech provést síťovou konfiguraci. Možností, jak toho docílit, je dnes již více – ip, ifconfig, NetworkManager, systemd, … Každý způsob má své zastánce i odpůrce.

Pokud by někdo chtěl, stejně jako já, k tomuto účelu využít systemd, měl by se v první řadě ujistit, že je aktivovaný modul systemd-networkdsystemctl enable systemd-networkd.

Nejprve si v systému vytvoříme síťový „bridge“, do kterého budeme v budoucnu moci připojovat případné virtuální servery (soubor .netdev). Poté si do nově vytvořeného rozhraní přidáme hlavní síťové rozhraní a nakonec celému mostu přiřadíme síťovou konfiguraci (soubory .network).

# /etc/systemd/network/bridge.netdev
[NetDev]
Name=br0
Kind=bridge
# /etc/systemd/network/ethernet.network
[Match]
MACAddress=00:00:5E:00:53:01

[Network]
Bridge=br0
# /etc/systemd/network/bridge.network
[Match]
Name=br0

[Network]
Address=198.51.100.101/24
Gateway=198.51.100.1

Nakonec stačí konfiguraci načíst „nakopnutím“ síťového démona: systemctl restart systemd-networkd. Konfigurace by se měla okamžitě načíst, stejně tak se ihned objeví nová síťová rozhraní.

Pozn.: Povšimněte si, že v konfiguraci se nikde nevyskytuje jméno fyzického síťového rozhraní. Veškerá konfigurace se mapuje dle MAC adresy. To vidím jako jednu z výhod při použití systemd-networkd.

Velmi obdobně poté (nebo v případě použití nástrojů typu Ansible najednou) nastavíme ostatní stroje. Pro účely tohoto článku budu nyní předpokládat dva servery s adresami 198.51.100.101/24 a 198.51.100.102/24.

Fail-over pomocí DNS

Jedním ze způsobů, jak pojistit službu proti výpadku, je využít přímo možnosti DNS. Stačí, abychom v doménovém záznamu měli uvedeno více IP adres. Další služby pak lze uvádět jednoduše jako aliasy na již existující záznamy, takže se v případě většího množství záznamů ani příliš neupíšeme.

server.example.net  IN  A       198.51.100.101
server.example.net  IN  A       198.51.100.102

www.example.net     IN  CNAME   server.example.net.

Tímto způsobem jsme nádavkem získali i vyvažování zátěže, neboť DNS server nám nejenom vrátí více položek, ale také zamíchá s pořadím, takže různí klienti budou jako první přistupovat na různé servery.

Funguje to skvěle, ale má to jeden háček. Aby to bylo účinné, je potřeba podpora na straně klienta. Ne všechny aplikace totiž umí využít vícero záznamů a v případě nedostupnosti jednoho použít další v pořadí. Zcela bezchybně to funguje například u e-mailových služeb (jen je třeba použít záznam typu MX) či adresářových služeb (OpenLDAP). Pro webové aplikace však toto nefunguje úplně nejlépe. Weboví klienti mají tendenci tvrdohlavě používat první položku na seznamu i přesto, že je zrovna tento server momentálně nedostupný. Nicméně je toto řešení vhodné alespoň pro vyvažování zátěže.

Fail-over na úrovni IP

Další možnost jak zajistit odolnost proti výpadku serveru je tzv. plovoucí IP adresa. Budeme mít adresu, která bude přiřazena právě jednomu fyzickému stroji, ale ve chvíli, kdy se ten stane nedostupným (například z důvodu jeho hardwarového selhání), adresa transparentně přejde na jiný stroj. Využijeme protokolu VRRP (Virtual Router Redundancy Protocol) a nástroje keepalived.

Základní konfigurace, která nám zajistí, že virtuální adresa 198.51.100.10 bude přidělena právě jednomu funkčnímu stroji, by vypadala zhruba takto:

# server1: /etc/keepalived/keepalived.conf
global_defs {
    lvs_id LoadBalancer1
}
vrrp_sync_group Group1 {
    group {
        FloatIP1
    }
}
vrrp_instance FloatIP1 {
    interface bridge
    virtual_router_id 10
    priority 150
    advert_int 1
    virtual_ipaddress {
        198.51.100.10
    }
}
# server2: /etc/keepalived/keepalived.conf
global_defs {
    lvs_id LoadBalancer2
}
vrrp_sync_group Group1 {
    group {
        FloatIP1
    }
}
vrrp_instance FloatIP1 {
    interface bridge
    virtual_router_id 10
    priority 100
    advert_int 1
    virtual_ipaddress {
        198.51.100.10
    }
}

Load-balancing

Teď je ovšem problém, že v optimálním stavu, kdy fungují oba servery, je veškerá komunikace směrovaná na 198.51.100.10 obsluhována pouze jedním serverem. I na toto ale existuje lék, pokud si vzpomeneme na naše hrátky s DNS. V keepalived konfiguraci vyrobíme ještě jednu synchronizační skupinu a druhou instanci pro adresu 198.51.100.20, kde budou priority obráceně:

# server1: /etc/keepalived/keepalived.conf
vrrp_instance FloatIP2 {
    interface bridge
    virtual_router_id 20
    priority 100
    advert_int 1
    virtual_ipaddress {
        198.51.100.20
    }
}
# server2: /etc/keepalived/keepalived.conf
vrrp_instance FloatIP2 {
    interface bridge
    virtual_router_id 20
    priority 150
    advert_int 1
    virtual_ipaddress {
        198.51.100.20
    }
}

Po restartu služby keepalived by se na každém serveru měla objevit jedna z virtuálních adres. Při výpadku jednoho ze serverů se pak na druhém objeví adresy obě. Když server opět ožije, tu „svoji adresu“ si opět převezme. Obě dvě virtuální adresy nyní můžeme umístit do DNS, jako tomu bylo na začátku. Nyní máme k dispozici dvě adresy, které v optimálním případě míří na různé servery, v případě výpadku jsou obě nasměrovány na zdravý server.

server.example.net  IN  A       198.51.100.10
server.example.net  IN  A       198.51.100.20

server1.example.net IN  A       198.51.100.101
server1.example.net IN  A       198.51.100.102

www.example.net     IN  CNAME   server.example.net.

Pro dnešek je to vše. V příštím díle se podíváme na to, jak pomocí HAProxy udělat load-balancing a failover na úrovni aplikační, což masivně využijeme pro hladký provoz webových aplikací.

Našli jste v článku chybu?