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
ssmmessagespermissions and the task definition must includeinitProcessEnabled: 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¶
- 07_Object_Storage.md - Object Storage
- 09_Virtual_Private_Cloud.md - VPC Networking