Container Services (ECS/EKS/Fargate vs GKE/Cloud Run)

Container Services (ECS/EKS/Fargate vs GKE/Cloud Run)

1. Container Overview

1.1 Container vs VM

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   Virtual Machine (VM)                      β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”                        β”‚
β”‚  β”‚  App A  β”‚ β”‚  App B  β”‚ β”‚  App C  β”‚                        β”‚
β”‚  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€                        β”‚
β”‚  β”‚Guest OS β”‚ β”‚Guest OS β”‚ β”‚Guest OS β”‚  ← OS per VM          β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                        β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚
β”‚  β”‚                    Hypervisor                           β”‚β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚
β”‚  β”‚                    Host OS                              β”‚β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                       Container                             β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”                        β”‚
β”‚  β”‚  App A  β”‚ β”‚  App B  β”‚ β”‚  App C  β”‚                        β”‚
β”‚  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€                        β”‚
β”‚  β”‚  Libs   β”‚ β”‚  Libs   β”‚ β”‚  Libs   β”‚  ← Libraries only     β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                        β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚
β”‚  β”‚                  Container Runtime                      β”‚β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚
β”‚  β”‚                    Host OS                              β”‚β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

1.2 Service Comparison

Category AWS GCP
Container Registry ECR Artifact Registry
Container Orchestration ECS -
Managed Kubernetes EKS GKE
Serverless Containers Fargate Cloud Run
App Platform App Runner Cloud Run

2. Container Registry

2.1 AWS ECR (Elastic Container Registry)

# 1. ECR λ ˆν¬μ§€ν† λ¦¬ 생성
aws ecr create-repository \
    --repository-name my-app \
    --region ap-northeast-2

# 2. Docker 둜그인
aws ecr get-login-password --region ap-northeast-2 | \
    docker login --username AWS --password-stdin \
    123456789012.dkr.ecr.ap-northeast-2.amazonaws.com

# 3. 이미지 λΉŒλ“œ 및 νƒœκ·Έ
docker build -t my-app .
docker tag my-app:latest \
    123456789012.dkr.ecr.ap-northeast-2.amazonaws.com/my-app:latest

# 4. 이미지 ν‘Έμ‹œ
docker push 123456789012.dkr.ecr.ap-northeast-2.amazonaws.com/my-app:latest

# 5. 이미지 λͺ©λ‘ 확인
aws ecr list-images --repository-name my-app

2.2 GCP Artifact Registry

# 1. Artifact Registry API ν™œμ„±ν™”
gcloud services enable artifactregistry.googleapis.com

# 2. λ ˆν¬μ§€ν† λ¦¬ 생성
gcloud artifacts repositories create my-repo \
    --repository-format=docker \
    --location=asia-northeast3 \
    --description="My Docker repository"

# 3. Docker 인증 μ„€μ •
gcloud auth configure-docker asia-northeast3-docker.pkg.dev

# 4. 이미지 λΉŒλ“œ 및 νƒœκ·Έ
docker build -t my-app .
docker tag my-app:latest \
    asia-northeast3-docker.pkg.dev/PROJECT_ID/my-repo/my-app:latest

# 5. 이미지 ν‘Έμ‹œ
docker push asia-northeast3-docker.pkg.dev/PROJECT_ID/my-repo/my-app:latest

# 6. 이미지 λͺ©λ‘ 확인
gcloud artifacts docker images list \
    asia-northeast3-docker.pkg.dev/PROJECT_ID/my-repo

3. AWS ECS (Elastic Container Service)

3.1 ECS Concepts

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                        ECS Cluster                          β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚
β”‚  β”‚                      Service                            β”‚β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                   β”‚β”‚
β”‚  β”‚  β”‚    Task       β”‚  β”‚    Task       β”‚  ← Container groupβ”‚β”‚
β”‚  β”‚  β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚  β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚                   β”‚β”‚
β”‚  β”‚  β”‚ β”‚ Container β”‚ β”‚  β”‚ β”‚ Container β”‚ β”‚                   β”‚β”‚
β”‚  β”‚  β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚  β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚                   β”‚β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                   β”‚β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”               β”‚
β”‚  β”‚ EC2 Instance      β”‚  β”‚ Fargate           β”‚               β”‚
β”‚  β”‚ (self-managed)    β”‚  β”‚ (serverless)      β”‚               β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜               β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

3.2 Creating an ECS Cluster

# 1. Create cluster (Fargate)
aws ecs create-cluster \
    --cluster-name my-cluster \
    --capacity-providers FARGATE FARGATE_SPOT

