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-networkd: systemctl 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í.