ipvsadm ile Linux Sanal Sunucu (LVS) Yük Dengeleme Yapılandırması ve Yönetimi

Yük dengeleme konusuna yıllar önce bir e-ticaret projesinde girmek zorunda kaldım. O dönemde HAProxy ve Nginx her yerde konuşulurken, ben altyapıda LVS’yi keşfedince neden bu kadar az belgeleme var diye düşündüm. Kernel seviyesinde çalışması, düşük overhead’i ve gerçek anlamda yüksek trafik senaryolarındaki performansı beni çok etkiledi. Bugün ipvsadm aracını ve LVS altyapısını baştan sona ele alacağız.

LVS Nedir ve Neden Kernel Seviyesinde Önemlidir

Linux Virtual Server (LVS), Linux çekirdeğinin içine entegre edilmiş bir yük dengeleme çözümüdür. HAProxy veya Nginx’in userspace’de çalışmasının aksine, LVS doğrudan kernel’in netfilter altyapısı üzerinde çalışır. Bu fark pratikte şu anlama gelir: paketler userspace’e hiç çıkmadan yönlendirilir, context switch maliyeti yoktur ve binlerce eş zamanlı bağlantıyı minimal CPU kullanımıyla yönetebilirsiniz.

ipvsadm bu çekirdeğin IPVS (IP Virtual Server) modülünü yönetmek için kullanılan kullanıcı arayüzü aracıdır. LVS’yi iptables‘ın nasıl netfilter’ı yönettiği gibi düşünebilirsiniz; ipvsadm de IPVS kural setini aynı şekilde yönetir.

Temel bileşenler şunlardır:

  • Director (Yönetici Sunucu): Gelen trafiği alan ve backend sunuculara dağıtan LVS çalıştıran makine
  • Real Server (Gerçek Sunucu): Asıl iş yükünü taşıyan backend sunucular
  • Virtual IP (VIP): Client’ların bağlandığı, director üzerinde tanımlı sanal IP adresi

Kurulum ve Ön Hazırlık

Çoğu modern Linux dağıtımında IPVS modülü zaten kernel’e derlenmiş gelir. Önce modülün yüklenip yüklenmediğini kontrol edin:

lsmod | grep ip_vs
modinfo ip_vs

Eğer modül yüklü değilse:

modprobe ip_vs
modprobe ip_vs_rr
modprobe ip_vs_wrr
modprobe ip_vs_lc

ipvsadm aracını kurmak için:

# RHEL/CentOS/AlmaLinux
dnf install ipvsadm -y

# Debian/Ubuntu
apt install ipvsadm -y

# Arch Linux
pacman -S ipvsadm

Modüllerin sistem yeniden başladıktan sonra da yüklü kalması için /etc/modules-load.d/ipvs.conf dosyası oluşturun:

cat > /etc/modules-load.d/ipvs.conf << 'EOF'
ip_vs
ip_vs_rr
ip_vs_wrr
ip_vs_lc
ip_vs_lblc
ip_vs_sh
nf_conntrack
EOF

İpvsadm Temel Parametreleri

Araçla çalışmadan önce sık kullanılan parametreleri bilmek lazım:

Servis yönetimi:

  • -A: Yeni sanal servis ekler (Add)
  • -E: Mevcut sanal servisi düzenler (Edit)
  • -D: Sanal servisi siler (Delete)
  • -C: Tüm kuralları temizler (Clear)
  • -L: Kuralları listeler (List)

Real server yönetimi:

  • -a: Sanal servise gerçek sunucu ekler
  • -e: Gerçek sunucu ayarlarını düzenler
  • -d: Gerçek sunucu siler

Sık kullanılan seçenekler:

  • -t: TCP servisi tanımlar
  • -u: UDP servisi tanımlar
  • -s: Zamanlama algoritması belirtir (rr, wrr, lc, wlc, sh…)
  • -r: Real server adresini belirtir
  • -w: Sunucu ağırlığını (weight) belirtir
  • -m: Masquerading (NAT) modunu etkinleştirir
  • -g: Direct Routing modunu etkinleştirir
  • -i: IP tunneling modunu etkinleştirir
  • –save: Kuralları stdout’a yazar
  • –restore: stdin’den kuralları yükler
  • -n: Sayısal çıktı (DNS çözümlemesi yapmaz)
  • -c: Bağlantı tablosunu gösterir
  • –stats: İstatistik bilgilerini gösterir
  • –rate: Oran bazlı istatistikler gösterir

LVS Çalışma Modları

