发布于 2026-01-06 1 阅读
0

面向初学者的简单 ECS + ECR 项目

面向初学者的简单 ECS + ECR 项目

您是 AWS 新手,正在尝试了解 ECS 和 ECR 如何协同工作来部署应用程序吗?这篇文章正是为您准备的!在本篇简单的演练中,我们将学习如何将应用程序容器化,将镜像存储在 Amazon ECR 中,并使用 Terraform 在 ECS 上运行它。

✅ 先决条件

开始之前,请确保已安装并配置以下内容:

  • ✅ AWS CLI(已配置凭证)
  • ✅ Terraform
  • ✅ Docker
  • ✅ 一个现有的 ECR 存储库(或者 Terraform 可以为您创建一个)

🧰 本项目中使用的服务(基于 Terraform)

1. Amazon ECR(弹性容器注册表)

🗃️ 一个完全托管的 Docker 容器注册表,用于存储和管理您的容器镜像。

  • 用于存储由您的应用程序构建的 Docker 镜像。
  • Terraform 可以自动创建(或重用)ECR 存储库。
  • ECS 服务在运行时直接从 ECR 拉取镜像。

2. Amazon ECS(弹性容器服务)与 Fargate

🚢 容器编排服务,可让您运行和扩展容器化应用程序。

  • 我们使用 Fargate,一种无服务器计算引擎,它消除了管理 EC2 实例的需要。
  • ECS负责容器的部署、扩展和管理生命周期。
  • 一个或多个 ECS 任务(容器)在由集群支持的 ECS 服务中运行。

3. 亚马逊 VPC(虚拟私有云)

🌐 所有 AWS 资源均部署在隔离的网络环境中。

  • 为 ECS 服务和 ALB 配置了带有公共子网的自定义 VPC。
  • 包括互联网网关、路由表和安全组。
  • 为您的应用提供安全有序的网络边界。

4. 应用负载均衡器(ALB)

⚖️ 将传入流量分配到在不同可用区运行的 ECS 任务中。

  • 通过HTTP协议公开您的应用程序。
  • 自动将流量分配到可用的 ECS 容器(目标)。
  • 集成 CloudFront 作为源。

5. Amazon CloudFront(内容分发网络)

🚀 安全快速地将您的内容送达全球各地。

  • 位于 ALB 前面,缓存静态和动态内容。
  • 默认使用 AWS 管理的 SSL 证书提供 HTTPS 服务。
  • 与 S3 集成以存储访问日志,并与 CloudWatch 集成以进行监控。

6. Amazon S3(简单存储服务)

💾 安全、耐用的对象存储,适用于任何类型的数据。

  • 用于存储 CloudFront 访问日志,从而可以了解谁在何时以何种方式访问​​了什么。
  • 系统会自动创建一个专用存储桶来收集日志。
  • 可用于调试、审计和流量分析。

7. Amazon CloudWatch

📈 用于 AWS 资源和应用程序的监控和可观测性平台。

  • 跟踪关键的 CloudFront 指标,例如请求计数、4xx/5xx 错误率和延迟。
  • 用于触发警报和分析性能趋势。
  • 如果已配置,还可以记录自定义应用程序或 ECS 级别的日志。

8. Amazon SNS(简单通知服务)

🔔 用于根据监控触发器发送通知的消息服务。

  • 已连接至 CloudWatch 警报,用于发送电子邮件通知。
  • 当超出阈值时发出警报(例如,CloudFront 出现过多 5xx 错误)。
  • 确保您能立即收到有关潜在问题或流量高峰的通知。

9. Terraform

🛠️基础设施即代码工具,用于自动化和管理所有云资源。

  • 在不同环境中一致地定义、配置和销毁基础设施。
  • 实现 VPC、ECS、ALB、CloudFront、S3、CloudWatch 和 SNS 设置的完全自动化。
  • 使您的部署可重复、版本可控且易于维护。

🛠️部署步骤

步骤 1:初始化 Terraform
在您的工作目录中设置 Terraform。

terraform init
Enter fullscreen mode Exit fullscreen mode

步骤 2:格式化 Terraform 代码
清理 Terraform 文件(可选,但推荐):

terraform fmt
Enter fullscreen mode Exit fullscreen mode

步骤 3:准备 Docker 镜像并推送到 ECR
如果您尚未将应用程序镜像推送到 ECR,请检查ecr_push.sh脚本文件夹并运行以下命令
。此脚本将执行以下操作:

  • 构建 Docker 镜像
  • 用你的 ECR 存储库 URL 标记它
  • 将图像推送到 ECR

⚠️ ECR 中已有图片?您可以跳过此步骤。

✅ 部署前的最终检查
🔍 1. 仔细检查 Terraform 变量配置
确保以下内容已正确定义并填充:

在 variables.tf 中:

  • 地区
  • ECR存储库名称
  • S3 日志存储桶名称(可选的默认名称或动态名称)
  • CloudFront 价格类别或别名配置(如有)
  • SNS 主题订阅电子邮件
  • 为确保安全,限制对特定 IP 地址的访问(请查看 VPC 模块 main.tf 文件)
  • ECS 任务内存、CPU 和任务数量
  • 日志保留期

步骤 4:查看 Terraform 计划
预览 Terraform 将创建的内容:

terraform plan -out=tfplan
Enter fullscreen mode Exit fullscreen mode

