昨天我們學會了如何寫 Task Definition,今天要學習 ECS Service - 一個聰明的管理員,確保我們的交易程式永遠在運行。就像農場需要一個可靠的管理員來確保農作物得到適當照顧一樣,ECS Service 會確保我們的容器健康運行。
ECS Service 就像是農場的自動化管理系統,它會:
graph TD
subgraph "ECS Cluster - 農場"
A[ECS Service<br/>管理員] --> B[Task 1<br/>工人A]
A --> C[Task 2<br/>工人B]
A --> D[Task 3<br/>工人C]
E[Application Load Balancer<br/>工作分配器] --> B
E --> C
E --> D
F[Auto Scaling<br/>智慧調度] --> A
G[CloudWatch<br/>監控系統] --> F
end
H[Internet<br/>外部世界] --> E
I[Target Group<br/>工人群組] --> E
style A fill:#e3f2fd
style E fill:#f3e5f5
style F fill:#e8f5e8
{
"serviceName": "trading-bot-service",
"cluster": "trading-cluster",
"taskDefinition": "trading-bot-task:1",
"desiredCount": 2,
"launchType": "FARGATE",
"platformVersion": "LATEST",
"networkConfiguration": {
"awsvpcConfiguration": {
"subnets": [
"subnet-12345678",
"subnet-87654321"
],
"securityGroups": [
"sg-trading-ecs"
],
"assignPublicIp": "DISABLED"
}
},
"loadBalancers": [
{
"targetGroupArn": "arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/trading-tg/1234567890123456",
"containerName": "trading-bot",
"containerPort": 8080
}
],
"serviceRegistries": [
{
"registryArn": "arn:aws:servicediscovery:us-east-1:123456789012:service/srv-trading",
"containerName": "trading-bot"
}
]
}
ECS Service 的核心職責是維持「期望狀態」:
graph LR
A[期望狀態<br/>Desired: 2 Tasks] --> B{檢查現狀}
B --> C[實際運行: 2 Tasks<br/>✅ 正常]
B --> D[實際運行: 1 Task<br/>❌ 不足]
B --> E[實際運行: 3 Tasks<br/>❌ 過多]
D --> F[啟動新 Task]
E --> G[停止多餘 Task]
F --> A
G --> A
C --> A
{
"healthCheckGracePeriodSeconds": 300,
"deploymentConfiguration": {
"maximumPercent": 200,
"minimumHealthyPercent": 50
}
}
參數說明:
healthCheckGracePeriodSeconds
: 新 Task 的健康檢查寬限期maximumPercent
: 部署期間最多可以有多少個 TaskminimumHealthyPercent
: 部署期間至少要有多少個健康的 Taskgraph TD
A[開始更新] --> B[啟動新版本 Task]
B --> C{新 Task 健康檢查}
C --> |通過| D[停止舊版本 Task]
C --> |失敗| E[回滾到舊版本]
D --> F{還有舊 Task?}
F --> |是| B
F --> |否| G[更新完成]
E --> H[更新失敗]
style G fill:#ccffcc
style H fill:#ffcccc
首先為 Application Load Balancer 建立 Target Group:
# 建立 Target Group
aws elbv2 create-target-group \
--name trading-bot-tg \
--protocol HTTP \
--port 8080 \
--vpc-id vpc-12345678 \
--target-type ip \
--health-check-path /health \
--health-check-interval-seconds 30 \
--health-check-timeout-seconds 5 \
--healthy-threshold-count 2 \
--unhealthy-threshold-count 3
# 建立 ALB
aws elbv2 create-load-balancer \
--name trading-bot-alb \
--subnets subnet-12345678 subnet-87654321 \
--security-groups sg-alb-12345678 \
--scheme internet-facing \
--type application \
--ip-address-type ipv4
# 建立 Listener
aws elbv2 create-listener \
--load-balancer-arn arn:aws:elasticloadbalancing:us-east-1:123456789012:loadbalancer/app/trading-bot-alb/1234567890123456 \
--protocol HTTP \
--port 80 \
--default-actions Type=forward,TargetGroupArn=arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/trading-bot-tg/1234567890123456
# 建立 Service
aws ecs create-service \
--cluster trading-cluster \
--service-name trading-bot-service \
--task-definition trading-bot-task:1 \
--desired-count 2 \
--launch-type FARGATE \
--platform-version LATEST \
--network-configuration "awsvpcConfiguration={subnets=[subnet-12345678,subnet-87654321],securityGroups=[sg-trading-ecs],assignPublicIp=DISABLED}" \
--load-balancers "targetGroupArn=arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/trading-bot-tg/1234567890123456,containerName=trading-bot,containerPort=8080"
# 註冊可擴展目標
aws application-autoscaling register-scalable-target \
--service-namespace ecs \
--resource-id service/trading-cluster/trading-bot-service \
--scalable-dimension ecs:service:DesiredCount \
--min-capacity 1 \
--max-capacity 10
# 建立 CPU 使用率擴展政策
aws application-autoscaling put-scaling-policy \
--policy-name trading-bot-cpu-scaling \
--service-namespace ecs \
--resource-id service/trading-cluster/trading-bot-service \
--scalable-dimension ecs:service:DesiredCount \
--policy-type TargetTrackingScaling \
--target-tracking-scaling-policy-configuration '{
"TargetValue": 70.0,
"PredefinedMetricSpecification": {
"PredefinedMetricType": "ECSServiceAverageCPUUtilization"
},
"ScaleOutCooldown": 300,
"ScaleInCooldown": 300
}'
graph TD
A[CloudWatch 監控] --> B{CPU 使用率}
B --> |> 70%| C[觸發擴展]
B --> |< 30%| D[觸發縮減]
B --> |30-70%| E[維持現狀]
C --> F[增加 Task 數量]
D --> G[減少 Task 數量]
F --> H[等待 300 秒冷卻]
G --> I[等待 300 秒冷卻]
H --> A
I --> A
E --> A
style C fill:#ffcccc
style D fill:#ccffcc
style E fill:#fff3e0
# 建立命名空間
aws servicediscovery create-private-dns-namespace \
--name trading.internal \
--vpc vpc-12345678 \
--description "Trading system internal namespace"
# 建立服務
aws servicediscovery create-service \
--name trading-bot \
--namespace-id ns-12345678 \
--dns-config '{
"NamespaceId": "ns-12345678",
"DnsRecords": [
{
"Type": "A",
"TTL": 60
}
]
}' \
--health-check-custom-config FailureThreshold=1
graph TB
A[ECS Service 監控] --> B[Task 層級]
A --> C[Service 層級]
A --> D[負載平衡器層級]
B --> E[CPU 使用率<br/>記憶體使用率<br/>網路 I/O]
C --> F[運行中 Task 數量<br/>期望 Task 數量<br/>pending Tasks]
D --> G[健康目標數量<br/>回應時間<br/>錯誤率]
style E fill:#e3f2fd
style F fill:#f3e5f5
style G fill:#fff3e0
# 查看 Service 狀態
aws ecs describe-services \
--cluster trading-cluster \
--services trading-bot-service
# 查看 Service 事件
aws ecs describe-services \
--cluster trading-cluster \
--services trading-bot-service \
--query 'services[0].events'
# 查看 Task 詳細資訊
aws ecs list-tasks \
--cluster trading-cluster \
--service-name trading-bot-service
# 查看 Target Group 健康狀態
aws elbv2 describe-target-health \
--target-group-arn arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/trading-bot-tg/1234567890123456
藍綠部署 vs 滾動更新:
策略 | 優點 | 缺點 | 適用場景 |
---|---|---|---|
滾動更新 | 資源使用效率高 | 部署時間較長 | 一般更新 |
藍綠部署 | 快速切換、容易回滾 | 需要雙倍資源 | 重要更新 |
{
"desiredCount": 2, // 至少 2 個 Task 確保高可用
"deploymentConfiguration": {
"maximumPercent": 200, // 部署時最多 4 個 Task
"minimumHealthyPercent": 50 // 部署時至少 1 個健康 Task
}
}
今天我們學習了 ECS Service 這個聰明的管理員,它就像農場裡的自動化系統,確保我們的交易程式穩定運行。重要的概念包括:
明天我們將學習 AWS Launch Template,為我們的 EC2 執行個體建立標準化的啟動範本。
下一篇:Day 8 - AWS Launch Template on EC2