LVS üç farklı yönlendirme modunda çalışabilir. Ortamınıza göre hangisini seçeceğiniz kritik bir karardır.

NAT Modu (Masquerading)

En basit kurulum şeklidir. Director hem gelen hem giden trafiği yönetir. Backend sunucular dışarıya erişmek için director’ı default gateway olarak kullanmak zorundadır. Küçük ve orta ölçekli kurulumlar için uygundur ama director darboğaz yaratabilir.

Direct Routing (DR) Modu

Üretim ortamlarında en çok tercih ettiğim mod budur. Director sadece gelen paketleri yönlendirir, cevaplar backend sunuculardan doğrudan client’a gider. Bu sayede director üzerindeki yük dramatik biçimde azalır. Ancak director ve real server’ların aynı L2 ağda (aynı switch broadcast domain) olması gerekir.

IP Tunneling Modu

Real server’ların farklı lokasyonlarda (hatta farklı veri merkezlerinde) olabildiği senaryo için tasarlanmıştır. IP-in-IP tünelleme kullanır. Coğrafi dağıtık yapılar için tercih edilir.

NAT Modu ile Temel Yapılandırma

Senaryo: 192.168.1.100 IP adresli director, 80. portta gelen HTTP trafiğini iki backend sunucuya dağıtsın.

  • Director: 192.168.1.100 (dış), 10.0.0.1 (iç)
  • Backend-1: 10.0.0.10
  • Backend-2: 10.0.0.11
  • VIP: 192.168.1.200

Önce IP forwarding’i aktif edin:

echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf
sysctl -p

Sanal servisi oluşturun ve backend’leri ekleyin:

# VIP'i interface'e ekle
ip addr add 192.168.1.200/24 dev eth0

# Sanal servis oluştur, round-robin algoritması kullan
ipvsadm -A -t 192.168.1.200:80 -s rr

# Backend sunucularını NAT moduyla ekle
ipvsadm -a -t 192.168.1.200:80 -r 10.0.0.10:80 -m
ipvsadm -a -t 192.168.1.200:80 -r 10.0.0.11:80 -m

# Kuralları listele
ipvsadm -L -n

NAT modunda backend sunucuların default gateway’i director olarak ayarlanmalıdır:

# Backend sunucularda çalıştırılacak
ip route del default
ip route add default via 10.0.0.1

Direct Routing Modu ile Üretim Yapılandırması

DR modu daha karmaşık görünür ama performans açısından çok daha üstündür. Büyük bir medya platformu için DR modunu yapılandırdığımda saniyede 50.000 isteği director üzerinde %8 CPU kullanımıyla karşılayabildik; aynı trafiği NAT modunda test ettiğimizde CPU %45’e çıkmıştı.

Senaryo:

  • VIP: 10.10.10.100
  • Director eth0: 10.10.10.1
  • Backend-1 eth0: 10.10.10.10
  • Backend-2 eth0: 10.10.10.11

Director üzerinde:

# VIP'i ekle
ip addr add 10.10.10.100/32 dev lo label lo:0

# IP forwarding aç
sysctl -w net.ipv4.ip_forward=1

# Sanal servis oluştur
ipvsadm -A -t 10.10.10.100:80 -s wlc

# Backend'leri DR moduyla ekle (weighted least connection)
ipvsadm -a -t 10.10.10.100:80 -r 10.10.10.10:80 -g -w 10
ipvsadm -a -t 10.10.10.100:80 -r 10.10.10.11:80 -g -w 5

Her backend sunucu üzerinde VIP’i loopback’e eklemeniz ve ARP davranışını düzenlemeniz gerekir. Bu DR modunun en kritik adımıdır:

# ARP yanıtlamasını kapat (VIP için)
sysctl -w net.ipv4.conf.all.arp_ignore=1
sysctl -w net.ipv4.conf.all.arp_announce=2
sysctl -w net.ipv4.conf.lo.arp_ignore=1
sysctl -w net.ipv4.conf.lo.arp_announce=2

# VIP'i loopback'e ekle
ip addr add 10.10.10.100/32 dev lo label lo:0

# sysctl kalıcı hale getir
cat >> /etc/sysctl.conf << 'EOF'
net.ipv4.conf.all.arp_ignore=1
net.ipv4.conf.all.arp_announce=2
EOF
sysctl -p