忽略 1 以销毁

步骤 5:应用 Terraform 配置,
部署基础架构:

terraform apply tfplan
Enter fullscreen mode Exit fullscreen mode

或者简单地说:

如果你在 Terraform Plan 命令中不使用 -out=tfplan 参数,

terraform apply
Enter fullscreen mode Exit fullscreen mode

运行期间,您会收到一封订阅邮件,我已将其用于社交媒体主题。点击并确认订阅。

由于 Terraform 需要配置多个资源,例如 ECS 任务、服务、ALB 和 CloudFront,因此部署可能需要几分钟时间。
默认情况下,Terraform 会通过分析其内部依赖关系图来确定资源的创建顺序。
但是,如有需要,我们可以使用 depends_on 属性显式地控制创建顺序。

您可以忽略此消息——Terraform 正在尝试重新创建 ECR 镜像,但由于该镜像已存在,因此没有必要重新创建。为了避免将来再次出现这种情况,您可以使用 Terraform 生命周期规则来ignore_changes阻止对镜像配置的更新。

✅ 第 6 步:访问您的应用程序
Terraform 创建完所有资源后,会自动生成一个 outputs.txt 文件,其中包含部署的关键访问信息。

感谢 main.tf 中的 null_resources 代码块

此文件包含:

- VPC ID
- ECR Repository URL
- ECS Cluster Name
- Load Balancer DNS
- CloudFront Domain Name
- CloudWatch Dashboard Name
- S3 Logs Bucket Name
- SNS Topic ARN
Enter fullscreen mode Exit fullscreen mode

⚠️ 如果实际项目中包含敏感数据,请确保不要将 outputs.txt 提交到版本控制系统中。

或者运行命令

terraform output
Enter fullscreen mode Exit fullscreen mode

您可以使用任一 URL 访问您的 Web 应用程序。

🔗 应用网址:

  • CloudFront(全局 HTTPS):推荐用于生产环境
  • ALB DNS(直接 HTTP):适用于内部测试或快速验证

步骤 7:清理资源
完成后,销毁所有已创建的 AWS 资源以避免产生费用:

terraform destroy
Enter fullscreen mode Exit fullscreen mode

⚠️ 关于销毁资源的注意事项:
在执行 `terraform destroy` 命令时,大多数 AWS 资源将自动删除。但是,您可能会看到类似这样的错误:

ECR Repository not empty – cannot delete
S3 Bucket not empty – cannot delete
Enter fullscreen mode Exit fullscreen mode

这是因为:

  • 如果 Amazon ECR 中仍包含图像,则不允许删除。
  • 如果 Amazon S3 中包含对象/日志,则不允许删除。

✅ 解决方案
🔹 选项 1:通过 AWS 控制台手动删除
转到 ECR → 选择您的存储库 → 删除所有图像。

前往 S3 → 选择存储桶 → 清空存储桶 → 然后删除它。

🔹选项2:使用AWS CLI
删除所有ECR镜像:

aws ecr batch-delete-image \
  --repository-name ecs-ecr-demo \
  --image-ids $(aws ecr list-images --repository-name ecs-ecr-demo --query 'imageIds[*]' --output json)
Enter fullscreen mode Exit fullscreen mode

清空并删除 S3 存储桶:

aws s3 rm s3://ecs-ecr-demo-logs-<your-bucket-id> --recursive
aws s3 rb s3://ecs-ecr-demo-logs-<your-bucket-id>
Enter fullscreen mode Exit fullscreen mode

清除这些问题后,重新运行:

terraform destroy
Enter fullscreen mode Exit fullscreen mode

🔁 流程概要

  • 用户发送请求 → CloudFront 通过 HTTPS 接收请求。
  • CloudFront 检查缓存;如果缓存未命中,则转发到 ALB。
  • ALB 将请求转发给 ECS 任务之一(Fargate)。
  • ECS 任务(运行 NGINX)返回响应。
  • CloudFront 会缓存响应并将响应发送回用户。
  • 日志上传至 S3;指标上传至 CloudWatch;警报(如有)通过 SNS 发送。

🎨 设计选择

模块化 Terraform 结构:

  • 每个组件(VPC、ECS、ECR、ALB、CloudFront)都在各自的模块中。
  • 易于扩展、维护或重复使用。
  • 无状态 Web 应用:
  • 一个简单的基于 NGINX 的静态页面,用于演示目的。
  • 安全:
  • 用于快速演示访问的公共子网。
  • 安全组将流量限制在端口 80 和 443 以内。

输出文件:

null_resource 会将重要信息(例如 URL、VPC ID)写入 outputs.txt。

🔧 如何自定义

  • 📝 修改 docker/index.html 文件以更新网站内容
  • 🏗️ 编辑 main.tf 文件以修改基础架构行为
  • 🔁 更新 ECS 模块以更改容器设置

💡小贴士

  • 在 ECR 模块中添加 lifecycle { ignore_changes = [...] } 以避免重新创建问题。
  • 当您需要手动控制资源顺序时,请使用 depends_on。
  • 对于实际应用,请考虑使用私有子网、ALB 上的 HTTPS 和自定义域名。

🚀 立即体验

📦 GitHub 代码库:https://github.com/aquavis12/ecs-ecr-demo

文章来源:https://dev.to/aws-builders/a-simple-ecs-ecr-project-for-beginners-4gc0