yazılar

Konteyneri Buluta Taşımak: ECR, ECS Fargate ve ALB

Docker · AWS · ECS · Fargate · ECR · ALB · DevOps

Eğitim sunumuna erişmek için → Ders 3 Slaytları Kaynak kod & sunumlargithub.com/Kaangml/docker-egitimi

Nereye Gidiyoruz?

Önceki derste local’de çalışan bir FastAPI imajı vardı: docker build, docker run, docker compose. Şimdi o imajı gerçek bir URL’e taşıyoruz — herkesin erişebileceği, yük altında ölçeklenebilen, sunucu yönetmek zorunda olmadığımız bir ortama.

Yol şu: ECR → ECS + Fargate → ALB → Public URL

AWS Konteyner Ekosistemi

Önce haritayı anlamak gerekiyor. Hangi servis ne işe yarıyor?

AWS Servisi Ne yapar? Docker karşılığı
ECR (Elastic Container Registry) Private image deposu Docker Hub (özel)
ECS (Elastic Container Service) Container çalıştırma ve yönetimi docker run otomatik
Fargate Sunucu yönetmeden container çalıştır EC2 olmadan Docker
ALB (Application Load Balancer) İstekleri container’lara dağıt Nginx (yönetilen)

Neden Fargate seçiyoruz? Alternatif EC2’dur — sunucu kiralarsın, üstüne Docker kurarsın, patch’lerini takip edersin. Fargate’de bunların hiçbiri yok; AWS altyapıyı halleder, sen sadece container konfigürasyonunu tarif edersin.

Adım 1: ECR’ye Push

İmajı önce AWS’nin private registry’sine göndermek gerekiyor. ECS oradan çekecek.

# Repository oluştur
aws ecr create-repository \
  --repository-name image-classifier-api \
  --region eu-central-1

# AWS kimlik bilgisiyle Docker'a login ol
aws ecr get-login-password --region eu-central-1 | \
  docker login --username AWS \
  --password-stdin \
  $ACCOUNT.dkr.ecr.eu-central-1.amazonaws.com

# İmajı tag'le ve push et
docker tag image-classifier-api:latest \
  $ACCOUNT.dkr.ecr.eu-central-1.amazonaws.com/image-classifier-api:latest

docker push \
  $ACCOUNT.dkr.ecr.eu-central-1.amazonaws.com/image-classifier-api:latest

ACCOUNT değeri AWS hesap ID’n. aws sts get-caller-identity --query Account --output text ile öğrenebilirsin.

ECR’nin Docker Hub’dan farkı: IAM tabanlı erişim kontrolü ve KMS şifrelemesi. İmaj public değil; sadece doğru izinlere sahip servisler çekebilir.

Adım 2: ECS Kavramlarını Anlamak

ECS’te dört kavram var, hiyerarşik:

  • Cluster — container’ların çalışacağı ortam (Fargate veya EC2)
  • Task Definition — container’ın tarifnamesi: hangi imaj, kaç CPU, kaç RAM, hangi port, hangi env var’lar
  • Task — Task Definition’dan ayağa kalkmış çalışan bir örnek
  • Service — “Bu Task Definition’dan her zaman N tane çalışsın” kuralı

Service’in güçlü yanı şu: bir Task çöktüğünde Service onu fark edip yenisini başlatır. Desired count’u 2 tuttuğunda daima 2 Task ayakta olmaya çalışır.

Adım 3: Task Definition

Task Definition bir JSON belgesidir. AWS Console’dan form doldurarak da oluşturulabilir, ama CLI ile daha net görünüyor:

aws ecs register-task-definition \
  --family image-classifier-api \
  --requires-compatibilities FARGATE \
  --network-mode awsvpc \
  --cpu 1024 --memory 2048 \
  --container-definitions '[
    {
      "name": "image-classifier-api",
      "image": "'$ECR_URI'/image-classifier-api:latest",
      "portMappings": [{"containerPort": 8080}],
      "environment": [
        {"name": "S3_BUCKET", "value": "my-images-bucket"}
      ]
    }
  ]'

cpu: 1024 = 1 vCPU, memory: 2048 = 2 GB RAM. Fargate bu değerler üzerinden faturalandırır — task çalıştığı sürece, kullanıyor olsan da olmasan da.

network-mode: awsvpc Fargate’de zorunlu. Her task’a ayrı bir elastic network interface ve özel IP verilir.

Adım 4: Service ve ALB

Service oluştururken ALB’yi de bağlıyoruz. Trafiği task’lara bölen bu katmandır.

aws ecs create-service \
  --cluster image-classifier-api-cluster \
  --service-name image-classifier-api-service \
  --task-definition image-classifier-api \
  --desired-count 2 \
  --launch-type FARGATE \
  --load-balancers targetGroupArn=$TG_ARN,containerName=image-classifier-api,containerPort=8080

Security Group ayarı kritik: ALB’nin container’lara ulaşabilmesi için inbound kuralları doğru olmalı.

Kaynak Port Açıklama
0.0.0.0/0 80 ALB’ye dışarıdan gelen trafik
ALB Security Group 8080 ALB’den container’a gelen trafik

Ölçekleme

Service’i güncelleyerek anında yatay ölçekleme yapılabilir:

# 5 task'a çıkar
aws ecs update-service \
  --cluster image-classifier-api-cluster \
  --service image-classifier-api-service \
  --desired-count 5

# Mevcut durumu kontrol et
aws ecs describe-services \
  --cluster image-classifier-api-cluster \
  --services image-classifier-api-service

ALB gelen istekleri mevcut task’lar arasında round-robin ile dağıtır. Yeni task’lar ayağa kalktıkça otomatik olarak ALB’nin hedef grubuna eklenir.

Canlı Test

ALB DNS alındıktan sonra:

curl -X POST http://ALB_DNS/predict -F "[email protected]"

Yanıt:

{
  "result": true,
  "skor": 0.94,
  "s3_key": "uploads/..."
}

curl her seferinde farklı bir task’a gidebilir. CloudWatch Logs → Log Groups → task loglarını izleyerek hangi task’ın cevap verdiğini görebilirsin.

Maliyet ve Temizlik

Demo için tahmini maliyet:

Kaynak Birim maliyet
Fargate (1 vCPU, 2 GB) × 2 task ~$0.10/saat
ALB ~$0.02/saat
ECR (500 MB imaj) ~$0.05/ay
Toplam ~$0.12/saat

3 saatlik demo ≈ $0.40. Bırakılırsa birikir — demodan sonra mutlaka silin:

# 1. Service'i durdur (desired count = 0)
aws ecs update-service \
  --cluster image-classifier-api-cluster \
  --service image-classifier-api-service \
  --desired-count 0

# 2. Service sil
aws ecs delete-service \
  --cluster image-classifier-api-cluster \
  --service image-classifier-api-service

# 3. Cluster sil
aws ecs delete-cluster --cluster image-classifier-api-cluster

# 4. ECR repository sil
aws ecr delete-repository \
  --repository-name image-classifier-api --force

Local vs AWS: Ne Değişti?

Local:   docker run → localhost:8000
AWS:     ECR push → ECS Task → ALB → public URL

Mimari aynı: bir container, bir port, bir API. Fark altyapıda: AWS artık yeniden başlatmayı, yük dağıtımını ve network yönetimini hallediyor. Container’ın içinden bakınca hiçbir şey değişmedi.