HAProxy load balancer konfigūravimas

Kas yra HAProxy ir kodėl jis toks populiarus

HAProxy – tai vienas iš patikimiausių ir greičiausių load balancer sprendimų, kuris jau daugiau nei dvidešimt metų padeda IT specialistams valdyti serverių apkrovas. Šis atvirojo kodo įrankis tapo standartu daugelyje organizacijų, nuo mažų startuolių iki milžiniškų korporacijų kaip Reddit, GitHub ar Stack Overflow.

Pagrindinis HAProxy privalumas – tai neįtikėtinas našumas. Jis gali apdoroti dešimtis tūkstančių užklausų per sekundę net ir vidutinės galios serveryje. Be to, HAProxy pasižymi stabilumu – kartą sukonfigūravus, jis tiesiog veikia, nepriklausomai nuo to, ar jūsų sistemą naudoja 100 ar 100,000 vartotojų.

Dar viena priežastis, kodėl HAProxy taip mėgstamas – jo lankstumas. Galite jį naudoti kaip paprastą HTTP load balancer, TCP proxy, SSL termination point ar net kaip sudėtingą traffic routing sistemą su įvairiomis taisyklėmis ir sąlygomis. Ir visa tai konfigūruojama viename teksto faile.

Pasiruošimas darbui ir bazinė įdiegtis

Prieš pradedant konfigūruoti HAProxy, reikia jį įdiegti. Daugumoje Linux distribucijų tai paprasta kaip du kartus du. Ubuntu ar Debian sistemose pakanka paleisti:

sudo apt-get update
sudo apt-get install haproxy

CentOS ar RHEL sistemose naudokite:

sudo yum install haproxy

Įdiegus HAProxy, pagrindinis konfigūracijos failas bus /etc/haproxy/haproxy.cfg. Prieš pradedant bet kokius pakeitimus, visada pasidarykite atsarginę kopiją:

sudo cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.backup

Tai gali atrodyti kaip akivaizdus patarimas, bet patikėkite – po kelių valandų konfigūravimo ir bandymų, kai kažkas nustoja veikti, ta atsarginė kopija bus jūsų gelbėjimo ratas.

Taip pat įsitikinkite, kad turite bent du backend serverius, tarp kurių galėsite paskirstyti apkrovą. Jei testuojate lokalioje aplinkoje, galite paleisti du paprastus web serverius skirtinguose portuose – pavyzdžiui, Apache 8080 porte ir Nginx 8081 porte.

Konfigūracijos failo struktūra ir pagrindiniai blokai

HAProxy konfigūracijos failas susideda iš kelių pagrindinių sekcijų, kiekviena atsakinga už skirtingus aspektus. Supratimas, kaip šios sekcijos tarpusavyje sąveikauja, yra raktas į sėkmingą konfigūraciją.

Global sekcija nustato bendrus parametrus, kurie taikomi visam HAProxy procesui. Čia apibrėžiami dalykai kaip maksimalus prisijungimų skaičius, log failų vietos, vartotojas ir grupė, kurios teisėmis veiks procesas:

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
maxconn 4000

Defaults sekcija nustato numatytuosius parametrus, kurie bus taikomi visiems frontend ir backend blokams, nebent juose bus nurodyti kiti nustatymai. Tai labai patogu, nes leidžia išvengti kodo dubliavimo:

defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000

Frontend sekcija apibrėžia, kaip HAProxy priims įeinančias užklausas. Čia nurodote, kokiame porte klausytis, kokius SSL sertifikatus naudoti ir kaip nukreipti srautą į backend:

frontend http_front
bind *:80
default_backend http_back

Backend sekcija apibrėžia serverius, į kuriuos bus siunčiamos užklausos, ir kaip bus paskirstoma apkrova:

backend http_back
balance roundrobin
server server1 192.168.1.10:80 check
server server2 192.168.1.11:80 check

Apkrovos paskirstymo algoritmai ir jų pasirinkimas

Vienas svarbiausių sprendimų konfigūruojant load balancer yra pasirinkti tinkamą apkrovos paskirstymo algoritmą. HAProxy siūlo keletą variantų, kiekvienas su savo privalumais ir trūkumais.

Round Robin – paprasčiausias ir dažniausiai naudojamas algoritmas. Užklausos paskirstomos cikliškai: pirma serveris gauna užklausą, tada antras, trečias, ir vėl grįžtama prie pirmo. Tai puikiai veikia, kai visi serveriai yra vienodos galios:

balance roundrobin

Least Connections – užklausos siunčiamos į serverį, kuris tuo metu turi mažiausiai aktyvių prisijungimų. Tai efektyviau nei round robin, kai užklausos užtrunka skirtingai:

balance leastconn

Source – užklausos iš to paties IP adreso visada nukreipiamos į tą patį serverį. Tai naudinga, kai reikia sesijos persistencijos:

balance source

URI – užklausos paskirstomos pagal URL. Tai reiškia, kad tos pačios URL užklausos visada pateks į tą patį serverį, kas puikiai tinka cache optimizavimui:

balance uri

Praktikoje dažniausiai naudojamas round robin arba leastconn. Jei turite stateless aplikaciją (kur sesijos informacija saugoma duomenų bazėje ar Redis), round robin bus paprasčiausias ir efektyviausias pasirinkimas. Jei užklausos gali užtrukti labai skirtingai, geriau rinktis leastconn.

Health checks ir serverių monitoringas

Viena iš svarbiausių load balancer funkcijų – automatiškai aptikti, kai backend serveris nustoja veikti, ir nustoti siųsti į jį užklausas. HAProxy turi puikias health checking galimybes.

Paprasčiausias būdas – pridėti check parametrą prie kiekvieno serverio apibrėžimo:

server web1 192.168.1.10:80 check
server web2 192.168.1.11:80 check

Tai nurodo HAProxy periodiškai tikrinti, ar serveris atsako. Bet galite būti daug konkretesni:

server web1 192.168.1.10:80 check inter 2000 rise 2 fall 3

Šie parametrai reiškia:
inter 2000 – tikrinti kas 2 sekundes
rise 2 – serveris laikomas veikiančiu po dviejų sėkmingų patikrinimų
fall 3 – serveris laikomas neveikiančiu po trijų nesėkmingų patikrinimų

Galite net apibrėžti specialias health check užklausas. Pavyzdžiui, jei turite specialų endpoint /health, kuris tikrina duomenų bazės prisijungimą ir kitas kritines sistemas:

option httpchk GET /health
http-check expect status 200

Taip HAProxy ne tik tikrins, ar serveris atsako, bet ir ar jūsų aplikacija tikrai veikia kaip reikiant. Tai gali išgelbėti situacijose, kai web serveris veikia, bet aplikacija užstrigusi ar duomenų bazė nepasiekiama.

SSL/TLS terminacija ir saugumo aspektai

Šiuolaikiniame internete SSL/TLS yra būtinybė, ne prabanga. HAProxy puikiai tvarko SSL termination – tai reiškia, kad HTTPS užklausos dešifruojamos HAProxy lygyje, o backend serveriams siunčiamos jau paprastos HTTP užklausos. Tai sumažina backend serverių apkrovą ir supaprastina sertifikatų valdymą.

Norint įjungti SSL, pirmiausia reikia turėti sertifikatą. Jei testuojate, galite susigeneruoti self-signed sertifikatą:

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/haproxy.key -out /etc/ssl/certs/haproxy.crt

Tada sujunkite sertifikatą ir raktą į vieną failą (HAProxy to reikalauja):

sudo cat /etc/ssl/certs/haproxy.crt /etc/ssl/private/haproxy.key > /etc/ssl/private/haproxy.pem

Dabar galite konfigūruoti frontend su SSL:

frontend https_front
bind *:443 ssl crt /etc/ssl/private/haproxy.pem
default_backend http_back

Saugumo požiūriu, rekomenduoju įjungti tik modernius SSL protokolus ir stiprius šifravimo algoritmus:

bind *:443 ssl crt /etc/ssl/private/haproxy.pem no-sslv3 no-tlsv10 no-tlsv11
ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384

Taip pat naudinga automatiškai peradresuoti HTTP srautą į HTTPS:

frontend http_front
bind *:80
redirect scheme https code 301 if !{ ssl_fc }

Pažangios konfigūracijos ir traffic routing

Kai įvaldote pagrindus, galite pradėti naudoti pažangesnes HAProxy funkcijas. Viena populiariausių – ACL (Access Control Lists), leidžiančios nukreipti srautą pagal įvairias sąlygas.

Pavyzdžiui, galite nukreipti užklausas į skirtingus backend serverius pagal URL kelią:

frontend http_front
bind *:80

acl is_api path_beg /api
acl is_static path_beg /static

use_backend api_servers if is_api
use_backend static_servers if is_static
default_backend web_servers

Arba pagal domeno vardą (naudinga, kai viename HAProxy aptarnaujate kelis projektus):

acl is_blog hdr(host) -i blog.example.com
acl is_shop hdr(host) -i shop.example.com

use_backend blog_servers if is_blog
use_backend shop_servers if is_shop

Galite net nukreipti tam tikrą procentą srauto į naują serverių versiją (canary deployment):

backend web_back
balance roundrobin

server web1 192.168.1.10:80 check weight 90
server web2_new 192.168.1.20:80 check weight 10

Čia 90% srauto eis į seną serverį, o 10% į naują. Jei viskas veikia gerai, galite palaipsniui didinti naujojo serverio weight reikšmę.

Dar viena naudinga funkcija – rate limiting. Galite apriboti užklausų skaičių iš vieno IP:

frontend http_front
bind *:80

stick-table type ip size 100k expire 30s store http_req_rate(10s)
http-request track-sc0 src
http-request deny if { sc_http_req_rate(0) gt 100 }

Tai leis ne daugiau kaip 100 užklausų per 10 sekundžių iš vieno IP adreso, kas padeda apsisaugoti nuo paprastų DDoS atakų.

Statistika, logai ir troubleshooting

HAProxy turi puikią statistikos sąsają, kuri leidžia realiu laiku stebėti, kas vyksta jūsų load balancer. Įjungti ją labai paprasta:

listen stats
bind *:8404
stats enable
stats uri /stats
stats refresh 30s
stats auth admin:slaptazodis

Dabar galite atidaryti naršyklėje http://jusu-serveris:8404/stats ir matysite gražią lentelę su visais frontend ir backend serveriais, jų būsenomis, užklausų skaičiais, atsakymo laikais ir kitais parametrais.

Logų konfigūravimas taip pat svarbus. Standartiškai HAProxy siunčia logus į syslog, bet galite nukreipti juos į atskirą failą. Ubuntu sistemoje redaguokite /etc/rsyslog.d/49-haproxy.conf:

$ModLoad imudp
$UDPServerRun 514
$UDPServerAddress 127.0.0.1

local0.* /var/log/haproxy.log

Perkraukite rsyslog:

sudo systemctl restart rsyslog

Kai kažkas nustoja veikti, pirmas dalykas – patikrinti konfigūracijos failą:

sudo haproxy -c -f /etc/haproxy/haproxy.cfg

Ši komanda patikrins sintaksę ir praneš apie klaidas. Jei viskas gerai, bet HAProxy vis tiek neveikia kaip tikitės, žiūrėkite logus:

sudo tail -f /var/log/haproxy.log

Dažniausios problemos: neteisingi backend serverių adresai, uždaryti portai, firewall taisyklės, blokuojančios srautą, arba backend serveriai, kurie neatlieka health check testų.

Kai viskas sueina į vieną vietą

HAProxy konfigūravimas iš pradžių gali atrodyti bauginantis, bet iš tikrųjų tai labai logiškas ir aiškus procesas. Pradėkite nuo paprasto round robin konfigūracijos su dviem serveriais, įsitikinkite, kad veikia, tada palaipsniui pridėkite SSL, health checks, pažangesnius routing rules.

Svarbiausias patarimas – testuokite kiekvieną pakeitimą atskirai. Nepridėkite dešimties naujų konfigūracijos eilučių iš karto. Pridėkite vieną ar dvi, perkraukite HAProxy, patikrinkite, ar veikia. Jei ne – lengviau suprasti, kas negerai.

Nepamirškite monitoringo. HAProxy statistikos puslapis turėtų būti vienas iš pirmųjų dalykų, į kuriuos žiūrite, kai kas nors negerai. Jis parodys, kurie serveriai veikia, kurie ne, kiek užklausų apdorojama, kiek klaidu įvyksta.

Ir galiausiai – dokumentuokite savo konfigūraciją. Pridėkite komentarus prie sudėtingesnių ACL taisyklių ar backend konfigūracijų. Po kelių mėnesių (ar net savaičių) būsite dėkingi sau už tuos komentarus, kai bandysite prisiminti, kodėl kažką konfigūravote būtent taip.

HAProxy – tai įrankis, kuris gali augti kartu su jūsų projektu. Pradedant nuo paprasto load balancing dviem serveriams, baigiant sudėtinga multi-datacenter architektūra su šimtais serverių. Ir gražiausia, kad pagrindinis konfigūracijos principas išlieka tas pats.

Daugiau

Qwik framework: resumability koncepcija