Cloud Native ve Sunucusuz Mimariler: Bulutun Gücünden Tam Verimle Yararlanmak
Günümüzde yazılım geliştirme, sadece kod yazmaktan ibaret değil; aynı zamanda uygulamaları bulutta nasıl çalıştıracağınızı, ölçeklendireceğinizi ve yöneteceğinizi de kapsıyor. Cloud Native (Bulut Yerel), uygulamaların bulut ortamının avantajlarından (ölçeklenebilirlik, dayanıklılık, esneklik) tam olarak yararlanacak şekilde tasarlanması ve çalıştırılmasıdır.【1†L4-L6】Serverless (Sunucusuz) ise bu yaklaşımın bir adım ötesine geçerek, altyapı yönetimini tamamen bulut sağlayıcısına bırakır ve geliştiricilerin sadece kod yazmaya odaklanmasını sağlar.【2†L4-L6】
1. Cloud Native Nedir? (Temel Prensipler)
Cloud Native, bir uygulamanın bulut ortamında dinamik, ölçeklenebilir ve dayanıklı olmasını sağlayan bir dizi prensip ve teknolojiden oluşur. Bu prensipler, 12-Factor App metodolojisi ile özetlenir.【1†L8-L10】
12-Factor App Prensipleri (Özet):
-
Tek Bir Kod Tabanı (Codebase): Her servis için tek bir kod tabanı, birden fazla deploy ortamı.
-
Bağımlılıkları Açıkça Beyan Etme (Dependencies): Bağımlılıkları açıkça tanımlayın ve yönetin.
-
Konfigürasyonu Ortamdan Ayırma (Config): Konfigürasyonu kod dışında, ortam değişkenlerinde saklayın.
-
Arka Plan Hizmetleri (Backing Services): Veritabanı, cache, message broker gibi hizmetleri bağımsız ve değiştirilebilir kaynaklar olarak ele alın.
-
Build, Release, Run Ayrımı: Bu üç aşamayı kesinlikle ayırın.
-
Stateless Süreçler (Processes): Uygulama süreçleri durumsuz (stateless) olmalıdır.
-
Port Binding: Hizmetleri bağlantı noktalarına (port) bağlayarak sunun.
-
Concurrency: Süreçleri yatayda ölçeklendirerek eşzamanlılığı yönetin.
-
Disposability (Atılabilirlik): Süreçler hızlı başlamalı ve düzgün kapanmalıdır (graceful shutdown).
-
Dev/Prod Parity: Geliştirme, staging ve production ortamlarını olabildiğince benzer tutun.
-
Logs (Günlükler): Logları olay akışı (event stream) olarak ele alın.
-
Admin Processes (Yönetici Süreçleri): Veri taşıma (migration) gibi işlemleri ayrı bir süreç olarak çalıştırın.
2. Container Orchestration (Konteyner Orkestrasyonu)
Cloud Native uygulamaların bel kemiği, container (konteyner) teknolojisidir (Docker). Konteynerlar, uygulamayı ve bağımlılıklarını izole edilmiş bir ortamda paketler. Ancak, onlarca veya yüzlerce konteyneri manuel olarak yönetmek imkânsızdır. İşte bu noktada container orchestration araçları devreye girer.
Kubernetes: Endüstri standardı container orchestration platformudur.【3†L6-L9】
-
Otomatik Ölçeklendirme: CPU veya özel metriklerine göre pod sayısını otomatik artırıp azaltır.
-
Kendi Kendini İyileştirme (Self-Healing): Başarısız pod'ları yeniden başlatır, sağlıksız pod'ları değiştirir.
-
Servis Keşfi ve Yük Dengeleme: Servisleri birbirine bağlar ve trafiği dengeler.
-
Rolling Update / Rollback: Yeni sürümleri kademeli olarak (zero-downtime) yayınlar ve hata durumunda geri alır.
-
Secret ve Configuration Yönetimi: Hassas bilgileri (parola, token) güvenle yönetir.
.NET ile Kubernetes'te Çalışma:
dockerfile
# Dockerfile FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base WORKDIR /app EXPOSE 80 FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build WORKDIR /src COPY ["MyApp.csproj", "."] RUN dotnet restore COPY . . RUN dotnet build -c Release -o /app/build FROM build AS publish RUN dotnet publish -c Release -o /app/publish FROM base AS final WORKDIR /app COPY --from=publish /app/publish . ENTRYPOINT ["dotnet", "MyApp.dll"]
yaml
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deployment
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myregistry/myapp:latest
ports:
- containerPort: 80
env:
- name: ConnectionStrings__Default
valueFrom:
secretKeyRef:
name: db-secret
key: connection-string
---
apiVersion: v1
kind: Service
metadata:
name: myapp-service
spec:
selector:
app: myapp
ports:
- protocol: TCP
port: 80
targetPort: 80
type: LoadBalancer
Horizontal Pod Autoscaler (HPA):
yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: myapp-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: myapp-deployment
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
3. Serverless (Sunucusuz) Mimariler
Serverless, bulut sağlayıcısının altyapıyı (sunucular, ölçeklendirme, kapasite planlaması) tamamen yönettiği, geliştiricilerin sadece kod yazmaya odaklandığı bir modeldir.【2†L4-L6】FaaS (Function as a Service), serverless'ın en yaygın uygulama şeklidir.
Temel Özellikler:
-
Event-Driven (Olay Tabanlı): Fonksiyonlar, bir HTTP isteği, kuyruk mesajı, zamanlayıcı veya dosya yükleme gibi olaylar (events) tarafından tetiklenir.
-
Otomatik Ölçeklendirme: Gelen istek hacmine göre otomatik olarak ölçeklenir (sıfırdan binlere).
-
Kullanım Başına Ödeme (Pay-per-use): Sadece fonksiyon çalıştığı süre (ve işlem gücü) için ödeme yapılır.
-
Altyapı Yönetimi Yok: Sunucu kurulumu, bakımı, güvenlik yamaları tamamen sağlayıcı tarafından yapılır.
Popüler Serverless Platformları:
-
Azure Functions: .NET ile en iyi entegrasyonu sunar.
-
AWS Lambda: En olgun ve yaygın kullanılan platformdur.
-
Google Cloud Functions: Google Cloud ekosistemi ile entegredir.
Azure Functions ile .NET Örneği:
csharp
// HTTP Tetiklemeli Function
[FunctionName("HttpTriggerFunction")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
string name = req.Query["name"];
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
name = name ?? data?.name;
return name != null
? (ActionResult)new OkObjectResult($"Hello, {name}")
: new BadRequestObjectResult("Please pass a name on the query string or in the request body");
}
csharp
// Queue Tetiklemeli Function
[FunctionName("QueueTriggerFunction")]
public static void Run(
[QueueTrigger("myqueue-items", Connection = "AzureWebJobsStorage")] string myQueueItem,
ILogger log)
{
log.LogInformation($"C# Queue trigger function processed: {myQueueItem}");
}
csharp
// Timer Tetiklemeli Function (Zamanlayıcı)
[FunctionName("TimerTriggerFunction")]
public static void Run(
[TimerTrigger("0 */5 * * * *")] TimerInfo myTimer, // Her 5 dakikada bir
ILogger log)
{
log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
}
4. Durable Functions (Stateful Serverless)
Serverless fonksiyonlar genelde durumsuz (stateless) olsa da, Durable Functions, state'li (durumlu) ve uzun süren iş akışlarını serverless ortamda yönetmenizi sağlar.【4†L6-L9】
Kullanım Senaryoları:
-
SAGA Pattern: Dağıtık işlemlerde (distributed transactions) eventual consistency sağlamak.
-
İnsan Onayı (Human Approval): Bir iş akışında beklenmesi gereken adımlar (ör. yönetici onayı).
-
Uzun Süren İşlemler: Saatlerce veya günlerce süren iş akışları.
csharp
[FunctionName("OrderOrchestrator")]
public static async Task<List<string>> RunOrchestrator(
[OrchestrationTrigger] IDurableOrchestrationContext context)
{
var orderId = context.GetInput<string>();
// 1. Ödemeyi işle
var paymentResult = await context.CallActivityAsync<bool>("ProcessPayment", orderId);
if (!paymentResult)
{
// Ödeme başarısız, sipariş iptal et
await context.CallActivityAsync("CancelOrder", orderId);
return new List<string> { "Payment failed, order cancelled." };
}
// 2. Stok rezervasyonu yap
var stockResult = await context.CallActivityAsync<bool>("ReserveStock", orderId);
if (!stockResult)
{
// Stok yok, ödemeyi iade et
await context.CallActivityAsync("RefundPayment", orderId);
await context.CallActivityAsync("CancelOrder", orderId);
return new List<string> { "Out of stock, order cancelled and payment refunded." };
}
// 3. Kargo oluştur
await context.CallActivityAsync("CreateShipment", orderId);
// 4. Sipariş tamamlandı
await context.CallActivityAsync("CompleteOrder", orderId);
return new List<string> { "Order completed successfully!" };
}
5. Serverless vs. Containers: Ne Zaman Hangisi?
| Kriter | Serverless (Azure Functions / AWS Lambda) | Containers (Azure Container Instances / Kubernetes) |
|---|---|---|
| Ölçeklenebilirlik | Otomatik, anlık (sıfırdan binlere) | Manuel veya otomatik (HPA), daha yavaş |
| Maliyet | Kullanım başına ödeme (çalışma süresi) | 7/24 çalışan kaynaklar için sabit maliyet |
| Başlangıç Süresi (Cold Start) | İlk çağrıda gecikme (cold start) olabilir | Her zaman sıcak (hot), sıfır gecikme |
| Altyapı Kontrolü | Sınırlı (sağlayıcıya bağlı) | Tam kontrol (OS, network, güvenlik) |
| Uzun Süren İşlemler | Timeout limitleri var (Azure'da 10 dakika) | Sınırsız (uygulama kontrolünde) |
| State Yönetimi | Stateless, Durable Functions ile state'li | State'li veya state'siz uygulama |
| .NET Uyumluluğu | .NET 8, 9, 10 desteği (Azure Functions) | Tam .NET desteği |
| Kullanım Senaryosu | Event-driven, API'ler, background işlemler | Karmaşık, uzun süren, özel altyapı gerektiren işler |
6. .NET ile Cloud Native Uygulama Geliştirme İpuçları
-
12-Factor App Prensiplerini Uygulayın: Konfigürasyonu (
appsettings.jsonyerine environment variables), loglamayı (Serilog, OpenTelemetry) ve bağımlılıkları doğru yönetin. -
Health Checks (Sağlık Kontrolleri): Uygulamanızın durumunu izlemek için
/healthendpoint'i ekleyin.csharp
builder.Services.AddHealthChecks() .AddDbContextCheck<AppDbContext>() .AddUrlGroup(new Uri("https://api.example.com"), "External API"); -
Distributed Caching: Redis ile önbellekleme yaparak veritabanı yükünü azaltın.
-
Resilience (Dayanıklılık): Polly ile retry, circuit breaker, timeout politikaları uygulayın.
-
Observability (Gözlemlenebilirlik): OpenTelemetry ile metrics, logging ve distributed tracing entegrasyonu yapın.
-
Container Image Optimizasyonu: Docker image'larınızı küçük ve güvenli tutun (Alpine tabanlı, çok aşamalı build).
-
CI/CD Pipeline: GitHub Actions, Azure DevOps veya GitLab CI ile otomatik build, test ve deploy pipeline'ı oluşturun.
Sonuç:
Cloud Native ve Serverless mimariler, modern yazılım geliştirmenin geleceğini şekillendiriyor. Cloud Native, uygulamalarınızı bulutun gücünden tam olarak yararlanacak şekilde tasarlamanızı sağlarken; Serverless, altyapı yönetimini tamamen ortadan kaldırarak geliştiricilerin sadece kod yazmaya odaklanmasına olanak tanır.
.NET ekosistemi, her iki yaklaşım için de zengin araçlar sunar: Kubernetes ile container orchestration, Azure Functions ile serverless, Durable Functions ile state'li iş akışları. Doğru stratejiyi seçmek, uygulamanızın ihtiyaçlarına, maliyet hedeflerine ve ekip yetkinliklerine bağlıdır. Unutmayın: Bulut, sadece bir hosting ortamı değil, uygulama mimarinizin ayrılmaz bir parçasıdır.