Bu ARP ayarı yapılmazsa her backend sunucu VIP için ARP cevabı verir ve ağ karışıklığı oluşur. Bunu atladığınızda client istekleri rastgele backend’lere gider, director bypass edilir ve kurulum çalışmıyormuş gibi görünür. Saatler alan bir debug süreci yaşayabilirsiniz.

Zamanlama Algoritmaları

ipvsadm farklı yük dağılım algoritmaları sunar:

  • rr (Round Robin): Sırayla dağıtır, en basit seçenek
  • wrr (Weighted Round Robin): Ağırlıklara göre sırayla dağıtır
  • lc (Least Connection): En az aktif bağlantısı olan sunucuya yönlendirir
  • wlc (Weighted Least Connection): Ağırlık ve aktif bağlantı sayısını birleştirir, genellikle en iyi seçimdir
  • sh (Source Hashing): Kaynak IP’ye göre aynı backend’e yönlendirir, session affinity için kullanılır
  • dh (Destination Hashing): Hedef IP’ye göre hash’ler
  • lblc (Locality-Based Least Connection): Cache sunucuları için özel tasarlanmıştır
  • sed (Shortest Expected Delay): Beklenen gecikmeye göre dağıtır
  • nq (Never Queue): Boş sunucu varsa direkt gönderir, yoksa SED kullanır

Session tabanlı uygulamalar için sh algoritmasını kullanmak, ya da uygulama katmanında session replication yapmak gerekir. Basit stateless API servisleri için wlc genellikle en iyi sonucu verir.

Kalıcı Bağlantı (Persistence) Ayarı

Bazı uygulamalar aynı client’ın belirli süre boyunca aynı backend’e gitmesini gerektirir. HTTPS handshake, oturum yönetimi gibi durumlar bunun örneğidir:

# 300 saniyelik persistence ile servis oluştur
ipvsadm -A -t 10.10.10.100:443 -s wlc -p 300

# Persistence sadece belirli bir port için değil tüm portlar için de tanımlanabilir
# 0 port numarası tüm portları kapsar
ipvsadm -A -t 10.10.10.100:0 -s rr -p 600

Kuralları İzleme ve Sorun Giderme

Canlı ortamda en çok ihtiyaç duyduğunuz komutlar bunlardır:

# Servisleri ve backend'leri detaylıca listele
ipvsadm -L -n --stats

# Aktif bağlantıları göster
ipvsadm -L -n -c

# Belirli bir servisi izle (her 2 saniyede bir güncelle)
watch -n 2 'ipvsadm -L -n --stats'

# Hız istatistikleri
ipvsadm -L -n --rate

# Bağlantı sayısı, byte ve paket istatistikleri
ipvsadm -L -n --stats | grep -E "(TCP|->)"

# Kernel IPVS bağlantı tablosunu doğrudan görmek için
cat /proc/net/ip_vs
cat /proc/net/ip_vs_stats
cat /proc/net/ip_vs_conn

Timeout değerlerini görmek ve ayarlamak için:

# Mevcut timeout değerlerini gör
ipvsadm -L --timeout

# TCP, TCP FIN ve UDP timeout değerlerini ayarla (saniye cinsinden)
ipvsadm --set 900 120 300

Kuralları Kaydetme ve Geri Yükleme

Üretim ortamında kuralların yeniden başlatma sonrasında kaybolmaması kritiktir:

# Kuralları kaydet
ipvsadm --save > /etc/ipvsadm.rules
# veya
ipvsadm-save -n > /etc/ipvsadm.rules

# Kayıtlı kuralları geri yükle
ipvsadm --restore < /etc/ipvsadm.rules
# veya
ipvsadm-restore < /etc/ipvsadm.rules

Systemd ile otomatik yükleme için:

# ipvsadm servisini etkinleştir
systemctl enable ipvsadm
systemctl start ipvsadm

# RHEL tabanlı sistemlerde kurallar /etc/sysconfig/ipvsadm'e kaydedilir
ipvsadm-save > /etc/sysconfig/ipvsadm

Gerçek Dünya Senaryosu: Çok Katmanlı Web Uygulaması

Bir fintech şirketinin altyapısını ele alalım. HTTP (80) ve HTTPS (443) trafiği için ayrı sanal servisler, farklı ağırlıklara sahip sunucular ve persistence ihtiyacı var:

#!/bin/bash
# lvs-setup.sh - Üretim LVS yapılandırması

VIP="203.0.113.100"
BACKEND1="10.0.1.10"
BACKEND2="10.0.1.11"
BACKEND3="10.0.1.12"  # Daha güçlü sunucu

# Önceki kuralları temizle
ipvsadm -C