# 2. Create Task Definition
# task-definition.json
{
    "family": "my-task",
    "networkMode": "awsvpc",
    "requiresCompatibilities": ["FARGATE"],
    "cpu": "256",
    "memory": "512",
    "executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
    "containerDefinitions": [
        {
            "name": "my-container",
            "image": "123456789012.dkr.ecr.ap-northeast-2.amazonaws.com/my-app:latest",
            "essential": true,
            "portMappings": [
                {
                    "containerPort": 80,
                    "protocol": "tcp"
                }
            ],
            "logConfiguration": {
                "logDriver": "awslogs",
                "options": {
                    "awslogs-group": "/ecs/my-task",
                    "awslogs-region": "ap-northeast-2",
                    "awslogs-stream-prefix": "ecs"
                }
            }
        }
    ]
}

aws ecs register-task-definition --cli-input-json file://task-definition.json

# 3. Create service
aws ecs create-service \
    --cluster my-cluster \
    --service-name my-service \
    --task-definition my-task:1 \
    --desired-count 2 \
    --launch-type FARGATE \
    --network-configuration "awsvpcConfiguration={subnets=[subnet-xxx],securityGroups=[sg-xxx],assignPublicIp=ENABLED}"

3.3 ECS Service Connect

ECS Service Connect provides built-in service mesh capabilities for service-to-service communication without requiring a separate proxy or service mesh setup.

// Service definition with Service Connect
{
    "cluster": "my-cluster",
    "serviceName": "backend-service",
    "taskDefinition": "backend-task:1",
    "serviceConnectConfiguration": {
        "enabled": true,
        "namespace": "my-app-namespace",
        "services": [
            {
                "portName": "http",
                "discoveryName": "backend",
                "clientAliases": [
                    {
                        "port": 80,
                        "dnsName": "backend.local"
                    }
                ]
            }
        ]
    },
    "desiredCount": 2,
    "launchType": "FARGATE",
    "networkConfiguration": {
        "awsvpcConfiguration": {
            "subnets": ["subnet-xxx"],
            "securityGroups": ["sg-xxx"]
        }
    }
}

Key Benefits: - Built-in service discovery (AWS Cloud Map integration) - Automatic load balancing between services - Traffic metrics and observability without additional agents - No need for external service mesh (Istio, Consul)

3.4 ECS Exec (Container Debugging)

ECS Exec allows interactive shell access to running containers for debugging.

# Enable ECS Exec on a service
aws ecs update-service \
    --cluster my-cluster \
    --service my-service \
    --enable-execute-command

# Start an interactive shell session
aws ecs execute-command \
    --cluster my-cluster \
    --task TASK_ID \
    --container my-container \
    --interactive \
    --command "/bin/sh"

# Run a one-off command
aws ecs execute-command \
    --cluster my-cluster \
    --task TASK_ID \
    --container my-container \
    --command "cat /app/config.json"

Note: ECS Exec requires the task role to have ssmmessages permissions and the task definition must include initProcessEnabled: true.


4. AWS EKS (Elastic Kubernetes Service)

4.1 Creating an EKS Cluster

# 1. Install eksctl (macOS)
brew install eksctl

# 2. ν΄λŸ¬μŠ€ν„° 생성
eksctl create cluster \
    --name my-cluster \
    --region ap-northeast-2 \
    --nodegroup-name my-nodes \
    --node-type t3.medium \
    --nodes 2 \
    --nodes-min 1 \
    --nodes-max 4

# 3. kubeconfig μ—…λ°μ΄νŠΈ
aws eks update-kubeconfig --name my-cluster --region ap-northeast-2

# 4. ν΄λŸ¬μŠ€ν„° 확인
kubectl get nodes

4.2 EKS Auto Mode

EKS Auto Mode (launched late 2024) simplifies EKS by automating node management, similar to GKE Autopilot.

# Create an EKS cluster with Auto Mode
eksctl create cluster \
    --name my-auto-cluster \
    --region ap-northeast-2 \
    --auto-mode

# Or enable Auto Mode on an existing cluster
aws eks update-cluster-config \
    --name my-cluster \
    --compute-config enabled=true \
    --kubernetes-network-config '{"elasticLoadBalancing":{"enabled":true}}' \
    --storage-config '{"blockStorage":{"enabled":true}}'
Feature EKS Standard EKS Auto Mode
Node Provisioning Manual (managed node groups or Karpenter) Automatic
Node OS Updates User-managed AWS-managed
Load Balancer Install AWS LB Controller Built-in
Storage (EBS CSI) Install EBS CSI driver Built-in
Billing EC2 instance-based Pod resource-based (with overhead)
Best For Fine-grained control Simplified operations

4.3 Deploying Applications

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app
        image: 123456789012.dkr.ecr.ap-northeast-2.amazonaws.com/my-app:latest
        ports:
        - containerPort: 80
        resources:
          requests:
            memory: "128Mi"
            cpu: "250m"
          limits:
            memory: "256Mi"
            cpu: "500m"
---
apiVersion: v1
kind: Service
metadata:
  name: my-app-service
