GCP Compute Engine Load Balancer Yapılandırması

Google Cloud’da bir uygulamayı production’a almadan önce load balancer yapılandırmasını doğru yapmak, gecenin 3’ünde alarm almak ile rahat uyumak arasındaki farkı belirliyor. GCP’nin load balancing sistemi AWS’ye kıyasla farklı bir mimari anlayışa sahip ve bu farkları kavramadan yapılan yapılandırmalar ciddi sorunlara yol açabiliyor. Bu yazıda sıfırdan bir HTTP(S) Load Balancer kurulumunu, backend service yapılandırmasını, health check mekanizmalarını ve gerçek dünya senaryolarında karşılaşılan tuzakları ele alacağız.

GCP Load Balancing Mimarisini Anlamak

GCP’de load balancer denince aklınıza tek bir servis gelmesin. Google’ın load balancing çözümü birkaç farklı katmandan oluşuyor ve her biri farklı kullanım senaryoları için tasarlanmış.

HTTP(S) Load Balancer: Layer 7 seviyesinde çalışır, URL tabanlı yönlendirme yapabilirsiniz, global bir yapıdır.

TCP/SSL Load Balancer: Layer 4 seviyesinde çalışır, HTTP dışı TCP trafiği için kullanılır.

Internal Load Balancer: VPC içi trafik için kullanılır, dışarıdan erişilemez.

Network Load Balancer: Yüksek performans gerektiren senaryolar için, anycast IP kullanır.

Çoğu web uygulaması senaryosunda HTTP(S) Load Balancer ile çalışacaksınız. Bu yapının en kritik özelliği global anycast IP kullanması. Yani kullanıcı dünyanın neresinden bağlansa, Google’ın en yakın edge noktasına yönlendiriliyor ve trafik Google’ın omurgası üzerinden backend’inize ulaşıyor. Bu hem latency hem de DDoS koruması açısından ciddi bir avantaj.

Ön Hazırlık: Instance Group Oluşturma

Load balancer’ın arkasına koyacağınız instance’ları önce bir Managed Instance Group (MIG) içinde toplamanız gerekiyor. MIG, otomatik ölçeklendirme ve health check entegrasyonu açısından unmanaged instance group’a göre çok daha güçlü.

Önce bir instance template oluşturalım:

gcloud compute instance-templates create web-server-template 
  --machine-type=e2-medium 
  --image-family=debian-11 
  --image-project=debian-cloud 
  --boot-disk-size=20GB 
  --tags=http-server,https-server 
  --metadata=startup-script='#!/bin/bash
    apt-get update
    apt-get install -y nginx
    echo "Backend: $(hostname)" > /var/www/html/index.html
    systemctl start nginx
    systemctl enable nginx'

Template hazır olduğunda MIG’i oluşturuyoruz. Bölgesel dağıtım için --region kullanıyoruz, tek zone için --zone:

gcloud compute instance-groups managed create web-server-mig 
  --template=web-server-template 
  --size=3 
  --region=europe-west1

# Otomatik ölçeklendirmeyi aktif ediyoruz
gcloud compute instance-groups managed set-autoscaling web-server-mig 
  --region=europe-west1 
  --min-num-replicas=2 
  --max-num-replicas=10 
  --target-cpu-utilization=0.70 
  --cool-down-period=90

MIG’deki instance’ların HTTP trafiğine yanıt vermesi için named port tanımlamak şart. Load balancer bu bilgiyi kullanıyor:

gcloud compute instance-groups managed set-named-ports web-server-mig 
  --region=europe-west1 
  --named-ports=http:80,https:443

Firewall Kurallarını Doğru Yapılandırmak

Burası çok sık atlanan ama kritik bir adım. GCP Load Balancer’ı health check paketleri belirli IP aralıklarından geliyor. Bu aralıklara izin vermezseniz health check’ler başarısız olur ve traffic hiçbir backend’e yönlendirilmez.

Google’ın health check IP aralıkları şunlar: 130.211.0.0/22 ve 35.191.0.0/16

# Health check trafiği için firewall kuralı
gcloud compute firewall-rules create allow-health-checks 
  --network=default 
  --action=allow 
  --direction=ingress 
  --source-ranges=130.211.0.0/22,35.191.0.0/16 
  --target-tags=http-server 
  --rules=tcp:80,tcp:443

# Genel HTTP/HTTPS trafiği için kural
gcloud compute firewall-rules create allow-http-https 
  --network=default 
  --action=allow 
  --direction=ingress 
  --source-ranges=0.0.0.0/0 
  --target-tags=http-server 
  --rules=tcp:80,tcp:443

