HAProxy ile Yüksek Erişilebilirlik: Keepalived ve Health Check
Modern mikroservis mimarilerinde veya yüksek trafikli web uygulamalarında kesintisiz hizmet sunmak artık bir lüks değil, zorunluluk. Tam da bu noktada, haproxy ve keepalived ikilisi, linux sunucularınız üzerinde kurabileceğiniz, kurumsal sınıfta, maliyetsiz ve son derece güvenilir bir aktif-pasif ha (high availability) loadbalancer çözümü olarak imdadımıza yetişiyor. Peki ama bu iki canavarı prod ortamında birbirine küstürmeden, arkadaki servislerin sağlık durumlarına (health check) ve gelen isteğin içeriğine (ACL) göre nasıl kusursuzca dans ettireceğiz? Bu yazıda lafı hiç dolandırmadan, doğrudan production ortamında hırpalanmış senaryolardan süzülen pratik bir mimariyi ayağa kaldıracağız.
Neden Sadece HAProxy Yetmiyor? (SPOF Nedir?)
HAProxy, performansına ve stabilitesine şapka çıkardığımız harika bir load balancer. Ancak ne kadar güçlü olursa olsun, tek bir sunucu üzerinde çalıştığı sürece sisteminizde bir SPOF (Single Point of Failure) yani tek hata noktası oluşturur. HAProxy’nin üzerinde çalıştığı Linux sunucunun donanımı çökerse, network kartı yanarsa ya da kernel panik yaparsa tüm sisteminiz karanlığa gömülür.
İşte bu riski bertaraf etmek için Keepalived devreye giriyor. Keepalived, VRRP (Virtual Router Redundancy Protocol) protokolünü kullanarak iki farklı load balancer sunucusunun tek bir Sanal IP (Virtual IP – VIP) arkasında çalışmasını sağlar. Aktif olan sunucu çöktüğünde, pasif durumdaki yedek sunucu VIP’yi milisaniyeler içinde üzerine alır. Kullanıcılar bu failover sürecini ruhları bile duymadan atlatırlar.
Altyapı Hazırlığı ve Olmazsa Olmaz Kernel Parametresi
Kuruluma başlamadan önce topolojimizi netleştirelim. Elimizde iki adet Linux (Ubuntu/Debian tabanlı kabul ediyoruz) sunucu olduğunu varsayalım:
- LB01 (Master): 192.168.1.10
- LB02 (Backup): 192.168.1.11
- Sanal IP (VIP): 192.168.1.100
Şimdi kıdemli bir sistemcinin asla atlamayacağı o kritik kernel ayarına gelelim: net.ipv4.ip_nonlocal_bind. Varsayılan olarak Linux, sunucu üzerinde fiziksel olarak tanımlanmamış bir IP adresine servislerin bind olmasını (yani o IP’yi dinlemesini) engeller. VIP, pasif sunucuda o an aktif olmadığı için backup sunucudaki HAProxy servisi başlatılamaz ve çöker. Bunun önüne geçmek için her iki sunucuda da şu komutu koşturuyoruz:
echo "net.ipv4.ip_nonlocal_bind=1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
Bu sihirli dokunuş sayesinde HAProxy, sunucuda henüz tanımlanmamış olan 192.168.1.100 IP’sini hiç çekinmeden dinlemeye başlayacaktır.
Keepalived ile Aktif-Pasif VIP Kurulumu
Her iki sunucuya da keepalived paketini kuralım:
sudo apt update && sudo apt install keepalived -y
Şimdi konfigürasyon zamanı. En kritik nokta, master sunucu çöktüğünde VIP’nin pasif sunucuya geçmesi, ancak master geri geldiğinde (eğer istemiyorsak) gereksiz yere VIP’yi geri alıp ufak da olsa bir kesinti yaratmamasıdır. Buna “non-preemptive” yapılandırma denir. Ancak biz bu örnekte klasik aktif-pasif öncelik yapısını kuracağız.
Master (LB01) Konfigürasyonu
/etc/keepalived/keepalived.conf dosyasını oluşturun ve aşağıdaki gibi düzenleyin:
vrrp_script check_haproxy {
script "killall -0 haproxy" # HAProxy çalışıyor mu kontrol et
interval 2 # Her 2 saniyede bir çalıştır
weight 2 # Başarılıysa önceliğe (priority) 2 ekle
}
vrrp_instance VI_1 {
state MASTER
interface eth0 # Network arayüzünüzün adı (ip a ile kontrol edin)
virtual_router_id 51 # İki sunucuda da AYNI olmalı
priority 101 # Master daha yüksek önceliğe sahip
advert_int 1
authentication {
auth_type PASS
auth_pass GizliSifre123 # İki sunucuda da aynı olmalı
}
virtual_ipaddress {
192.168.1.100/24 # Paylaşılan Sanal IP (VIP)
}
track_script {
check_haproxy
}
}
Backup (LB02) Konfigürasyonu
Backup sunucumuzda ise dosya neredeyse aynıdır, sadece state ve priority değerleri değişir:
vrrp_script check_haproxy {
script "killall -0 haproxy"
interval 2
weight 2
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 100 # Master'dan daha düşük
advert_int 1
authentication {
auth_type PASS
auth_pass GizliSifre123
}
virtual_ipaddress {
192.168.1.100/24
}
track_script {
check_haproxy
}
}
Konfigürasyonları kaydettikten sonra her iki sunucuda da servisi başlatalım:
sudo systemctl enable --now keepalived
Eğer her şey yolunda gittiyse, LB01 üzerinde ip a show eth0 komutunu verdiğinizde secondary IP olarak 192.168.1.100 adresini görmelisiniz. LB02’de ise bu IP görünmemelidir.
HAProxy Kurulumu ve Sağlık Kontrolü (Health Check) Sanatı
Sıra geldi yük dengeleme katmanımıza. HAProxy’yi kuralım:
sudo apt install haproxy -y
Bir load balancer’ı akıllı kılan şey, arkasındaki uygulama sunucularının (backend) gerçekten yaşayıp yaşamadığını bilmesidir. Sadece TCP portunun açık olması (Layer 4) uygulamanın sağlıklı çalıştığı anlamına gelmez. Uygulama veritabanına bağlanamadığı için HTTP 500 hatası veriyor olabilir ama TCP portu hala ayaktadır. Bu yüzden her zaman HTTP tabanlı (Layer 7) health check tercih etmelisiniz.
Gelin, hem gelişmiş health check mekanizmasını hem de VIP binding konseptini barındıran örnek bir /etc/haproxy/haproxy.cfg dosyası hazırlayalım:
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
user haproxy
group haproxy
daemon
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
frontend http_front
bind 192.168.1.100:80 # Sadece VIP üzerinden gelen istekleri dinle
mode http
default_backend app_backend
backend app_backend
mode http
balance roundrobin
# Layer 7 Health Check Yapılandırması
option httpchk GET /healthz HTTP/1.1\r\nHost:\ myapp.local
http-check expect status 200
# Backend Sunucuları
server app01 192.168.1.20:8080 check inter 3000 rise 2 fall 3
server app02 192.168.1.21:8080 check inter 3000 rise 2 fall 3
Burada Neler Döndü? (Detaylı “Neden” Analizi)
bind 192.168.1.100:80: HAProxy’ye sadece VIP adresini dinlemesini söyledik. Bu, trafiğin kontrolsüz şekilde doğrudan nodeların kendi IP’leri üzerinden akmasını engeller.option httpchk GET /healthz: HAProxy, backend sunucularına her 3 saniyede bir (inter 3000) HTTP GET isteği gönderir.http-check expect status 200: Gelen yanıtın HTTP 200 OK olması durumunda sunucu “sağlıklı” kabul edilir.rise 2 fall 3: Bir sunucu ardışık 3 kez başarısız health check yanıtı verirse (fall), trafik ona gönderilmez (out of rotation). Ne zaman ki ardışık 2 başarılı yanıt verir (rise), o zaman tekrar gruba dahil edilir.
Gelişmiş ACL (Access Control List) Tabanlı Routing
Prod ortamlarında genellikle tek bir domain arkasında birden fazla mikroservis barındırırız. Örneğin /api ile başlayan isteklerin API servislerine, statik dosyaların ise başka bir backende gitmesini isteriz. HAProxy’nin ACL mekanizması bu konuda tam bir canavardır.
Aşağıdaki konfigürasyon örneğinde, path ve domain bazlı yönlendirmeyi nasıl yapacağımızı görelim:
frontend http_front_advanced
bind 192.168.1.100:80
mode http
# ACL Tanımları
acl is_api path_beg -i /api
acl is_static path_end -i .jpg .png .css .js
acl host_admin hdr_beg(host) -i admin.
# Yönlendirme Kuralları (Routing Rules)
use_backend api_backend if is_api
use_backend static_backend if is_static
use_backend admin_backend if host_admin
# Varsayılan Backend
default_backend web_backend
backend web_backend
server web01 192.168.1.30:80 check
backend api_backend
server api01 192.168.1.40:8080 check
backend static_backend
server storage01 192.168.1.50:80 check
backend admin_backend
server admin01 192.168.1.60:80 check
Bu yapıyla birlikte, tek bir load balancer IP’si üzerinden gelen istekleri, url path’ine veya HTTP host header’ına göre ayıklayıp tamamen farklı sunucu gruplarına sıfır performans kaybıyla dağıtabiliyoruz.
Failover Testi: Fişi Çektiğimizde Ne Oluyor?
Kurulumumuzu tamamladık ve servislerimizi başlattık (sudo systemctl enable --now haproxy). Peki sistemimiz gerçekten yüksek erişilebilir mi? Bunu test etmenin en vahşi (ve keyifli) yolu canlı ortamda simülasyon yapmaktır.
Öncelikle master sunucumuzda (LB01) IP adresini izleyelim:
ip addr show eth0
Burada 192.168.1.100 IP’sini görmeliyiz. Şimdi master sunucu üzerinde HAProxy servisini durdurarak Keepalived’ın bu durumu fark etmesini sağlayalım:
sudo systemctl stop haproxy
Hemen ardından pasif sunucuya (LB02) geçip logları izleyelim:
tail -f /var/log/syslog | grep Keepalived
Loglarda şuna benzer bir satır görmelisiniz:
Keepalived_vrrp[1234]: VRRP_Instance(VI_1) Entering MASTER STATE
Ve ip addr show eth0 çalıştırdığınızda, VIP’nin saniyeden daha kısa bir sürede LB02’ye göç ettiğini göreceksiniz. Kullanıcılarınız, veritabanına veri yazmaya ve web sitenizde gezinmeye kesintisiz olarak devam edecektir. İşte gerçek HA kalitesi!
Sonuç ve Pro-Tip
HAProxy ve Keepalived ikilisi, karmaşık cloud mimarilerine veya pahalı donanımsal load balancer cihazlarına ihtiyaç duymadan, Linux’un gücüyle scale olabilen harika bir çözümdür.
Son bir prod tavsiyesi: Keepalived loglarını mutlaka merkezi bir izleme aracına (Elasticsearch, Loki vb.) yönlendirin ve VIP geçişlerinde (state transitions) ekibinize Slack veya Teams üzerinden alert atacak bir script tetikleyin (bunun için Keepalived’ın notify_master ve notify_backup direktiflerini araştırabilirsiniz). VIP’nin sessiz sedasız sürekli yer değiştirmesi, altyapınızda sinsi bir network dalgalanması olduğunun habercisi olabilir.