spec:
  type: LoadBalancer
  selector:
    app: my-app
  ports:
  - port: 80
    targetPort: 80
# 배포
kubectl apply -f deployment.yaml

# μƒνƒœ 확인
kubectl get pods
kubectl get services

5. GCP GKE (Google Kubernetes Engine)

5.1 Creating a GKE Cluster

# 1. GKE API ν™œμ„±ν™”
gcloud services enable container.googleapis.com

# 2. ν΄λŸ¬μŠ€ν„° 생성 (Autopilot - ꢌμž₯)
gcloud container clusters create-auto my-cluster \
    --region=asia-northeast3

# λ˜λŠ” Standard ν΄λŸ¬μŠ€ν„°
gcloud container clusters create my-cluster \
    --region=asia-northeast3 \
    --num-nodes=2 \
    --machine-type=e2-medium

# 3. ν΄λŸ¬μŠ€ν„° 인증 정보 κ°€μ Έμ˜€κΈ°
gcloud container clusters get-credentials my-cluster \
    --region=asia-northeast3

# 4. ν΄λŸ¬μŠ€ν„° 확인
kubectl get nodes

5.2 GKE Autopilot Deep Dive

GKE Autopilot is a fully managed Kubernetes mode where Google manages the entire cluster infrastructure, including nodes, scaling, and security.

Autopilot vs Standard:

Category Autopilot Standard
Node Management Google auto-managed User-managed
Billing Pod resource-based Node-based
Security Enhanced defaults (hardened OS, Workload Identity, Shielded GKE Nodes) Manual configuration
Scalability Automatic HPA/VPA Manual/auto configuration
GPU Support Supported (L4, A100, H100, TPU) Supported
Spot Pods Supported Supported (preemptible nodes)
DaemonSets Allowed (billing included) Allowed
Privileged Pods Not allowed Allowed
Best For Most workloads, cost optimization Fine-grained control, special kernel needs

Autopilot Security Features (enabled by default): - Container-Optimized OS with containerd - Workload Identity (no node service account keys) - Shielded GKE Nodes (secure boot, integrity monitoring) - Network policy enforcement - Pod security standards (Baseline by default) - Binary Authorization ready

# Deploy with Spot Pods on Autopilot (cost savings up to 60-91%)
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: batch-processor
spec:
  replicas: 5
  selector:
    matchLabels:
      app: batch-processor
  template:
    metadata:
      labels:
        app: batch-processor
    spec:
      nodeSelector:
        cloud.google.com/gke-spot: "true"
      terminationGracePeriodSeconds: 25
      containers:
      - name: worker
        image: asia-northeast3-docker.pkg.dev/PROJECT_ID/my-repo/worker:latest
        resources:
          requests:
            cpu: "500m"
            memory: "1Gi"
            # GPU request on Autopilot
            # nvidia.com/gpu: "1"
          limits:
            cpu: "500m"
            memory: "1Gi"
      tolerations:
      - key: cloud.google.com/gke-spot
        operator: Equal
        value: "true"
        effect: NoSchedule
EOF

5.3 Deploying Applications

# deployment.yaml (GKE)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app
        image: asia-northeast3-docker.pkg.dev/PROJECT_ID/my-repo/my-app:latest
        ports:
        - containerPort: 80
        resources:
          requests:
            memory: "128Mi"
            cpu: "250m"
          limits:
            memory: "256Mi"
            cpu: "500m"
---
apiVersion: v1
kind: Service
metadata:
  name: my-app-service
spec:
  type: LoadBalancer
  selector:
    app: my-app
  ports:
  - port: 80
    targetPort: 80
kubectl apply -f deployment.yaml
kubectl get services

6. Serverless Containers

6.1 AWS Fargate

Fargate runs containers without server provisioning.

Features: - No EC2 instance management needed - Define resources at task level - Use with ECS or EKS

# ECS + Fargate둜 μ„œλΉ„μŠ€ 생성
aws ecs create-service \
    --cluster my-cluster \
    --service-name my-fargate-service \
    --task-definition my-task:1 \
    --desired-count 2 \
    --launch-type FARGATE \
    --platform-version LATEST \
    --network-configuration "awsvpcConfiguration={subnets=[subnet-xxx],securityGroups=[sg-xxx],assignPublicIp=ENABLED}"

6.2 GCP Cloud Run

Cloud Run runs containers in a serverless manner.

Features: - Fully managed - Request-based auto-scaling (to zero) - Pay only for what you use - HTTP traffic or event-driven

# 1. 이미지 배포
gcloud run deploy my-service \
    --image=asia-northeast3-docker.pkg.dev/PROJECT_ID/my-repo/my-app:latest \
    --region=asia-northeast3 \
    --platform=managed \
    --allow-unauthenticated

# 2. μ„œλΉ„μŠ€ URL 확인
gcloud run services describe my-service \
    --region=asia-northeast3 \
    --format='value(status.url)'