Health Check Yapılandırması

Health check olmadan load balancer anlamlı bir iş yapmaz. Sağlıksız instance’lara trafik yönlendirmemesi için health check’leri doğru yapılandırmanız gerekiyor.

gcloud compute health-checks create http web-health-check 
  --port=80 
  --request-path=/health 
  --check-interval=10s 
  --timeout=5s 
  --healthy-threshold=2 
  --unhealthy-threshold=3

Parametrelerin ne anlama geldiğini açıklayalım:

–check-interval: Health check’ler arasındaki süre. 10 saniye makul bir değer, çok kısa yaparsanız gereksiz trafik üretirsiniz.

–timeout: Health check cevabı için bekleme süresi. Bu değer her zaman check-interval’dan küçük olmalı.

–healthy-threshold: Bir instance’ın tekrar sağlıklı sayılması için üst üste kaç başarılı check gerekiyor.

–unhealthy-threshold: Instance’ı sağlıksız saymak için üst üste kaç başarısız check gerekiyor.

Uygulamanızda /health endpoint’i olmuyorsa ve root path kullanıyorsanız şunu göz önünde bulundurun: root path bazen redirect döndürür ve bu health check’i başarısız sayar. /health endpoint’i her zaman 200 OK ve basit bir JSON response dönmeli.

Backend Service Oluşturma

Backend service, load balancer’ın instance group’larla nasıl konuşacağını tanımlayan yapı. Burada session affinity, connection draining ve protokol gibi kritik ayarlar yapılıyor:

gcloud compute backend-services create web-backend-service 
  --protocol=HTTP 
  --port-name=http 
  --health-checks=web-health-check 
  --global 
  --connection-draining-timeout=300 
  --session-affinity=NONE 
  --load-balancing-scheme=EXTERNAL

–connection-draining-timeout: Bir instance sağlıksız duruma düştüğünde veya ölçeklendirme nedeniyle kaldırılırken, mevcut bağlantıların kapatılması için beklenen süre. 300 saniye çoğu senaryo için yeterli ancak uzun süreli işlemler yapan uygulamalarda bu değeri artırın.

–session-affinity: Aynı kullanıcının aynı backend’e yönlendirilmesi için. Stateless uygulamalarda NONE tercih edin, session tabanlı uygulamalarda CLIENT_IP veya GENERATED_COOKIE kullanabilirsiniz.

Şimdi MIG’i backend service’e ekleyelim:

gcloud compute backend-services add-backend web-backend-service 
  --instance-group=web-server-mig 
  --instance-group-region=europe-west1 
  --balancing-mode=UTILIZATION 
  --max-utilization=0.8 
  --global

–balancing-mode: İki seçenek var. UTILIZATION, CPU kullanımına göre trafik dağıtır. RATE ise saniyedeki istek sayısına göre dağıtır. Genel web uygulamaları için UTILIZATION daha sağlıklı sonuç verir.

URL Map ve Frontend Yapılandırması

URL map, hangi URL’nin hangi backend’e gideceğini belirliyor. Basit bir yapılandırmadan başlayalım:

# URL map oluşturma
gcloud compute url-maps create web-url-map 
  --default-service=web-backend-service

# HTTP proxy oluşturma
gcloud compute target-http-proxies create web-http-proxy 
  --url-map=web-url-map

# Forwarding rule (Frontend IP ve port) oluşturma
gcloud compute forwarding-rules create web-forwarding-rule 
  --address-type=EXTERNAL 
  --target-http-proxy=web-http-proxy 
  --ports=80 
  --global

Bu noktada temel bir load balancer çalışır durumda. Ancak production ortamı için HTTPS zorunlu. SSL sertifikası ekleyelim:

# Google managed SSL sertifikası oluşturma
gcloud compute ssl-certificates create web-ssl-cert 
  --domains=app.example.com 
  --global

# HTTPS proxy oluşturma
gcloud compute target-https-proxies create web-https-proxy 
  --url-map=web-url-map 
  --ssl-certificates=web-ssl-cert

# HTTPS forwarding rule
gcloud compute forwarding-rules create web-https-forwarding-rule 
  --address-type=EXTERNAL 
  --target-https-proxy=web-https-proxy 
  --ports=443 
  --global

Google managed sertifikalar otomatik yenileniyor, yönetimini tamamen GCP’ye bırakıyorsunuz. Sertifikanın aktif olması için domain’in load balancer IP’sini göstermesi gerekiyor ve bu bazen 30-60 dakika sürebiliyor.

HTTP’den HTTPS’e Yönlendirme

