Azure Load Balancer Yapılandırması: Adım Adım Kurulum ve Yönetim
Azure ortamında uygulamalarını yüksek erişilebilirlik ile çalıştırmak istiyorsan, Load Balancer yapılandırması kaçınılmaz bir konu haline geliyor. Özellikle production ortamlarında tek bir sanal makinenin arkasına sığınmak artık bir seçenek değil. Bu yazıda Azure Load Balancer’ı sıfırdan yapılandırmayı, gerçek dünya senaryolarına göre optimize etmeyi ve yaygın hataları nasıl önleyeceğini ele alacağız.
Azure Load Balancer Nedir ve Ne Zaman Kullanılır
Azure Load Balancer, OSI modelinin 4. katmanında (TCP/UDP) çalışan, gelen trafiği birden fazla backend instance’a dağıtan bir hizmettir. Google’ladığında karşına çıkan şatafatlı tanımları bir kenara bırakalım. Pratik olarak şöyle düşün: Elinde 3 tane web sunucun var, tüm trafik sadece birine gidiyor ve o sunucu çöktüğünde servisin tamamen erişilemez oluyor. İşte Load Balancer bu sorunu çözer.
İki temel türü var:
- Public Load Balancer: İnternet’ten gelen trafiği backend pool’a dağıtır. Dışa açık uygulamalar için kullanılır.
- Internal (Private) Load Balancer: Sanal ağ içindeki trafiği yönetir. Microservice mimarileri veya çok katmanlı uygulamalarda kullanılır.
SKU seçimine de dikkat etmek gerekiyor. Basic SKU küçük test ortamları için yeterliyken, production için her zaman Standard SKU kullanmalısın. Standard SKU SLA garantisi sunar, availability zone desteği vardır ve güvenlik varsayılan olarak daha katıdır.
Önkoşullar ve Ortam Hazırlığı
Başlamadan önce birkaç şeyin hazır olması gerekiyor. Azure CLI’nin güncel sürümü yüklü olmalı ve doğru subscription’a bağlı olmalısın.
# Azure CLI versiyonunu kontrol et
az --version
# Hesabına giriş yap
az login
# Aktif subscription'ı kontrol et
az account show
# Eğer birden fazla subscription varsa doğrusunu seç
az account set --subscription "subscription-id-veya-adi"
Sonra bir Resource Group oluşturalım ve değişkenleri tanımlayalım. Bu değişkenleri script boyunca kullanacağız, bu yüzden terminal oturumunu açık tut.
# Değişkenleri tanımla
RG="rg-loadbalancer-demo"
LOCATION="westeurope"
VNET_NAME="vnet-demo"
SUBNET_NAME="subnet-backend"
LB_NAME="lb-demo-public"
PUBLIC_IP_NAME="pip-lb-demo"
BACKEND_POOL="backendpool-web"
HEALTH_PROBE="probe-http"
LB_RULE="rule-http"
# Resource group oluştur
az group create
--name $RG
--location $LOCATION
# Sanal ağ ve subnet oluştur
az network vnet create
--resource-group $RG
--name $VNET_NAME
--address-prefix 10.0.0.0/16
--subnet-name $SUBNET_NAME
--subnet-prefix 10.0.1.0/24
Public Load Balancer Yapılandırması
Public IP Adresi Oluşturma
Standard SKU için static public IP oluşturmak gerekiyor. Basic SKU’da dynamic IP kullanılabilir ama Standard’da static zorunlu.
# Static Public IP oluştur
az network public-ip create
--resource-group $RG
--name $PUBLIC_IP_NAME
--sku Standard
--allocation-method Static
--zone 1 2 3
# IP adresini kontrol et
az network public-ip show
--resource-group $RG
--name $PUBLIC_IP_NAME
--query ipAddress
--output tsv
Load Balancer’ı Oluşturma
# Load Balancer oluştur
az network lb create
--resource-group $RG
--name $LB_NAME
--sku Standard
--public-ip-address $PUBLIC_IP_NAME
--frontend-ip-name "frontend-config"
--backend-pool-name $BACKEND_POOL
# Backend pool durumunu kontrol et
az network lb address-pool show
--resource-group $RG
--lb-name $LB_NAME
--name $BACKEND_POOL
Health Probe Yapılandırması
Health probe, Load Balancer’ın backend instance’larının sağlıklı olup olmadığını anlamasını sağlar. Bu konfigürasyonu yanlış yaparsan hem çalışan sunucuya trafik gitmeyebilir hem de çökmüş sunucuya trafik gitmeye devam edebilir.
# HTTP health probe oluştur
az network lb probe create
--resource-group $RG
--lb-name $LB_NAME
--name $HEALTH_PROBE
--protocol Http
--port 80
--path "/health"
--interval 15
--threshold 2
# TCP probe alternatifi (HTTP endpoint yoksa)
az network lb probe create
--resource-group $RG
--lb-name $LB_NAME
--name "probe-tcp-443"
--protocol Tcp
--port 443
--interval 5
--threshold 2
Buradaki –interval değeri probe’un kaç saniyede bir kontrol yapacağını belirtir. –threshold ise kaç başarısız probe’dan sonra instance’ın unhealthy sayılacağını tanımlar. Örneğin interval=15 ve threshold=2 dersen, bir sunucunun 30 saniye sonra devre dışı bırakılacağı anlamına gelir.
Load Balancing Rule Tanımlama
# HTTP load balancing rule oluştur
az network lb rule create
--resource-group $RG
--lb-name $LB_NAME
--name $LB_RULE
--protocol Tcp
--frontend-port 80
--backend-port 80
--frontend-ip-name "frontend-config"
--backend-pool-name $BACKEND_POOL
--probe-name $HEALTH_PROBE
--idle-timeout 4
--enable-tcp-reset true
# HTTPS için ayrı bir rule ekle
az network lb rule create
--resource-group $RG
--lb-name $LB_NAME
--name "rule-https"
--protocol Tcp
--frontend-port 443
--backend-port 443
--frontend-ip-name "frontend-config"
--backend-pool-name $BACKEND_POOL
--probe-name "probe-tcp-443"
--idle-timeout 4
--enable-tcp-reset true
–enable-tcp-reset özelliği idle timeout dolduğunda TCP RST paketi gönderir. Bu, uzun süreli bağlantılarda uygulamanın askıda kalmasını önler. Production ortamında bu ayarı her zaman aktif et.
Backend Sanal Makineleri Yapılandırma
Backend pool’a VM eklemek için NIC’leri load balancer’a bağlamamız gerekiyor.
# Availability Set oluştur (Zone kullanmıyorsan)
az vm availability-set create
--resource-group $RG
--name "avset-web"
--platform-fault-domain-count 2
--platform-update-domain-count 5
# İki adet VM oluştur
for i in 1 2; do
az vm create
--resource-group $RG
--name "vm-web-0${i}"
--image Ubuntu2204
--size Standard_B2s
--availability-set "avset-web"
--vnet-name $VNET_NAME
--subnet $SUBNET_NAME
--admin-username azureuser
--generate-ssh-keys
--no-wait
done
# VM'lerin oluşturulmasını bekle
az vm wait
--resource-group $RG
--name "vm-web-01"
--created
az vm wait
--resource-group $RG
--name "vm-web-02"
--created
Şimdi bu VM’lerin NIC’lerini backend pool’a ekleyelim:
# Her VM'nin NIC ID'sini al ve backend pool'a ekle
for i in 1 2; do
NIC_ID=$(az vm show
--resource-group $RG
--name "vm-web-0${i}"
--query "networkProfile.networkInterfaces[0].id"
--output tsv)
NIC_NAME=$(echo $NIC_ID | awk -F'/' '{print $NF}')
# NIC'in IP konfigürasyon adını al
IP_CONFIG=$(az network nic show
--ids $NIC_ID
--query "ipConfigurations[0].name"
--output tsv)
# NIC'i backend pool'a ekle
az network nic ip-config address-pool add
--resource-group $RG
--nic-name $NIC_NAME
--ip-config-name $IP_CONFIG
--lb-name $LB_NAME
--address-pool $BACKEND_POOL
echo "vm-web-0${i} backend pool'a eklendi"
done
Network Security Group Yapılandırması
Standard SKU Load Balancer varsayılan olarak tüm trafiği engeller. NSG kurallarını doğru tanımlamamak, en sık karşılaşılan hatalardan biridir.
# NSG oluştur
az network nsg create
--resource-group $RG
--name "nsg-web-subnet"
# HTTP trafiğine izin ver
az network nsg rule create
--resource-group $RG
--nsg-name "nsg-web-subnet"
--name "Allow-HTTP"
--protocol Tcp
--priority 100
--destination-port-range 80
--access Allow
--direction Inbound
# HTTPS trafiğine izin ver
az network nsg rule create
--resource-group $RG
--nsg-name "nsg-web-subnet"
--name "Allow-HTTPS"
--protocol Tcp
--priority 110
--destination-port-range 443
--access Allow
--direction Inbound
# Azure Load Balancer health probe trafiğine izin ver
# Bu kural olmazsa probe'lar başarısız olur
az network nsg rule create
--resource-group $RG
--nsg-name "nsg-web-subnet"
--name "Allow-AzureLB"
--protocol "*"
--priority 120
--source-address-prefix "AzureLoadBalancer"
--destination-port-range "*"
--access Allow
--direction Inbound
# NSG'yi subnet'e bağla
az network vnet subnet update
--resource-group $RG
--vnet-name $VNET_NAME
--name $SUBNET_NAME
--network-security-group "nsg-web-subnet"
AzureLoadBalancer servis tag’ini unutanlar çok zaman kaybeder. Bu tag olmadan health probe’lar VM’lere ulaşamaz ve tüm instance’lar unhealthy görünür.
Internal Load Balancer Senaryosu
Çok katmanlı mimaride web katmanından uygulama katmanına trafik yönlendirmek için Internal Load Balancer kullanılır. Dışarıya açık olmayan bu yapı için public IP’ye gerek yoktur.
# Internal Load Balancer için ayrı subnet oluştur
az network vnet subnet create
--resource-group $RG
--vnet-name $VNET_NAME
--name "subnet-app"
--address-prefix 10.0.2.0/24
# Internal Load Balancer oluştur
az network lb create
--resource-group $RG
--name "lb-internal-app"
--sku Standard
--vnet-name $VNET_NAME
--subnet "subnet-app"
--private-ip-address "10.0.2.10"
--frontend-ip-name "frontend-internal"
--backend-pool-name "backendpool-app"
# Application katmanı için health probe
az network lb probe create
--resource-group $RG
--lb-name "lb-internal-app"
--name "probe-app-8080"
--protocol Http
--port 8080
--path "/actuator/health"
--interval 10
--threshold 3
# Load balancing rule
az network lb rule create
--resource-group $RG
--lb-name "lb-internal-app"
--name "rule-app"
--protocol Tcp
--frontend-port 8080
--backend-port 8080
--frontend-ip-name "frontend-internal"
--backend-pool-name "backendpool-app"
--probe-name "probe-app-8080"
--load-distribution SourceIPProtocol
–load-distribution SourceIPProtocol parametresi session persistence için önemli. Uygulamanın oturum durumunu tutması gerekiyorsa aynı istemciden gelen istekler her zaman aynı backend’e yönlendirilir.
Dağıtım modu seçenekleri:
- Default: Beş demet hash kullanır (source IP, destination IP, protocol, source port, destination port)
- SourceIP: İki demet hash (source IP ve destination IP). Aynı kaynak-hedef ikilisi her zaman aynı backend’e gider.
- SourceIPProtocol: Üç demet hash. Yukarıdaki gibi ama protocol da dahil edilir.
Outbound NAT Rules Yapılandırması
Standard SKU’da backend pool’undaki VM’ler varsayılan olarak outbound internet erişimine sahip değildir. Güvenlik açısından bu doğru bir karar ama VM’lerin güncelleme yapabilmesi veya dış servislere bağlanabilmesi için outbound rule tanımlamak gerekir.
# Outbound için ayrı Public IP oluştur
az network public-ip create
--resource-group $RG
--name "pip-outbound"
--sku Standard
--allocation-method Static
# Outbound rule oluştur
az network lb outbound-rule create
--resource-group $RG
--lb-name $LB_NAME
--name "outbound-rule"
--frontend-ip-configs "frontend-config"
--protocol All
--outbound-ports 10000
--address-pool $BACKEND_POOL
# Outbound bağlantıyı test et
az vm run-command invoke
--resource-group $RG
--name "vm-web-01"
--command-id RunShellScript
--scripts "curl -s https://ifconfig.me"
Monitoring ve Diagnostik
Load balancer’ın durumunu izlemek, sorunları erkenden fark etmen için kritik.
# Load Balancer metriklerini kontrol et
az monitor metrics list
--resource "/subscriptions/$(az account show --query id -o tsv)/resourceGroups/$RG/providers/Microsoft.Network/loadBalancers/$LB_NAME"
--metric "VipAvailability"
--interval PT1M
--output table
# Backend health durumunu sorgula
az network lb show
--resource-group $RG
--name $LB_NAME
--query "backendAddressPools[].loadBalancingRules"
--output json
# Diagnostic settings ekle (Log Analytics)
LOG_ANALYTICS_ID="/subscriptions/$(az account show --query id -o tsv)/resourceGroups/$RG/providers/Microsoft.OperationalInsights/workspaces/law-demo"
az monitor diagnostic-settings create
--name "lb-diagnostics"
--resource "/subscriptions/$(az account show --query id -o tsv)/resourceGroups/$RG/providers/Microsoft.Network/loadBalancers/$LB_NAME"
--workspace $LOG_ANALYTICS_ID
--metrics '[{"category": "AllMetrics", "enabled": true}]'
Yaygın Sorunlar ve Çözümleri
Sahada en sık karşılaştığım sorunları ve çözümlerini paylaşayım:
Backend instance’lar unhealthy görünüyor:
- NSG’de AzureLoadBalancer servis tag’i eksik olabilir
- Health probe’un hedeflediği path yanlış olabilir (“/health” yerine “/healthz” gibi)
- VM’deki uygulama probe portunu dinlemiyor olabilir
- Probe HTTP dönüşünde 200 dışında kod dönüyor olabilir
Trafik backend’lere eşit dağılmıyor:
- Session persistence aktif olabilir, SourceIPProtocol modundaysan aynı IP’den gelen istekler hep aynı backend’e gider
- Backend instance’lardan biri diğerlerinden daha güçlüyse ve weighted round-robin düşünüyorsan Azure Load Balancer bunu desteklemiyor, Application Gateway’e geçmek gerekebilir
VM’ler internete çıkamıyor:
- Standard SKU’da default outbound erişim yoktur
- Outbound rule veya NAT Gateway eklemelisin
- Ya da VM’e public IP atamalısın (production için önerilmez)
Yüksek latency:
- Cross-zone trafik ücretli ve ek latency ekler
- Zone-redundant yerine zone-specific deployment düşün
- Idle timeout değerini uygulamanın beklentisine göre ayarla
Temizlik
Test ortamı oluşturduysan ve artık ihtiyaç yoksa tüm kaynakları sil:
# Tüm resource group'u sil (içindeki her şeyle birlikte)
az group delete
--name $RG
--yes
--no-wait
echo "Resource group silme işlemi başlatıldı, birkaç dakika sürebilir"
Sonuç
Azure Load Balancer yapılandırması göründüğünden karmaşık değil ama detaylar önemli. Özellikle Standard SKU’ya geçince güvenlik varsayılan olarak kapalı geldiği için NSG kurallarını doğru yazmak, health probe’ları gerçekçi değerlerle ayarlamak ve outbound erişimi planlamak kritik oluyor.
Bu yazıda ele aldığımız konuları özetlersek: Public ve internal load balancer arasındaki fark, health probe yapılandırmasının doğru yapılmasının önemi, NSG ve AzureLoadBalancer servis tag’inin gerekliliği, outbound NAT rule ihtiyacı ve session persistence modları bunların hepsi production ortamında karşına çıkacak konular.
Bir sonraki adım olarak Azure Application Gateway’i incelemenizi öneririm. Eğer SSL termination, URL bazlı routing veya WAF gibi Layer 7 özellikleri gerekiyorsa Load Balancer’ın sınırlarına hızlıca ulaşırsın. Ama salt TCP/UDP yük dağıtımı için Azure Load Balancer hem maliyet hem de performans açısından hala en iyi seçenek olmaya devam ediyor.
