GKE ile 10 Bölgede Tek Manifest ile API Dağıtımı
GKE üzerinde küresel ölçekte gerçek zamanlı API çalıştırmak ve manifest tekrarlarından kurtulmak mı istiyorsunuz? İşte akıllı otomasyon yöntemleri!
Günümüzün dijital dünyasında, milisaniyeler bile kullanıcı deneyimini doğrudan etkilemektedir. Özellikle finans, oyun ve gerçek zamanlı haberleşme gibi sektörlerde, API (Uygulama Programlama Arayüzü) yanıt sürelerinin olabildiğince düşük olması hayati önem taşır. Bu gereksinimi karşılamanın en etkili yolu, uygulamalarınızı kullanıcılara coğrafi olarak en yakın noktalarda barındırmaktır. Google Kubernetes Engine (GKE), dünya genelinde yayılmış altyapısıyla bu ihtiyaca mükemmel bir yanıt sunar. Ancak, uygulamanızı 10 farklı küresel bölgede (region) çalıştırmaya karar verdiğinizde karşınıza büyük bir engel çıkar: Yapılandırma karmaşası.
Her bölge için ayrı ayrı Kubernetes manifest (yapılandırma dosyası) dosyaları oluşturmak, kopyalamak ve bunları güncel tutmak tam bir operasyonel kabustur. “Configuration Drift” (Yapılandırma Sapması) adı verilen bu durum, bölgeler arasında uyumsuzluklara ve beklenmedik kesintilere yol açar. Bu makalede, GKE üzerinde 10 farklı bölgede gerçek zamanlı bir API’yi, manifest dosyalarınızı hiç kopyalamadan (DRY – Don’t Repeat Yourself ilkesine sadık kalarak) nasıl başarıyla dağıtacağınızı adım adım inceleyeceğiz.
Küresel Ölçekte API Dağıtmanın Zorlukları Nelerdir?
Küresel bir API dağıtımı planlarken, mühendislik ekiplerinin karşılaştığı ilk zorluk altyapı yönetiminin karmaşıklığıdır. 10 farklı bölgede (örneğin; Frankfurt, Tokyo, Iowa, Sidney, São Paulo ve diğerleri) çalışan GKE kümeleriniz (clusters) olduğunu hayal edin. Her kümenin kendine has veritabanı bağlantı dizesi (connection string), IP blokları ve ölçeklendirme politikaları olacaktır.
Eğer geleneksel yöntemleri kullanırsanız, her bölge için ayrı bir YAML dosyası oluşturmanız gerekir. Bu durum şu sorunları beraberinde getirir:
- İnsan Hatası Riski: Bir ortam değişkenini (environment variable) güncellerken 10 dosyadan birini atlamanız, o bölgedeki uygulamanın çökmesine neden olabilir.
- Sürüm Kontrolü Zorluğu: Git geçmişiniz, aynı değişikliklerin tekrarlandığı yüzlerce satırlık commit (gönderim) mesajlarıyla dolar.
- Gecikme Süresi (Latency) Yönetimi: Bölgeler arasındaki veri senkronizasyonu ve trafik yönlendirmesi karmaşıklaşır.
Bu zorlukların üstesinden gelmek için modern bulut bilişim mimarisi (cloud computing architecture) prensiplerini ve deklaratif (bildirimsel) altyapı araçlarını kullanmamız gerekir. Amacımız, tek bir ana şablon (base template) tanımlamak ve bölgelere özel farklılıkları bu şablonun üzerine dinamik olarak giydirmektir.
Temel Kavramlar: GitOps, Kustomize ve Helm Nedir?
Süreci otomatikleştirmek ve kod tekrarlarından kaçınmak için modern GitOps araçları ve Kubernetes yerel yapılandırma yöneticilerinden yararlanacağız. Bu araçların rollerini anlamak, kuracağımız mimarinin temelini oluşturur.
| Araç | Temel Rolü | Çoklu Bölge Dağıtımındaki Avantajı |
|---|---|---|
| GitOps (ArgoCD) | Git deposunu tek doğruluk kaynağı (single source of truth) olarak kullanır. | Tüm kümelerin durumunu Git ile otomatik olarak eşitler. |
| Kustomize | Şablon kullanmadan (template-free) YAML dosyalarını özelleştirir. | Base (taban) ve Overlay (katman) mantığıyla kod tekrarını önler. |
| Helm | Kubernetes için paket yöneticisidir. | Üçüncü taraf uygulamaları standartlaştırmak için idealdir. |
Kustomize, Kubernetes topluluğu tarafından geliştirilen ve kubectl içerisine entegre edilmiş bir araçtır. Helm’den farklı olarak, YAML dosyalarınızı karmaşık şablon dilleriyle (Go templating) doldurmaz. Bunun yerine, saf Kubernetes manifestlerinizi alır ve üzerlerine yama (patch) uygulayarak hedef bölgeye uygun hale getirir. Bu makalede, kod tekrarlarını önlemek için ana silahımız Kustomize olacaktır.
Mimari Tasarım: 10 Bölgede Tek Merkezden Yönetim Nasıl Kurulur?
10 bölgeye yayılmış bir API’nin trafiğini yönetmek ve bu kümeleri tek bir merkezden kontrol etmek için Google Cloud’un sunduğu gelişmiş ağ çözümlerini kullanacağız. Mimarimizin merkezinde GKE Multi-Cluster Gateway yer alacaktır.
Geleneksel mimarilerde, her bölgedeki Kubernetes kümesi için ayrı bir harici yük dengeleyici (external load balancer) oluşturulur. Bu durum hem maliyeti artırır hem de DNS seviyesinde karmaşık coğrafi yönlendirme kuralları yazmanızı gerektirir. GKE Multi-Cluster Gateway ise Google’ın küresel Anycast IP altyapısını kullanır. Dünyanın neresinden gelirse gelsin, tüm kullanıcılar tek bir IP adresine yönlendirilir. Google ağ altyapısı, kullanıcının trafiğini otomatik olarak en düşük gecikme süresine sahip ve sağlıklı çalışan en yakın GKE kümesine iletir.
Bu mimariyi yönetmek için Git depolarımızı şu şekilde yapılandıracağız: Tek bir “uygulama” depomuz olacak. Bu depodaki değişiklikler, GitOps aracımız (örneğin ArgoCD) tarafından algılanacak ve 10 farklı GKE kümesine aynı anda, ancak her kümenin kendi özel parametreleriyle dağıtılacaktır.
Uygulamalı Rehber: Kustomize ile DRY İlkesi Nasıl Uygulanır?
Şimdi teoriyi pratiğe dökelim. Projemizin klasör yapısını oluşturarak işe başlıyoruz. Kustomize’ın gücü, ortak yapılandırmaları base klasöründe tutup, bölgeye özel değişiklikleri overlays altında tanımlamasından gelir.
Aşağıdaki dizin yapısını oluşturun:
├── base/
│ ├── deployment.yaml
│ ├── service.yaml
│ └── kustomization.yaml
└── overlays/
├── europe-west3/
│ └── kustomization.yaml
├── us-central1/
│ └── kustomization.yaml
└── asia-east1/
└── kustomization.yaml
İlk olarak, tüm bölgelerde ortak olacak temel API deployment (dağıtım) dosyamızı (base/deployment.yaml) tanımlayalım:
apiVersion: apps/v1
kind: Deployment
metadata:
name: realtime-api
spec:
replicas: 3
selector:
matchLabels:
app: realtime-api
template:
metadata:
labels:
app: realtime-api
spec:
containers:
- name: api-container
image: gcr.io/my-project/realtime-api:v1.0.0
ports:
- containerPort: 8080
env:
- name: REGION
value: "default"
- name: DB_HOST
value: "global-db-proxy"
Şimdi bu taban yapılandırmayı Kustomize’a tanıtmak için base/kustomization.yaml dosyasını oluşturalım:
resources:
- deployment.yaml
- service.yaml
Buraya kadar her şey standart. Şimdi sihirli kısma geliyoruz. Almanya (Frankfurt) bölgesi (europe-west3) için hiçbir YAML dosyasını kopyalamadan, sadece farklı olan değerleri tanımlayacağız. overlays/europe-west3/kustomization.yaml dosyasını şu şekilde düzenleyin:
resources:
- ../../base
patches:
- target:
kind: Deployment
name: realtime-api
patch: |-
- op: replace
path: /spec/replicas
value: 10
- op: replace
path: /spec/template/spec/containers/0/env/0/value
value: "europe-west3"
- op: replace
path: /spec/template/spec/containers/0/env/1/value
value: "eu-db.internal"
Bu yapılandırma sayesinde, Avrupa bölgesindeki kümemiz için replika sayısı otomatik olarak 10’a çıkarılacak, bölge adı ve veritabanı adresi o bölgeye özel olarak güncellenecektir. Diğer 9 bölge için de benzer şekilde sadece küçük yama (patch) dosyaları oluşturarak manifest kirliliğinin tamamen önüne geçebilirsiniz.
Gerçek Zamanlı Trafik Yönetimi: Multi-Cluster Gateway Nasıl Yapılandırılır?
Manifestlerimizi hazırladık ve bölgelere özel hale getirdik. Peki, küresel kullanıcı trafiğini bu 10 bölgeye nasıl dinamik olarak dağıtacağız? Google Cloud’un Multi-Cluster Gateway (Çoklu Küme Geçidi) özelliğini kullanarak bunu gerçekleştirebiliriz.
Öncelikle, küresel yük dengeleyicimizi tanımlayan bir Gateway kaynağı oluşturmamız gerekiyor. Bu kaynak, tüm bölgelerdeki GKE kümelerimizin önünde tek bir giriş kapısı olarak görev yapacaktır:
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: global-api-gateway
namespace: multi-cluster-gateways
annotations:
networking.gke.io/cert-tracker: "true"
spec:
gatewayClassName: gke-l7-global-external-managed-mc
listeners:
- name: https
protocol: HTTPS
port: 443
tls:
mode: Terminate
certificateRefs:
- name: api-global-cert
Bu Gateway tanımı, Google Cloud üzerinde küresel bir HTTPS yük dengeleyici oluşturur. Şimdi, gelen istekleri hangi servislerimize yönlendireceğimizi belirleyen HTTPRoute kaynağını tanımlayalım:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: realtime-api-route
namespace: default
spec:
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: global-api-gateway
namespace: multi-cluster-gateways
rules:
- backendRefs:
- group: ""
kind: Service
name: realtime-api
port: 8080
Bu yapılandırma sayesinde, Google’ın küresel yük dengeleyicisi 10 bölgedeki realtime-api servislerinin sağlık durumunu (health check) sürekli izler. Eğer Asya’daki bir kümede arıza yaşanırsa, o bölgedeki trafik otomatik ve kesintisiz olarak en yakın çalışan bölgeye aktarılır.
Vaka Analizi: Türkiye Merkezli Bir Fintek Şirketinin Küresel Başarı Hikayesi
Teorik bilginin ötesine geçmek için, gerçek bir başarı hikayesine göz atalım. Türkiye merkezli bir finansal teknoloji (fintek) girişimi olan “ParaYol”, Avrupa, Orta Doğu ve Asya-Pasifik bölgelerindeki kullanıcılara gerçek zamanlı döviz kuru ve para transferi API’si sunmaktadır.
Başlangıçta ParaYol, sadece 3 farklı bölgede manuel olarak kopyalanmış Kubernetes manifestleri ile hizmet veriyordu. Şirket küresel olarak büyüdükçe ve bölge sayısı 10’a ulaştığında, operasyonel süreçler tıkanma noktasına geldi. Yeni bir API sürümü yayınlamak tam 4 saat sürüyordu ve her dağıtımda en az bir bölgede yapılandırma hatası nedeniyle kesinti yaşanıyordu. Türkiye’deki mühendislik ekibi, geceleri farklı saat dilimlerindeki sistemleri ayakta tutmak için nöbet tutmak zorunda kalıyordu.
ParaYol mühendisleri, bu makalede anlattığımız mimariyi uygulamaya karar verdiler:
- Tüm Kubernetes altyapısını GKE Enterprise (Anthos) altında birleştirdiler.
- Kustomize kullanarak 120 farklı YAML dosyasını tek bir
baseve 10 adet küçükoverlaydosyasına indirdiler. - Multi-Cluster Gateway entegrasyonu ile küresel gecikme sürelerini (latency) optimize ettiler.
Sonuçlar oldukça çarpıcıydı. Yeni bir sürümün tüm dünyada yayına alınma süresi 4 saatten sadece 5 dakikaya düştü. En önemlisi, insan kaynaklı yapılandırma hataları sıfıra indi. Türkiye’deki kullanıcılar için gecikme süresi zaten düşüktü ancak bu mimari sayesinde Tokyo ve New York’taki kullanıcıların API yanıt süreleri de ortalama 320ms’den 28ms’ye geriledi.
İleri Düzey İpuçları: ArgoCD ApplicationSet ile Otomasyon
Kustomize ile manifestlerimizi sadeleştirdik ancak hala 10 farklı küme için ArgoCD üzerinde ayrı ayrı “Application” (Uygulama) tanımlamak zorunda kalabiliriz. Bu da başka bir kod tekrarı doğurur. Bu sorunu çözmek için ArgoCD’nin ApplicationSet özelliğini kullanabiliriz.
ApplicationSet, tek bir şablon kullanarak dinamik olarak birden fazla ArgoCD uygulaması oluşturmanızı sağlar. Aşağıdaki örnek, Git deponuzdaki klasörleri veya tanımladığınız bir listeyi tarayarak 10 bölgeye otomatik dağıtım gerçekleştirir:
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: realtime-api-regions
namespace: argocd
spec:
generators:
- list:
elements:
- cluster: europe-west3-cluster
region: europe-west3
- cluster: us-central1-cluster
region: us-central1
- cluster: asia-east1-cluster
region: asia-east1
template:
metadata:
name: '{{region}}-realtime-api'
spec:
project: default
source:
repoURL: 'https://github.com/parayol/gitops-infra.git'
targetRevision: HEAD
path: 'overlays/{{region}}'
destination:
name: '{{cluster}}'
namespace: default
syncPolicy:
automated:
prune: true
selfHeal: true
Bu ApplicationSet sayesinde, listeye yeni bir bölge eklediğiniz anda ArgoCD otomatik olarak o bölgedeki GKE kümesine bağlanır, Kustomize overlay dosyasını okur ve uygulamayı saniyeler içinde ayağa kaldırır. Artık 10 değil, 100 bölgeniz olsa bile tek bir satır kod değiştirmeden altyapınızı ölçekleyebilirsiniz.
Sonuç ve Sıkça Sorulan Sorular
Küresel ölçekte gerçek zamanlı bir API çalıştırmak, sadece güçlü sunuculara sahip olmakla ilgili değildir; bu altyapıyı nasıl yönettiğinizle doğrudan ilgilidir. GKE, Kustomize ve GitOps prensiplerini bir araya getirerek, kod tekrarı yapmadan, hata payını en aza indirerek ve operasyonel maliyetleri düşürerek 10 global bölgede stabil bir sistem kurabilirsiniz.
Bu makalede öğrendiğiniz yöntemler, karmaşık mikroservis mimarilerinizi yönetirken size hız ve güven kazandıracaktır. Unutmayın, en iyi kod yazılmamış koddur; en iyi manifest ise tekrar edilmemiş manifesttir.
Sıkça Sorulan Sorular
1. Kustomize yerine neden Helm kullanmıyoruz?
Helm, parametreleştirmek için şablonlama (templating) kullanır ve bu durum çok büyük projelerde okunabilirliği zorlaştırabilir. Kustomize ise saf Kubernetes YAML dosyalarıyla çalışır. Ancak, her iki aracı birlikte de kullanabilirsiniz; Helm ile paketlediğiniz uygulamaları Kustomize ile bölgelere göre yamalayabilirsiniz.
2. Multi-Cluster Gateway kullanmanın ek maliyeti nedir?
Multi-Cluster Gateway, Google Cloud’un GKE Enterprise (Anthos) lisanslamasına veya kullandığınız yük dengeleyici (load balancer) kaynaklarının saatlik ücretlendirmesine tabidir. 10 ayrı yük dengeleyici oluşturmak yerine tek bir küresel geçit kullanmak genellikle ağ trafiği optimizasyonu sağladığı için uzun vadede daha maliyet etkindir.
3. Bölgeler arasındaki veritabanı senkronizasyonunu nasıl çözebiliriz?
Gerçek zamanlı API’lerde veri tabanı kritik bir rol oynar. Google Cloud Spanner veya tamamen yönetilen çok bölgeli (multi-region) Cloud SQL gibi küresel olarak aktif-aktif (active-active) çalışan veritabanı çözümlerini tercih ederek gecikme süresini en aza indirebilirsiniz.
4. Yeni bir bölge eklemek ne kadar sürer?
Bu mimari kurulduktan sonra, yeni bir bölge eklemek sadece overlays klasörü altında yeni bir bölge adı oluşturup (örn: us-east4) ArgoCD ApplicationSet listesine bu bölgeyi eklemekten ibarettir. Bu işlem yaklaşık 2 dakika sürer.
#Kubernetes #GKE #GitOps #Kustomize #CloudComputing