# HTTP servisi - persistence yok, wlc algoritması
ipvsadm -A -t ${VIP}:80 -s wlc

ipvsadm -a -t ${VIP}:80 -r ${BACKEND1}:80 -g -w 10
ipvsadm -a -t ${VIP}:80 -r ${BACKEND2}:80 -g -w 10
ipvsadm -a -t ${VIP}:80 -r ${BACKEND3}:80 -g -w 20

# HTTPS servisi - 180 saniyelik persistence, sh algoritması
ipvsadm -A -t ${VIP}:443 -s sh -p 180

ipvsadm -a -t ${VIP}:443 -r ${BACKEND1}:443 -g -w 10
ipvsadm -a -t ${VIP}:443 -r ${BACKEND2}:443 -g -w 10
ipvsadm -a -t ${VIP}:443 -r ${BACKEND3}:443 -g -w 20

# Kuralları kaydet
ipvsadm-save -n > /etc/sysconfig/ipvsadm

echo "LVS yapılandırması tamamlandı"
ipvsadm -L -n

Sağlık Kontrolü ve Keepalived Entegrasyonu

ipvsadm kendi başına health check yapmaz. Üretimde bunu keepalived ile tamamlamak zorunludur. keepalived hem VRRP ile yüksek erişilebilirlik (iki director arasında failover) hem de backend sağlık kontrolü sağlar. Minimal bir keepalived konfigürasyonu:

# /etc/keepalived/keepalived.conf örneği
# Director-1 üzerinde

vrrp_instance LVS_VIP {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 100
    virtual_ipaddress {
        10.10.10.100/24
    }
}

virtual_server 10.10.10.100 80 {
    delay_loop 6
    lb_algo wlc
    lb_kind DR
    persistence_timeout 0
    protocol TCP

    real_server 10.10.10.10 80 {
        weight 10
        TCP_CHECK {
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }

    real_server 10.10.10.11 80 {
        weight 10
        TCP_CHECK {
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }
}

Keepalived, backend sunucu down olduğunda otomatik olarak ipvsadm kuralından çıkarır ve sunucu düzeldiğinde geri ekler. Bu olmadan LVS kullanmak yarım bir çözümdür.

Yaygın Hatalar ve Çözümleri

Problem: DR modunda client istekler backend’e ulaşıyor ama cevap gelmiyor.

Çözüm: Backend loopback ARP ayarlarını kontrol edin. arping -I eth0 komutu ile birden fazla MAC adresi cevap veriyorsa sorun burada. ip addr show ile loopback’te VIP’in tanımlı olduğunu doğrulayın.

Problem: ipvsadm -L çıktısında backend’ler görünüyor ama bağlantı sayısı hiç artmıyor.

Çözüm: ip_forward aktif mi kontrol edin. sysctl net.ipv4.ip_forward komutu 1 döndürmeli. Ayrıca firewall kurallarının IPVS trafiğini engelleyip engellemediğini inceleyin.

Problem: Persistence ayarlı olmasına rağmen aynı client farklı backend’lere gidiyor.

Çözüm: Client NAT arkasındaysa tüm istekler aynı IP’den geldiği için sh algoritması işe yaramaz. Bu durumda uygulama katmanında cookie-based session yönetimi şarttır.

Sonuç

LVS ve ipvsadm, Türkiye’deki sysadmin camiasında hak ettiği ilgiyi göremeyen bir teknoloji. Kernel seviyesinde çalışması, sıfıra yakın overhead’i ve Linux’un her yerine entegre edilmiş olması onu yüksek trafik senaryolarında vazgeçilmez kılar. HAProxy veya Nginx ile yük dengeleme yapıyorsanız bunları tamamen bırakmanıza gerek yok; LVS’yi L4 katmanında öne koyup Nginx’i L7 için arkada kullanmak mükemmel bir hibrit mimari oluşturur.

Kurulum öğrenme eğrisi biraz dikkat ister; özellikle DR modundaki ARP ayarları, ilk seferinde herkesin kafasını karıştırır. Ama bir kez oturduğunda son derece kararlı ve öngörülebilir bir sistem elde edersiniz. Keepalived ile tamamlandığında hem yüksek erişilebilirlik hem de akıllı yük dağılımı sunan tam anlamıyla production-grade bir altyapı kurmuş olursunuz. Özellikle yüksek bant genişliği gerektiren medya servisleri, finansal uygulamalar ve DNS altyapıları için ipvsadm hala birinci tercih olmaya devam ediyor.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir