Yük dengeleyici kurduğunda ilginç bir şey olur: uygulama katmanını tek hata noktası olmaktan çıkarırsın ama yerine yenisini koyarsın. Arkada üç sağlıklı uygulama sunucusu dursa bile, önlerindeki tek dengeleyici çöktüğünde hepsi birden erişilmez olur. Keepalived ve VRRP tam olarak bu son halkayı kapatmak için vardır: iki makine arasında paylaşılan bir sanal IP tanımlarsın, o IP her an yalnızca birinin üzerinde durur ve o makine düştüğünde saniyeler içinde diğerine geçer.
Bu rehberde iki düğümlü klasik bir failover kümesi kuracağız. Önce VRRP'nin nasıl çalıştığını, sonra keepalived.conf dosyasını satır satır, ardından yalnızca makinenin değil üzerindeki servisin de sağlığını izleyen vrrp_script mekanizmasını göreceğiz. Devretme anında ağda tam olarak ne olduğunu, split-brain (iki makinenin de kendini birincil sanması) durumunun neden oluştuğunu ve bulut ortamlarında multicast kapalıyken ne yapman gerektiğini de ele alacağız. Yük dengeleme katmanını henüz kurmadıysan önce yük dengeleyici nedir yazısına göz atmanı öneririm.
VRRP Nasıl Çalışır#
VRRP (Virtual Router Redundancy Protocol), aslen yönlendiriciler için tasarlanmış ama bugün her tür servis için kullanılan basit bir protokoldür. Mantığı şudur: aynı ağdaki birkaç makine bir "sanal yönlendirici" grubu oluşturur, bu grubun bir sanal IP adresi (VIP) ve bir sanal MAC adresi vardır. Grup içinde her an tek bir MASTER bulunur ve VIP o an MASTER olan makinenin arayüzüne bağlıdır. Diğerleri BACKUP durumunda bekler.
MASTER, ağa düzenli aralıklarla (varsayılan saniyede bir) VRRP duyuru paketi gönderir. BACKUP düğümler bu duyuruları dinler. Belirli bir süre — genellikle üç duyuru aralığı kadar — hiç duyuru gelmezse, BACKUP düğümler MASTER'ın öldüğüne karar verir ve aralarında en yüksek priority değerine sahip olan kendini MASTER ilan edip VIP'yi üstlenir. Tüm süreç saniyeler içinde biter.
Bilinmesi gereken iki teknik detay var. Birincisi, VRRP duyuruları IP protokol numarası 112 ile ve varsayılan olarak 224.0.0.18 multicast adresine gönderilir; güvenlik duvarın bunu engelliyorsa hiçbir şey çalışmaz. İkincisi, VRRP yalnızca aynı ağ segmentinde çalışır — iki makine farklı veri merkezlerinde ve aralarında L2 bağlantı yoksa VRRP bir işe yaramaz, o senaryoda DNS tabanlı ya da sağlayıcı API'si tabanlı bir devretme kurman gerekir.
| Kavram | Anlamı | Tipik değer |
|---|---|---|
virtual_router_id | Grup kimliği, aynı ağdaki her grup için benzersiz | 1-255 arası |
priority | Kim MASTER olur, yüksek olan kazanır | MASTER 100, BACKUP 90 |
advert_int | Duyuru aralığı (saniye) | 1 |
| VIP | Gruba ait, devreden IP adresi | 185.12.34.56 |
| Devretme süresi | Duyuru kesildikten sonra geçen süre | ~3 × advert_int |
Keepalived Kurulumu ve Temel Yapılandırma#
Kurulum tüm büyük dağıtımlarda tek komutluk bir iştir. İki makinede de aynı adımları uygulayacaksın; tek fark yapılandırma dosyasındaki birkaç satır olacak.
# Debian / Ubuntu
sudo apt update && sudo apt install -y keepalived
# RHEL / Rocky / AlmaLinux
sudo dnf install -y keepalived
# Servisi açılışta başlat
sudo systemctl enable keepalived
Örnek senaryomuzda iki düğüm var: lb1 gerçek IP 10.0.0.11, lb2 gerçek IP 10.0.0.12, paylaşılan sanal IP ise 10.0.0.10. Birincil düğümün /etc/keepalived/keepalived.conf dosyası şöyle:
# lb1 — birincil düğüm
global_defs {
router_id lb1
# Betikleri root yerine sınırlı bir kullanıcıyla çalıştır
script_user keepalived_script
enable_script_security
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 110
advert_int 1
authentication {
auth_type PASS
# DİKKAT: yalnızca ilk 8 karakter kullanılır
auth_pass G7kP2mQx
}
virtual_ipaddress {
10.0.0.10/24 dev eth0
}
}
İkincil düğümde yalnızca üç satır değişir:
# lb2 — yedek düğüm
global_defs {
router_id lb2
script_user keepalived_script
enable_script_security
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51 # AYNI olmalı
priority 100 # daha düşük
advert_int 1
authentication {
auth_type PASS
auth_pass G7kP2mQx # AYNI olmalı
}
virtual_ipaddress {
10.0.0.10/24 dev eth0
}
}
virtual_router_id ve auth_pass iki düğümde birebir aynı olmalıdır; farklıysa düğümler birbirini görmez ve ikisi de kendini MASTER sanar. auth_pass değerinin yalnızca ilk 8 karakteri dikkate alınır — ilk 8 karakteri aynı olan iki parola Keepalived için aynı paroladır. Aynı ağda birden fazla küme çalıştırıyorsan her birine farklı virtual_router_id ver.
Güvenlik duvarında VRRP trafiğine izin vermeyi unutma:
# firewalld
sudo firewall-cmd --permanent --add-protocol=vrrp
sudo firewall-cmd --reload
# ufw (her iki düğümde, karşı tarafın IP'si için)
sudo ufw allow from 10.0.0.12 proto vrrp
# nftables / iptables
sudo iptables -A INPUT -p 112 -s 10.0.0.0/24 -j ACCEPT
Servis Sağlığını İzlemek: vrrp_script ve track_script#
Buraya kadarki yapılandırma yalnızca makinenin hayatta olup olmadığını izler. Ama gerçek hayatta çok daha sık görülen senaryo şudur: makine ayakta, ağ bağlantısı sorunsuz, ama üzerindeki HAProxy ya da Nginx süreci çökmüş. Keepalived bu durumda hiçbir şey yapmaz — VIP çökmüş servisin durduğu makinede kalmaya devam eder ve site erişilmez olur.
Çözüm vrrp_script ile bir sağlık betiği tanımlayıp track_script ile onu VRRP örneğine bağlamaktır:
vrrp_script chk_haproxy {
# Süreç var mı? Sinyal göndermeden yalnızca varlığını kontrol eder
script "/usr/bin/killall -0 haproxy"
interval 2 # her 2 saniyede bir çalıştır
timeout 2 # betik 2 saniyede bitmezse başarısız say
fall 2 # üst üste 2 başarısızlıkta "arızalı" say
rise 2 # üst üste 2 başarıda "sağlıklı" say
weight -30 # arızalıysa priority'den 30 düş
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 110
advert_int 1
track_script {
chk_haproxy
}
virtual_ipaddress {
10.0.0.10/24 dev eth0
}
}
weight -30 satırındaki mantık şudur: lb1'in önceliği 110, lb2'ninki 100. HAProxy lb1'de çökerse betik başarısız olur ve lb1'in etkin önceliği 110 − 30 = 80'e düşer. Artık lb2 (100) daha yüksek önceliğe sahiptir ve VIP'yi devralır. HAProxy geri geldiğinde lb1 tekrar 110'a çıkar ve VIP'yi geri alır.
Ağırlık farkını doğru seçmek kritiktir. weight değerinin mutlak değeri, iki düğümün öncelik farkından büyük olmalıdır. Örneğimizde fark 10, ağırlık ise 30 — sorun yok. Ama weight -5 yazsaydın, lb1 arızalıyken bile 105 ile lb2'nin 100'ünü yenerdi ve devretme hiç gerçekleşmezdi. Bu, kurulumu "çalışıyor gibi" gösterip gerçek arızada sessizce başarısız olan en sinsi hatadır.
Süreç kontrolü yerine gerçek bir HTTP yanıtı isteyen daha sağlam bir betik de yazabilirsin:
#!/bin/bash
# /etc/keepalived/chk_web.sh — 0 dönerse sağlıklı
curl -fsS --max-time 2 -o /dev/null http://127.0.0.1:8080/saglik
sudo chmod 750 /etc/keepalived/chk_web.sh
sudo chown root:keepalived_script /etc/keepalived/chk_web.sh
⚠️ enable_script_security açıkken Keepalived, root olmayan bir kullanıcının yazabildiği betikleri çalıştırmayı reddeder. Betik dosyasının sahibi root olmalı ve grup dışındakilere yazma izni bulunmamalıdır; aksi halde Keepalived kayıtlara "unsafe" uyarısı yazar ve betiği hiç çalıştırmaz.
Devretme Anında Ne Oluyor#
VIP bir makineden diğerine geçtiğinde ağ seviyesinde iki şey olur. Birincisi, yeni MASTER VIP'yi kendi arayüzüne ekler. İkincisi ve daha önemlisi, gratuitous ARP paketleri yayınlar: "10.0.0.10 artık benim MAC adresimde" duyurusu. Aynı ağdaki tüm cihazlar ve yönlendiriciler ARP tablolarını günceller ve trafiği yeni makineye göndermeye başlar. Keepalived bunu otomatik yapar, senin bir şey yazman gerekmez.
Yük dengeleyicinin VIP üzerinde dinlemesi gerektiğinde bir engelle karşılaşırsın: HAProxy varsayılan olarak makinede henüz var olmayan bir IP'ye bağlanamaz ve BACKUP düğümde başlatılamaz. Bunu çözen sysctl ayarı şudur:
# VIP olmasa da o adrese bind edebilmek için
echo "net.ipv4.ip_nonlocal_bind = 1" | sudo tee /etc/sysctl.d/99-keepalived.conf
sudo sysctl --system
# Doğrula
sysctl net.ipv4.ip_nonlocal_bind
# net.ipv4.ip_nonlocal_bind = 1
Bu ayar olmadan tipik belirti şudur: her şeyi doğru kurmuşsundur, MASTER'da sorun yoktur, ama devretme sırasında BACKUP düğümdeki HAProxy açılışta hata verip durmuştur ve VIP boşa düşer. ip_nonlocal_bind ile her iki düğümde de servis sürekli çalışır durumda kalır, yalnızca trafiği VIP'nin durduğu makine alır.
Devretme ve geri dönüş anlarında bildirim almak istersen notify betikleri tanımlayabilirsin:
vrrp_instance VI_1 {
# ...
notify_master "/etc/keepalived/notify.sh MASTER"
notify_backup "/etc/keepalived/notify.sh BACKUP"
notify_fault "/etc/keepalived/notify.sh FAULT"
}
Bu betikler devretme kaydını dosyaya yazabilir ya da bir bildirim kanalına mesaj atabilir. Kaydı tutmak önemlidir: gece 03:00'te sessizce yaşanıp kendiliğinden geri dönmüş bir devretme fark edilmezse, aynı arıza büyüyerek geri gelir.
Split-Brain: İki MASTER Aynı Anda#
Keepalived kurulumlarında karşılaşılan en tehlikeli durum split-brain'dir. İki düğüm birbirinin VRRP duyurularını göremez ama ikisi de ağa bağlıdır. Her biri diğerinin öldüğüne karar verir, ikisi de MASTER olur ve aynı IP adresi ağda iki makinede birden durur. Sonuç kararsız ARP tabloları, yarısı bir makineye yarısı diğerine giden istekler ve iki farklı sunucuya yazan uygulamalardır.
Tipik sebepleri: güvenlik duvarının protokol 112'yi engellemesi, sağlayıcının ağında multicast'in kapalı olması, iki düğümün farklı virtual_router_id ya da auth_pass değerine sahip olması, düğümler arasındaki anahtarın multicast'i filtrelemesi. Yani neredeyse her zaman yapılandırma ya da ağ kaynaklıdır, Keepalived'in kendi hatası değildir.
Korunmanın en pratik yolları: VRRP trafiğini ayrı bir ağ arayüzünden geçirmek, multicast yerine unicast_peer kullanmak ve ikinci bir doğrulama kanalı bulundurmak. Yazma tutarlılığı kritik servisleri Keepalived ile devrettiriyorsan uygulama tarafında da bir tek-yazıcı garantisi olmalıdır. Bu kararların bütününe yüksek erişilebilirlik mimarisi yazısında bakıyoruz.
Bulut Ortamında VRRP: Unicast ve Sağlayıcı IP'leri#
Çoğu bulut sağlayıcısı sanal ağında multicast'e izin vermez. Bu durumda Keepalived'i unicast moda alırsın: her düğüm duyurularını doğrudan diğerinin IP adresine gönderir.
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 100
advert_int 1
nopreempt # eski MASTER dönünce VIP'yi geri almasın
# Multicast yerine doğrudan adresleme
unicast_src_ip 10.0.0.12
unicast_peer {
10.0.0.11
}
virtual_ipaddress {
10.0.0.10/24 dev eth0
}
}
nopreempt önemli bir davranış değişikliği getirir: varsayılan olarak eski MASTER geri döndüğünde VIP'yi hemen geri alır, yani bir arızada iki kesinti yaşarsın. nopreempt ile geri dönen düğüm BACKUP olarak bekler ve VIP yerinde kalır. Kullanmak için her iki düğümde de state BACKUP yazman gerekir.
Bulut ortamında ikinci bir engel daha var: sanal ağ, bir sunucunun kendisine atanmamış bir IP'den paket göndermesine izin vermeyebilir ve VIP hiç yönlenmez. Sağlayıcıların çözümü genellikle ayrı bir "taşınabilir IP" ürünüdür; nasıl çalıştığını floating IP nedir yazısında anlatıyoruz.
Test ve Sorun Giderme#
Kurulum bittiğinde asla "herhalde çalışıyordur" deyip bırakma. Devretmeyi kontrollü biçimde test etmek, gerçek arızada öğrenmekten çok daha ucuzdur.
# 1. VIP şu an kimde?
ip addr show eth0 | grep 10.0.0.10
# 2. VRRP duyuruları akıyor mu?
sudo tcpdump -i eth0 -n vrrp
# 3. Keepalived durumu ve karar kayıtları
sudo journalctl -u keepalived -f
# Beklenen satırlar:
# Entering MASTER STATE
# Entering BACKUP STATE
# VRRP_Script(chk_haproxy) failed
# 4. Kontrollü devretme testi: MASTER'da servisi durdur
sudo systemctl stop haproxy
# -> birkaç saniye içinde VIP lb2'ye geçmeli
# 5. Geri al
sudo systemctl start haproxy
Adım 4'ü uygularken ikinci bir terminalde VIP'ye sürekli istek göndererek kaç saniye kesinti yaşandığını ölçebilirsin:
# Her yarım saniyede bir istek, yanıt kodunu yaz
while true; do
curl -s -o /dev/null -w "%{http_code} " http://10.0.0.10/
sleep 0.5
done
Sağlıklı bir kurulumda burada en fazla birkaç saniyelik hata görürsün. On saniyeyi aşan bir kesinti varsa advert_int ve fall değerlerini gözden geçir; hiç devretme olmuyorsa büyük ihtimalle weight değeri öncelik farkından küçüktür.
Sık Yapılan Hatalar#
weight değerini öncelik farkından küçük seçmek. En sık ve en sessiz hata. Sağlık betiği başarısız olur, kayıtlarda görünür, ama etkin öncelik yine de karşı düğümün üzerinde kalır ve VIP hiç taşınmaz.
Servisi değil yalnızca makineyi izlemek. track_script olmadan Keepalived yalnızca makine tamamen kapandığında devreder. Uygulama çöktüğünde hiçbir şey olmaz — ki gerçek arızaların çoğu böyledir.
Güvenlik duvarında protokol 112'yi unutmak. Kurulum tamamlanır, kayıtlarda hata yoktur, ama iki düğüm de MASTER'dır. tcpdump -i eth0 vrrp ile karşı tarafın duyurularını görüp görmediğini kontrol et.
ip_nonlocal_bind ayarını atlamak. Devretme çalışır, VIP geçer, ama BACKUP düğümdeki servis açılışta bind edemeyip durmuş olduğu için yeni MASTER'da hiçbir şey dinlemez.
Devretmeyi hiç test etmemek. Kurulumdan aylar sonra ilk gerçek arızada, sağlık betiğinin enable_script_security yüzünden hiç çalışmadığını öğrenmek istemezsin. Devretme testini bakım planına yaz ve düzenli tekrarla.
Sıkça Sorulan Sorular#
Keepalived ile devretme ne kadar sürer#
Varsayılan ayarlarla (advert_int 1) BACKUP düğüm yaklaşık 3 saniye duyuru alamayınca MASTER'a geçer; buna gratuitous ARP'ın ağda yayılma süresi eklenir. Pratikte toplam kesinti 3-5 saniye civarındadır. advert_int değerini düşürerek bunu kısaltabilirsin, ama çok agresif değerler geçici ağ dalgalanmalarında gereksiz devretmelere yol açar; saniyenin altına inmeyi genellikle önermem.
Keepalived ücretsiz mi, lisans gerekiyor mu#
Keepalived tamamen açık kaynak ve ücretsizdir, GPL lisansıyla dağıtılır. Tüm büyük Linux dağıtımlarının resmi depolarında bulunur ve apt install keepalived ya da dnf install keepalived ile kurulur. Herhangi bir abonelik, düğüm sınırı ya da ticari kullanım kısıtı yoktur.
İki düğüm de MASTER görünüyor, neden#
Bu split-brain durumudur ve neredeyse her zaman düğümlerin birbirinin VRRP duyurularını görememesinden kaynaklanır. Sırasıyla şunları kontrol et: güvenlik duvarı IP protokol 112'ye izin veriyor mu, iki düğümde virtual_router_id aynı mı, auth_pass değerlerinin ilk 8 karakteri aynı mı, ağ multicast'e izin veriyor mu. Bulut ortamındaysan multicast büyük ihtimalle kapalıdır; unicast_peer yapılandırmasına geç.
Keepalived ile HAProxy'yi birlikte mi kullanmalıyım#
Evet, bu ikili birbirini tamamlar ve en yaygın üretim kombinasyonudur. HAProxy arka uçtaki uygulama sunucuları arasında yük dağıtır ve onların sağlığını izler; Keepalived ise HAProxy'nin kendisini yedekler ve düğüm ya da servis çöktüğünde sanal IP'yi diğer makineye taşır. Kurulum tarafı için HAProxy kurulumu yazısına, Nginx tercih ediyorsan Nginx yük dengeleyici yapılandırması yazısına bakabilirsin.
İkiden fazla düğüm ekleyebilir miyim#
Evet, gruba istediğin kadar düğüm katabilirsin; her birine farklı priority verirsin ve MASTER düştüğünde en yüksek önceliğe sahip olan devralır. Ancak pratikte iki düğüm çoğu senaryo için yeterlidir: üçüncü düğüm devretme güvenilirliğini kayda değer ölçüde artırmaz ama test yükünü büyütür. Üçüncü makineyi yedek yerine yük dengeleyicinin arkasına aktif koymak daha verimlidir.
VIP'ye SSL sertifikası nasıl kurulur#
Sertifika VIP'nin kendisine değil, VIP'yi dinleyen servise kurulur; yani HAProxy ya da Nginx yapılandırmasına. Önemli olan sertifika dosyalarının her iki düğümde de aynı olmasıdır, yoksa devretmeden sonra sertifika hatası alırsın. Let's Encrypt kullanıyorsan yenilemeyi tek düğümde yapıp dosyaları diğerine kopyalayan bir betik ya da ortak bir depolama kullan; iki düğümün ayrı ayrı yenileme yapması doğrulama çakışmalarına yol açar.
Kapanış#
Keepalived, bir yüksek erişilebilirlik kurulumunun son ve çoğu zaman atlanan halkasını kapatır: yük dengeleyicinin kendisini yedekler. Aklında tutman gereken dört şey var — track_script olmadan yalnızca makineyi izlemiş olursun, weight mutlaka öncelik farkından büyük olmalı, ip_nonlocal_bind açık değilse yedek düğümdeki servis hiç ayağa kalkmaz ve kurulumu gerçek bir kesinti öncesinde test etmelisin.
Bu mimariyi kurmak için aynı ağ segmentinde en az iki bağımsız sunucuya ihtiyacın var. VDS ve bulut sunucu paketlerimizde bu kurulumu tam root erişimiyle kendin yapabilir, donanım seviyesinde ayrıştırma istiyorsan dedicated sunucu tarafına geçebilirsin. Kurulumu ve düzenli devretme testlerini bize bırakmak istersen sunucu yönetimi hizmetimiz bu işi üstlenir; hedef kesinti sürenle gerçek uptime oranını karşılaştırmak için uptime SLA hesaplayıcı aracına bakabilirsin.