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.
