Skip to content

第 16 章 · AWS ECS/Fargate 与 S3

本章目标:

  • 理解 ECS 与 Fargate 的区别
  • 学会 Docker 镜像构建和推送
  • 掌握 Fargate Task Definition 配置
  • 使用 boto3 操作 S3 存储

16.1 ECS vs Fargate

特性ECS EC2ECS Fargate
基础设施管理需管理 EC2 实例无服务器
计费方式按 EC2 实例按 vCPU/内存
扩展性手动或 Auto Scaling自动
适用场景长期稳定负载波动负载、微服务

16.2 Docker 镜像构建

dockerfile
# Dockerfile
FROM python:3.12-slim

WORKDIR /app

# 安装依赖
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# 复制应用
COPY . .

# 健康检查
HEALTHCHECK --interval=30s --timeout=10s --retries=3 \
  CMD curl -f http://localhost:8000/health || exit 1

# 启动命令
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
bash
# 构建并推送
docker build -t agent-service:latest .
docker tag agent-service:latest $AWS_ACCOUNT.dkr.ecr.$REGION.amazonaws.com/agent-service:latest
docker push $AWS_ACCOUNT.dkr.ecr.$REGION.amazonaws.com/agent-service:latest

16.3 Task Definition

json
{
  "taskDefinition": {
    "family": "agent-service",
    "networkMode": "awsvpc",
    "cpu": "512",
    "memory": "1024",
    "requiresCompatibilities": ["FARGATE"],
    "executionRoleArn": "arn:aws:iam::XXX:role/ecs-execution-role",
    "taskRoleArn": "arn:aws:iam::XXX:role/ecs-task-role",
    "containerDefinitions": [
      {
        "name": "agent",
        "image": "XXX.dkr.ecr.us-east-1.amazonaws.com/agent-service:latest",
        "portMappings": [{"containerPort": 8000, "protocol": "tcp"}],
        "environment": [
          {"name": "AI_GATEWAY_API_KEY", "value": "xxx"},
          {"name": "LANGFUSE_PUBLIC_KEY", "value": "pk-xxx"}
        ],
        "secrets": [
          {"name": "OPENAI_API_KEY", "valueFrom": "arn:aws:secretsmanager::XXX:secret:openai-key"}
        ],
        "healthCheck": {
          "command": ["CMD-SHELL", "curl -f http://localhost:8000/health || exit 1"],
          "interval": 30,
          "timeout": 10,
          "retries": 3
        }
      }
    ]
  }
}

16.4 boto3 操作 S3

python
import boto3
from botocore.config import Config

s3 = boto3.client(
    "s3",
    config=Config(retries={"max_attempts": 3})
)

# 上传文件
s3.put_object(
    Bucket="agent-knowledge-base",
    Key="documents/intro.pdf",
    Body=file_bytes,
    ContentType="application/pdf"
)

# 生成预签名 URL(7 天有效)
url = s3.generate_presigned_url(
    "get_object",
    Params={"Bucket": "agent-knowledge-base", "Key": "documents/intro.pdf"},
    ExpiresIn=604800
)

# 列出文档
response = s3.list_objects_v2(
    Bucket="agent-knowledge-base",
    Prefix="documents/"
)
files = [obj["Key"] for obj in response.get("Contents", [])]

本章小结

  • Fargate 适合无服务器部署,按使用计费
  • Dockerfile 需包含健康检查
  • Task Definition 定义容器配置和环境变量
  • boto3 提供 S3 操作的 Python SDK

🛠️ 动手实践

  1. 构建 Docker 镜像并推送到 ECR
  2. 创建 Fargate Task Definition JSON
  3. 实现 S3 文件上传和预签名 URL 生成功能