Load balancery, proxy servery, high availability

Ján Václav, xvaclav@fi.muni.cz

Proxy servery

Motivácia

Je niekoľko možných dôvodov, prečo by sme mohli chcieť ako administrátor siete poskytovať proxy server:

HTTP proxy

Ak posielame nešifrovanú požiadavku cez proxy, vyzerá rovnako ako GET request, okrem toho že miesto cesty je poskytnutá plná URL:

    GET http://proto17.pv090.fi.muni.cz/demo.txt HTTP/1.1
    Proxy-Authorization: Basic cHYwOTA6amV6ZWs=
    Accept: text/html
        

Proxy-Authorization hlavička má rovnakú štruktúru ako Authorization hlavička, s ktorou ste sa mohli stretnúť pri konfigurácii HTTP serveru (väčšinou v móde Basic obsahuje užívateľské meno a heslo oddelené dvojbodkou, zakódované pomocou Base64).

HTTP proxy servery väčšinou poskytujú aj pripojenie pomocou metódy CONNECT, ktorá vám dovolí pripojiť sa na ľubovoľný port a prenášať dáta po TCP. Táto metóda je u proxy serverov často obmedzená na port 443 z dôvodu zneužívania (napr. spam cez SMTP). Požiadavka potom môže vyzerať takto:

    CONNECT proto17-beta.pv090.fi.muni.cz:22 HTTP/1.1
    Proxy-Authorization: cHYwOTA6amV6ZWs=
        
Server následne odpovie HTTP kódom, pri úspechu ako obvykle bude kód 200. Následne sa HTTP spojenie chová ako tunel medzi klientom a daným vyžiadaným serverom - server na opačnom konci nemusí byť nutne HTTP, proxy môže byť použité aj na nadviazanie spojenia napr. na SSH server.

Squid

SOCKS proxy

SOCKS protokol funguje podobne ako horeuvedený HTTP CONNECT, kde je špecifikovaná adresa serveru a port, na ktorý sa má proxy server pripojiť. Vo verzii SOCKS4 protokolu vyzerá hlavička na nadviazanie spojenia takto:

VER CMD DSTPORT DSTIP ID
Počet bajtov 1 1 2 4 ľubovoľný
Význam Verzia protokolu Príkaz Port IPv4 adresa Identifikátor užívateľa ukončený nulou

kde príkaz CMD je buď 0x01 - nadviazanie TCP spojenia, alebo 0x02 - port binding - použiteľné napr. pri vytvorení spätného dátového FTP spojenia.

Prevzaté z EN Wikipédie - SOCKS (lit.)

Protokol má ďaľšie verzie, kde každá z nich priniesla novú funkcionalitu:

Dokážeme vytvoriť lokálny SOCKS5 server, ktorý bude tunelovať dáta cez ľubovoľný server, ktorý má SSH, a nemá explicitne zakázané vytváranie tunelov (AllowTcpForwarding No v sshd_config). Docielime toho pomocou príkazu ssh -D <port> user@server, kde port je port, na ktorom bude SOCKS5 server lokálne počúvať.

High availability

Motivácia

Môžeme siahnuť po viacserverovej konfigurácii miesto jedného centrálneho servera z rôznych dôvodov:

Corosync

Corosync je systém na skupinovú komunikáciu medzi uzlami v sieti. Na väčšine distribúcii je dostupný ako balík corosync. Pre komunikáciu používa UDP na portoch 5404 až 5406. Samotný Corosync sa stará len o členstvo v klastri, odovzdávanie správ a kvórum. Čo sa stane pri zmenách v klastri, je na manažérovi klastrových prostriedkov. V praxi sa väčšinou používa jeden z dvoch manažerov - Pacemaker alebo rgmanager.

Corosync používa tzv. "totem" protokol na kontrolu dostupnosti uzlov. Token sa odovzdá niektorému uzlu, ktorý vykoná nejakú prácu a potom ho odovzdá ďalšiemu uzlu. Toto ide stále dookola, a ak niektorý uzol nepredá svoj token ďalšiemu, token sa vyhlási za stratený, zvýši sa počet chýb a odošle sa nový token. Ak sa stratí príliš veľa tokenov za sebou, uzol sa vyhlási za mŕtvy.

Keď je uzol vyhlásený za mŕtvy, zostávajúce uzly vytvoria nový klaster. Ak zostane dostatok uzlov na vytvorenie kvóra, nový klaster bude naďalej poskytovať služby. V dvojuzlových klastroch je kvórum zakázané, takže každý uzol môže pracovať samostatne.

Prevzaté z "Alteeve: Corosync"

Ak by sa klaster rozdelil na dve alebo viac podskupín ktoré nedokážu navzájom komunikovať, používa sa tzv. kvórum na určenie, či existuje skupina uzlov, ktorá môže naďalej vykonávať požiadvky, a ak áno, ktorá to je. Klaster má kvórum, ak platí, že viac než polovica zo všetkých strojov je aktívna a odpovedá na dotazy.

Ak ani jedna skupina nespĺňa túto požiadavku, predvoleným správaním Pacemakeru v takom prípade je zastaviť všetky zdroje, aby sa zabránilo poškodeniu dát.

Prevzaté z "Pacemaker: Perform a Failover"

Ukážka konfigurácie

Konfigurácia sa väčšinou nachádza v súbore /etc/corosync/corosync.conf.

    totem {
        version: 2
        cluster_name: debian

        # You probably want to configure these
        # ↓ if in a production environent
        crypto_cipher: none
        crypto_hash: none
    }
    
    quorum {
        provider: corosync_votequorum
        # If we happen to only have two servers,
        # we need to set the following option, otherwise
        # corosync will never reach quorum:
        # two_node: 1
    }
    
    nodelist {
        node {
            nodeid: 1
            ring0_addr: 172.26.7.59
            # We can add a ring1..N_addr here if we have
            # a secondary link between servers we want
            # to use.
        }
    
        node {
            nodeid: 2
            ring0_addr: 172.26.7.4
        }
    
        node {
            nodeid: 3
            ring0_addr: 172.26.7.58
        }
    }
            
Prevzaté z východzej konfigurácie na Debiane

Pacemaker

Pacemaker je softvér určený na správu počítačových klastrov. Podporuje napr. detekciu výpadkov na úrovni stroja alebo aplikácie. Na komunikáciu medzi strojmi v klastri stavia nad softvérom Corosync. Pre inštaláciu oboch je na väčšine distribúcii dostupný balíček pacemaker, ktorý má závislosť na balíčku corosync.

Hodí sa tiež nainštalovať crm, čo je CLI rozhranie pre konfiguráciu Pacemakeru -- dostupné ako balíček crmsh. Pre kontrolu stavu klastru môžeme potom použiť príkaz crm status

Zdroje

Zdroj (angl. resource) je služba pod správou Pacemakeru. Zdroj môže byť primitívny (základný typ), skupina alebo klon; pre zjednodušenie budeme používať iba primitívne zdroje.

Každý zdroj má agenta, ktorý poskytuje Pacemakeru štandardizované rozhranie pre správu danej služby. Jeden z typ zdrojov, ktorý môžeme vytvoriť, je zdieľaná IP adresa:
crm configure primitive            \
    cluster_ip                     \ # názov zdroja
    ocf:heartbeat:IPaddr2          \ # agent (Open Cluster Framework)
    params                         \
    ip=10.42.42.42 cidr_netmask=24 \ # adresa a maska
    op monitor interval=30s          # konfigurácia health checku
            
Následne môžeme pridať aj službu, napr. HAProxy:
crm configure primitive   \
    haproxy               \
    ocf:heartbeat:haproxy \
    params                \
    op monitor interval=15s
            
Ak chceme odstrániť zdroj, musíme ho najskôr zastaviť: crm resource stop cluster_ip, a až potom ho môžeme odstrániť: crm configure delete cluster_ip

Load balancery

IPVS - IP Virtual Server

IP Virtual Server je load balancer pracujúci na štvrtej vrstve (podpora pre TCP, UDP a SCTP), ktorý je súčasťou Linuxového jadra. Ak ho chceme používať, musíme sa uistiť, že je zakompilovaný do jadra alebo dostupný ako modul - možnosť CONFIG_IP_VS v konfigurácii.
Následne ho môžeme konfigurovať pomocou príkazu ipvsadm(8).

Konfigurácia

Najprv musíme vytvoriť virtuálnu službu pomocou prepínača -A, a následne môžeme pridávať tejto službe rôzne servery pomocou prepínača -a. Službe môžeme stanoviť, akou metódou má distribuovať požiadavky. Pár metód schedulingu, ktoré stoja za zmienku: Ukážka:
# Pre load balancing použijeme metódu round-robin, a budeme počúvať na porte 9000.
ipvsadm -A -t localhost:9000 -s rr

# Majme servery na portoch localhost:8081-8083. Pridáme ich do balancing poolu.
ipvsadm -a -t localhost:9000 -r localhost:8081 -m
ipvsadm -a -t localhost:9000 -r localhost:8082 -m
ipvsadm -a -t localhost:9000 -r localhost:8083 -m

# Ak chceme po nejakom čase daný balancer zrušiť, použijeme prepínač -D
ipvsadm -D -t localhost:9000

nginx

nginx je pôvodne určený ako webserver, ale dokáže tiež slúžiť ako reverzné proxy, resp. load balancer pre HTTP, TCP aj UDP aplikácie. Výhodou nginxu oproti Apache alebo HAProxy v tomto ohľade je, že môžeme používať jeden softvéru na hosting bežných stránok a zároveň ho používať ako reverzné proxy na rovnakom porte 80/443.
Ukážka, ako môžeme nakonfigurovať nginx ako load balancer webovej služby podobnej ako z IPVS ukážky:

user www-data;
error_log /var/log/nginx/error.log info;

events {
    worker_connections 768;
}

http {
    upstream backend {
        least_conn;
        server localhost:8081 max_fails=3 fail_timeout=30s;
        server localhost:8082 max_fails=3 fail_timeout=30s;
        server localhost:8083 max_fails=3 fail_timeout=30s;
    }

    server {
        listen 9000;
        server_name _;
        
        location / {
            proxy_pass http://backend;
        }
    }
}

upstream v nginx-e má niekoľko rôznych možných stratégii, podobne ako IPVS a HAProxy:

Load balancer môžeme nakonfigurovať aj tak, aby nahliadal na daný upstream iba ako generickú TCP službu pomocou bloku stream:

user www-data;
error_log /var/log/nginx/error.log info;

events {
    worker_connections 768;
}

stream {
    upstream backend {
        server localhost:8081;
        server localhost:8082;
        server localhost:8083;
    }

    server {
        listen 80;
        proxy_connect_timeout 1s;
        proxy_timeout 3s;
        proxy_pass backend;
    }

    # Ukážka UDP load balanceru - DNS
    upstream dns_servers {
        server 10.0.0.1:53;
        server 10.0.0.2:53;
        server 10.0.0.3:53;
        server 10.0.0.4:53;
    }

    server {
        listen 53 udp;
        proxy_pass dns_servers;
    }
}
            
Čiastočne prevzaté z "module ngx_stream_core_module"

HAProxy

HAProxy je load balancer/reverzný proxy server pre aplikácie založené na HTTP a TCP. Ukážka, ako môžeme nakonfigurovať HAProxy ako load balancer webovej služby podobnej ako z IPVS ukážky:

global
    log /dev/log	local0
    log /dev/log	local1 notice
    chroot /var/lib/haproxy
    stats socket /run/haproxy/admin.sock mode 660 level admin
    stats timeout 30s
    user haproxy
    group haproxy
    daemon

    # Default SSL material locations
    ca-base /etc/ssl/certs
    crt-base /etc/ssl/private

defaults
    log	global
    mode	http
    option	httplog
    option	dontlognull
    timeout connect 5000
    timeout client  50000
    timeout server  50000
    errorfile 400 /etc/haproxy/errors/400.http
    errorfile 403 /etc/haproxy/errors/403.http
    errorfile 500 /etc/haproxy/errors/500.http
    errorfile 502 /etc/haproxy/errors/502.http

frontend http
    bind :::9100 v4v6
    default_backend web_backend

frontend https
    bind :::4433 v4v6 ssl crt /etc/ssl/certs/proto17-fullchain.crt
    default_backend web_backend

backend web_backend
    mode http
    balance roundrobin

    server be1 127.0.0.1:8081 check
    server be2 127.0.0.1:8082 check
    server be3 127.0.0.1:8083 check
        
Čiastočne prevzaté z východzej konfigurácie na Debiane

Parameter check znamená, že HAProxy bude aktíve kontrolovať dostupnosť daný server. Ak niekoľkokrát za sebou server nedokáže odpovedať, odstráni ho z load balanceru, ale bude naďalej vykonávať kontroly - ak znovu začne odpovedať, pridá ho späť do balanceru.

Pomocou direktívy balance môžeme nastaviť chovanie load balanceru pri priraďovaní požiadaviek konkrétnym serverom. Pár možností, ktoré HAProxy poskytuje:

Literatúra