Quando siamo in presenza di installazioni medio-grandi, è possibile distribuire il carico di lavoro sui VMware View Connection Server aggiungendone di ulteriori grazie al ruolo “Replica”. Tuttavia, il bilanciamento o il failover tra di essi non è direttamente disponibile nel software. Per distribuire i client View tra i vari server, è necessario utilizzare un bilanciatore esterno.
VMware ha il suo modo di realizzare il bilanciamento, utilizzando le funzioni di balancing di VCNS (VMware vCloud Networking & Security, precedentemente noto come vShield Edge). Tuttavia, mi sono sempre trovato più a mio agio con HAProxy. Questo programma usa una quantità minima di memoria, e possiede funzioni interessantissimi come SSL offloading, differenti algoritmi di bilanciamento e altro ancora.
HAProxy può essere eseguito su una singola macchina linux, per bilanciare differenti server alle sue spalle, ma per configurazioni in alta disponibilità ovviamente è necessario utilizzare almeno 2 nodi, con un indirizzo IP virtuale che verrà gestito da un altro grande programma, Keepalived. Per le mie installazioni, uso solitamente CentOS 6, quindi questo tutorial sarà basato su questa distribuzione linux. La rete d’esempio prevede queste macchine e indirizzi IP:
hostname | IP Address | Note |
lb1.domain.local | 192.168.1.162 | Load Balancer 1, master |
lb2.domain.local | 192.168.1.163 | Load Balancer 2, slave |
view.domain.local | 192.168.1.170 | Virtual IP gestito dai balancers |
view01.domain.local | 192.168.1.165 | View Connection Server |
view02.domain.local | 192.168.1.166 | View Connection Server (Replica) |
HAProxy può operare sia con 1 o più connessioni di rete, in questo esempio tutti i server saranno connessi alla stessa rete.
Per prima cosa, dobbiamo attivare il repository Extra Packages for Enterprise Linux (EPEL), che contiene i pacchetti per HAProxy e Keepalived. Installiamo le info su EPEL in YUM:
#rpm -ivh http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-5.noarch.rpm
e installiamo HAproxy e Keepalived:
#yum -y install haproxy keepalived
Editiamo la configurazione di Keepalived in modo che assomigli alla seguente:
#vi /etc/keepalived/keepalived.conf
global_defs { notification_email { keepalived } notification_email_from keepalived@domain.local smtp_server 192.168.1.200 smtp_connect_timeout 30 router_id 192.168.1.170 } vrrp_script chk_haproxy { script "killall -0 haproxy" interval 1 # check every second weight 2 # add 2 points of prio if OK } vrrp_instance VI_1 { interface eth0 state MASTER smtp_alert virtual_router_id 51 priority 101 # 101 on master, 100 on slaves advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.1.170 } track_script { chk_haproxy } }
Una rapida spiegazione dei parametri principali che vedete qui:
- Keepalived utilizza VRRP per gestire l’indirizzo IP virtuali condiviso dai balancers. VRRP è un sistema attivo/passivo, quindi in un dato momento il virtual IP è in ascolto su un solo balancer. Questo rende l’uso di Keepalived più “network friendly”, evitando configurazioni dedicate su switches o routers
- la configurazione vera e propria di VRRP è contenuta in uno script di controllo che verifica lo stato di HAProxy; questo è vitale per avere una configurazione funzionante. Non c’è utilità infatti nell’avere il virtual IP in ascolto su un balancer dove per qualche motivo HAProxy è morto. Quindi, se il controllo di HAProxy dovesse fallire, lo script sposterà il virtual IP all’altro balancer, dove HAProxy è in esecuzione.
- La priorità sarà impostata a 101 sul nodo master, e 100 su tutti gli slaves. Ricordatevi di cambiare questo parametro quando copiate la configurazione sui nodi slaves.
- Per proteggere la comunicazione tra i nodi, è meglio utilizzare una password. Questa chiave pre-condivisa dovrà essere impostata uguale su tutti i balancers.
net.ipv4.ip_nonlocal_bind = 1
e applicate il nuovo parametro eseguendo:
#sysctl -p
Dobbiamo poi aggiungere delle configurazioni su iptables, abilitando in particolare il supporto per il multicast broadcast:
#iptables -I INPUT -d 224.0.0.0/8 -j ACCEPT
Quindi, una regola per il protocollo VRRP:
#iptables -I INPUT -p 112 -j ACCEPT
In aggiunta, aggiungeremo le regole corrispondenti per il traffico che vogliamo bilanciare. Per View ho inserito HTTP e HTTPS (tecnicamente è necessario solo https, ma creeremo una regola in HAProxy per redirigere le chiamate http verso https):
#iptables -I INPUT -p tcp --dport 80 -j ACCEPT #iptables -I INPUT -p tcp --dport 443 -j ACCEPT
finalmente, possiamo salvare la configurazione di iptables in modo che venga riapplicata ad ogniriavvio, e avviamo Keepalived:
#service iptables save #service keepalived start
Una volta configurati tutti i balancers, possiamo vedere il virtual IP in ascolto sul nodo master:
#ip addr sh eth0 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000 link/ether 00:50:56:b8:7b:8a brd ff:ff:ff:ff:ff:ff inet 192.168.1.162/24 brd 192.168.1.255 scope global eth0 inet 192.168.1.170/32 scope global eth0 inet6 fe80::250:56ff:feb8:7b8a/64 scope link valid_lft forever preferred_lft forever
Se eseguiamo lo stesso comando su un nodo slave, vedremo solo l’IP fisico di quel nodo. Potete testare facilmente il virtual IP: iniziate a pingarlo, e arrestate il servizio keepalived sul nodo master. Potreste vedere un ping perso (a seconda della velocità dell’infrastruttura di rete sottostante), dopodichè le risposte ai ping ricominceranno ad arrivare dal nodo slave. Una volta riavviato il master, questo riprenderà il controllo del virtual IP.
Bene! Passiamo ora alla configurazione di HAProxy:
#vi /etc/haproxy/haproxy.cfg
#--------------------------------------------------------------------- # Global settings #--------------------------------------------------------------------- global log 127.0.0.1 local2 chroot /var/lib/haproxy pidfile /var/run/haproxy.pid maxconn 4000 user haproxy group haproxy daemon stats socket /var/lib/haproxy/stats #--------------------------------------------------------------------- # common defaults that all the 'listen' and 'backend' sections will # use if not designated in their block #--------------------------------------------------------------------- defaults mode http log global option httplog option dontlognull option http-server-close option forwardfor except 127.0.0.0/8 option redispatch retries 3 timeout http-request 10s timeout queue 1m timeout connect 10s timeout client 1m timeout server 1m timeout http-keep-alive 10s timeout check 10s maxconn 3000 #--------------------------------------------------------------------- # Redirect to secured #--------------------------------------------------------------------- frontend unsecured bind 192.168.1.170:80 redirect location https://view.domain.local #--------------------------------------------------------------------- # frontend secured #--------------------------------------------------------------------- frontend secured bind 192.168.1.170:443 #ssl crt ./haproxy-cert.pem mode tcp default_backend view #--------------------------------------------------------------------- # balancing between the various backends #--------------------------------------------------------------------- backend view mode tcp balance source server view01 192.168.1.165:443 weight 1 check port 443 inter 2000 rise 2 fall 5 server view02 192.168.1.166:443 weight 1 check port 443 inter 2000 rise 2 fall 5
Guardiamo in dettaglio le ultime tre sezioni, dato che la parte precedente sono configurazioni generali:
- “frontend unsecured” è un semplice redirect, intercetta ogni tentativo di connessione su porta 80 (http) e la redirige su porta 443 (https). In questo modo anche gli utenti svogliati che dimenticano di scrivere https nell’url avranno una connessione corretta invece di un errore 404.
- “frontend secured” è il vero frontend. E’ in ascolto sul virtual IP, sulla porta 443. Se voleste utilizzare un certificato SSL per l’hostname “view.domain.local”, potete utilizzare OpenSSL per creare una certificate request, e una volta ottenuto il certificato sotto forma di file PEM, salvarlo su entrambi i balancers e togliere il commento per abilitarne l’uso
- backend “view” contiene le configurazioni dei server bilanciati. Il metodo di bilanciamento è “source”: ogni IP sorgente verrà sempre indirizzato verso lo stesso Connection Server fintanto che quello stesso Connection Server sarà attivo (il parametro “check port 443” è usato proprio per verificare che View sia in ascolto). Source è una buona configurazione se si hanno connessioni provenienti da numerosi indirizzi IP, come nel caso dei client View. Fate attenzione se le connessioni dovessero essere instradate da sistemi come NAT o simili, perchè ridurrebbero di molto il numero di IP sorgenti rendendo “source” molto meno efficace.
Una volta che tutto è configurato, rendiamo l’avvio di HAProxy e Keepalived automatico, e avviamo HAProxy:
# chkconfig haproxy on # chkconfig keepalived on # service haproxy start
Saremo in grado adesso di connetterci a https://view.domain.local e vedere uno dei View Connection servers.