# 3. νŠΈλž˜ν”½ λΆ„ν•  (Blue/Green)
gcloud run services update-traffic my-service \
    --region=asia-northeast3 \
    --to-revisions=my-service-00002-abc=50,my-service-00001-xyz=50

6.3 Cloud Run vs App Runner Comparison

Category GCP Cloud Run AWS App Runner
Source Container image, source code Container image, source code
Max Memory 32GB 12GB
Max Timeout 60 minutes 30 minutes
Scale to Zero Supported Supported (optional)
VPC Connection Supported Supported
GPU Supported Not supported

7. Service Selection Guide

7.1 Decision Tree

Do you need serverless containers?
β”œβ”€β”€ Yes β†’ Cloud Run / Fargate / App Runner
β”‚         └── Need Kubernetes features?
β”‚             β”œβ”€β”€ Yes β†’ Fargate on EKS
β”‚             └── No β†’ Cloud Run (GCP) / Fargate on ECS (AWS)
└── No β†’ Do you need Kubernetes?
          β”œβ”€β”€ Yes β†’ GKE (Autopilot/Standard) / EKS
          └── No β†’ ECS on EC2 / Compute Engine + Docker

7.2 Recommendations by Use Case

Use Case AWS Recommended GCP Recommended
Simple Web App App Runner Cloud Run
Microservices ECS Fargate + Service Connect Cloud Run
K8s (Simplified) EKS Auto Mode GKE Autopilot
K8s (Full Control) EKS Standard GKE Standard
ML/GPU Workloads EKS + GPU GKE Autopilot + GPU
Batch Jobs ECS Task Cloud Run Jobs
Event Processing Fargate + EventBridge Cloud Run + Eventarc
Cost-Sensitive Batch Fargate Spot Autopilot Spot Pods

8. Pricing Comparison

8.1 ECS/EKS vs GKE

AWS ECS (Fargate):

vCPU: $0.04048/hour (Seoul)
Memory: $0.004445/GB/hour (Seoul)

Example: 0.5 vCPU, 1GB, 24 hours
= (0.5 Γ— $0.04048 Γ— 24) + (1 Γ— $0.004445 Γ— 24)
= $0.49 + $0.11 = $0.60/day

AWS EKS:

Cluster: $0.10/hour ($72/month)
+ Node costs (EC2) or Fargate costs

GCP GKE:

Autopilot: vCPU $0.0445/hour, Memory $0.0049/GB/hour
Standard: Management fee $0.10/hour/cluster + node costs

Example: Autopilot 0.5 vCPU, 1GB, 24 hours
= (0.5 Γ— $0.0445 Γ— 24) + (1 Γ— $0.0049 Γ— 24)
= $0.53 + $0.12 = $0.65/day

8.2 Cloud Run Pricing

CPU: $0.00002400/vCPU-second (during request processing)
Memory: $0.00000250/GB-second
Requests: $0.40/million requests

Free Tier:
- 2 million requests/month
- 360,000 GB-seconds
- 180,000 vCPU-seconds

9. Hands-on: Deploy a Simple Web App

9.1 Prepare Dockerfile

# Dockerfile
FROM python:3.12-slim

WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

EXPOSE 8080
CMD ["python", "app.py"]
# app.py
from flask import Flask
import os

app = Flask(__name__)

@app.route('/')
def hello():
    return f"Hello from {os.environ.get('CLOUD_PROVIDER', 'Container')}!"

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8080)
# requirements.txt
flask==3.0.0
gunicorn==21.2.0

9.2 Deploy to GCP Cloud Run

# λΉŒλ“œ 및 배포 (μ†ŒμŠ€μ—μ„œ 직접)
gcloud run deploy my-app \
    --source=. \
    --region=asia-northeast3 \
    --allow-unauthenticated \
    --set-env-vars=CLOUD_PROVIDER=GCP

9.3 Deploy to AWS App Runner

# 1. ECR에 이미지 ν‘Έμ‹œ (μ•žμ„œ μ„€λͺ…ν•œ 방법)

# 2. App Runner μ„œλΉ„μŠ€ 생성
aws apprunner create-service \
    --service-name my-app \
    --source-configuration '{
        "ImageRepository": {
            "ImageIdentifier": "123456789012.dkr.ecr.ap-northeast-2.amazonaws.com/my-app:latest",
            "ImageRepositoryType": "ECR",
            "ImageConfiguration": {
                "Port": "8080",
                "RuntimeEnvironmentVariables": {
                    "CLOUD_PROVIDER": "AWS"
                }
            }
        },
        "AuthenticationConfiguration": {
            "AccessRoleArn": "arn:aws:iam::123456789012:role/AppRunnerECRAccessRole"
        }
    }'

10. Next Steps


References

to navigate between lessons