Kullanıcılar HTTP ile geldiğinde HTTPS’e yönlendirmek için URL map’e redirect kuralı eklemeniz gerekiyor:

# HTTP redirect için ayrı URL map
gcloud compute url-maps import http-redirect-url-map --global << 'EOF'
kind: compute#urlMap
name: http-redirect-url-map
defaultUrlRedirect:
  redirectResponseCode: MOVED_PERMANENTLY_DEFAULT
  httpsRedirect: true
EOF

# HTTP proxy'yi redirect map'e bağla
gcloud compute target-http-proxies create http-redirect-proxy 
  --url-map=http-redirect-url-map

# HTTP forwarding rule'u güncelle
gcloud compute forwarding-rules delete web-forwarding-rule --global --quiet

gcloud compute forwarding-rules create web-http-redirect-rule 
  --address-type=EXTERNAL 
  --target-http-proxy=http-redirect-proxy 
  --ports=80 
  --global

Path-Based Routing: Gerçek Dünya Senaryosu

Diyelim ki bir e-ticaret platformu yönetiyorsunuz. API istekleri ayrı bir backend grubuna, statik dosyalar Cloud Storage’a, ana site ise web server’lara gidecek. Bu senaryoyu URL map ile çözebilirsiniz:

# API backend service
gcloud compute backend-services create api-backend-service 
  --protocol=HTTP 
  --port-name=http 
  --health-checks=web-health-check 
  --global

# API MIG'ini backend'e ekle
gcloud compute backend-services add-backend api-backend-service 
  --instance-group=api-server-mig 
  --instance-group-region=europe-west1 
  --balancing-mode=RATE 
  --max-rate-per-instance=1000 
  --global

# Cloud Storage bucket'ını backend olarak eklemek için bucket backend service
gcloud compute backend-buckets create static-content-backend 
  --gcs-bucket-name=my-static-assets-bucket 
  --enable-cdn

# URL map'e path rules ekle
gcloud compute url-maps import web-url-map --global << 'EOF'
kind: compute#urlMap
name: web-url-map
defaultService: projects/MY_PROJECT/global/backendServices/web-backend-service
hostRules:
- hosts:
  - app.example.com
  pathMatcher: main-path-matcher
pathMatchers:
- name: main-path-matcher
  defaultService: projects/MY_PROJECT/global/backendServices/web-backend-service
  pathRules:
  - paths:
    - /api
    - /api/*
    service: projects/MY_PROJECT/global/backendServices/api-backend-service
  - paths:
    - /static
    - /static/*
    service: projects/MY_PROJECT/global/backendBuckets/static-content-backend
EOF

Cloud CDN Entegrasyonu

Backend bucket için CDN zaten aktif ettik. Web backend’e de CDN eklemek için:

gcloud compute backend-services update web-backend-service 
  --enable-cdn 
  --global

# Cache key politikası belirleme
gcloud compute backend-services update web-backend-service 
  --global 
  --cache-key-include-host 
  --cache-key-include-protocol 
  --cache-key-include-query-string

CDN’in ne önbelleğe alacağını header ile kontrol edebilirsiniz. Nginx’te şöyle bir yapılandırma yapın:

# /etc/nginx/sites-available/default içinde
location /api/ {
    add_header Cache-Control "no-store, no-cache, must-revalidate";
    proxy_pass http://localhost:8080;
}

location /static/ {
    add_header Cache-Control "public, max-age=86400";
    root /var/www;
}

Load Balancer Durumunu İzleme

Production’da bir şeyler ters gittiğinde hızlıca teşhis edebilmek için monitoring şart. GCP CLI ile backend sağlığını kontrol etmek:

# Backend service sağlık durumu
gcloud compute backend-services get-health web-backend-service 
  --global

# Forwarding rule listesi ve IP adresleri
gcloud compute forwarding-rules list --global

# URL map detayları
gcloud compute url-maps describe web-url-map --global

# SSL sertifika durumu
gcloud compute ssl-certificates describe web-ssl-cert --global

Backend sağlık çıktısında HEALTHY, UNHEALTHY veya UNKNOWN durumlarını göreceksiniz. UNKNOWN genellikle health check’in henüz tamamlanmadığı anlamına gelir.

Logging için Cloud Logging’e load balancer loglarını yönlendirin:

gcloud compute backend-services update web-backend-service 
  --global 
  --enable-logging 
  --logging-sample-rate=1.0

Sample rate 0.0 ile 1.0 arasında bir değer alır. 1.0 tüm isteklerin loglandığı anlamına gelir. Production’da maliyet açısından 0.1 veya 0.25 daha makul olabilir.

Yaygın Sorunlar ve Çözümleri

502 Bad Gateway alma sorunu: En sık karşılaşılan problem. Birkaç olası neden var. Backend instance’ların health check’e cevap vermediğini doğrulayın. Named port tanımının doğru olduğunu kontrol edin. Firewall kurallarının health check IP aralıklarına izin verdiğinden emin olun.

SSL sertifikası PROVISIONING durumunda takılma: Domain DNS kaydının load balancer IP’sini gösterdiğini doğrulayın. Sertifika aktivasyonu 60 dakikaya kadar sürebilir, sabırlı olun. Birden fazla domain varsa hepsinin DNS’i doğru yapılandırılmış olmalı.

Session sorunları: Stateful uygulamalarda session affinity olmadan kullanıcılar her istekte farklı backend’e gidebilir. Ya session’ları Redis gibi merkezi bir depoya taşıyın ya da GENERATED_COOKIE affinity kullanın.

Health check false positive: Uygulamanız 200 OK dönüyor ama içerik hatalı. Health check endpoint’inde sadece HTTP status code değil uygulama bileşenlerini de kontrol edin. Veritabanı bağlantısı, cache bağlantısı gibi kritik bileşenlerin durumunu /health endpoint’ine yansıtın.

Maliyet Optimizasyonu

Load balancer maliyeti aklınızda bulundurmanız gereken bir konu. GCP HTTP(S) Load Balancer için saatlik ücret artı işlenen veri başına ücret alınıyor.

Maliyeti düşürmek için şunlara dikkat edin:

  • Cloud CDN aktif edin, orjin’e gelen trafik azalır ve CDN cache’den servis maliyet açısından daha avantajlı.
  • Gereksiz backend service‘lerden kaçının, her biri ayrı ücretlendiriliyor.
  • Log sample rate‘i üretim ihtiyacına göre ayarlayın.
  • Test ortamları için load balancer yerine Cloud Run veya GKE’nin kendi load balancing mekanizmalarını değerlendirin.

Terraform ile Tüm Yapıyı Kod Olarak Yönetmek

Tüm bu yapıyı manuel CLI komutlarıyla kurmak yerine Terraform ile yönetmek daha sürdürülebilir. Temel bir örnek:

# main.tf içinde backend service tanımı
resource "google_compute_backend_service" "web_backend" {
  name                  = "web-backend-service"
  protocol              = "HTTP"
  port_name             = "http"
  load_balancing_scheme = "EXTERNAL"
  timeout_sec           = 30
  enable_cdn            = true

  health_checks = [google_compute_health_check.web_health.id]

  backend {
    group           = google_compute_region_instance_group_manager.web_mig.instance_group
    balancing_mode  = "UTILIZATION"
    max_utilization = 0.8
  }

  log_config {
    enable      = true
    sample_rate = 0.1
  }
}

resource "google_compute_health_check" "web_health" {
  name               = "web-health-check"
  check_interval_sec = 10
  timeout_sec        = 5

  http_health_check {
    port         = 80
    request_path = "/health"
  }
}

Terraform ile yönetim yapısı kurduğunuzda terraform plan ile değişiklikleri production’a uygulamadan önce görebilirsiniz. Bu özellikle load balancer gibi kritik altyapıda büyük kolaylık sağlıyor.

Sonuç

GCP HTTP(S) Load Balancer, doğru yapılandırıldığında son derece güçlü ve güvenilir bir altyapı sunuyor. Ancak sıradan bir load balancer gibi davranmıyor; global anycast mimarisi, CDN entegrasyonu ve URL tabanlı yönlendirme gibi özellikleriyle çok katmanlı bir sistem.

Yapılandırmada en kritik noktaları özetlemek gerekirse: health check IP aralıkları için firewall kuralları olmadan hiçbir şey çalışmaz, connection draining değerini uygulamanızın işlem sürelerine göre ayarlayın, HTTPS yönlendirmesini unutmayın ve backend service’leri Terraform gibi bir IaC aracıyla yönetin. Manuel CLI komutları ilk kurulum için uygun ama uzun vadede yapıyı code olarak tutmak hem izlenebilirlik hem de kurtarma senaryoları için hayat kurtarıcı.

Production’a geçmeden önce mutlaka health check’lerin HEALTHY durumda olduğunu, SSL sertifikasının ACTIVE olduğunu ve farklı path’lerin doğru backend’lere yönlendiğini doğrulayın. Küçük bir test trafiği göndererek logları izlemek, gece 3’te alarm almaktansa çok daha keyifli bir tercih.

Bir yanıt yazın

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