亚马逊AWS官方博客

利用 ECS ComposeX 自动化 ECS 容器架构部署

这是一篇由 John Preston 提供的客座博文,John Preston 是一位经验丰富的解决方案架构师,他热衷于开发,并且花了大量时间在 AWS 架构部署自动化的处理和开源上,包括 ECS ComposeX 开源项目。在本博文中,John 将会讨论此项目的动机,以及如何使用 Docker Compose 文件格式构建您的基础设施以及将您的服务部署到 AWS 服务。

针对 AWS Lambda 实施采用无服务器 SAM 的 ECS 和 Docker Compose

Docker Compose 通过在一个标准化文档中以逻辑方式将微服务相互连接在一起来帮助开发人员在其微服务之间执行本地集成测试,但是,将此迁移到云平台往往需要大量的时间和精力。例如,开发人员需要了解 Amazon Elastic Container Service (Amazon ECS) 的工作原理、定义、AWS Identity and Access Management (IAM)、联网等,而这意味着云工程师需要构建和预置所有这些资源。

在这个以实现应用程序集成和部署自动化为目标的时代,ECS ComposeX 是一次伟大的尝试,它可以帮助开发人员简化基础设施即代码 (IaC) 背后蕴含的复杂性,并将所需的服务和其他 AWS 资源部署到 AWS 生态系统。ECS ComposeX 是一个开源项目,旨在帮助解决使用 AWS 服务将微服务部署到 ECS 的问题。为了测试该项目,我需要继续为基础设施部署各种配置,以确认项目中的功能正常运行。尽管每次只需几美金,但我需要自己承担该开源项目的总费用,因此,我申请了适用于开源项目的 AWS 促销服务抵扣金额。表单填写非常简单:只需解释申请促销服务抵扣金额的原因,以及计划使用的服务和这些抵扣金额的用途。这解决了项目的经济问题,但我最感谢 AWS 的是,它为我提供了一个发表博文的机会,让我能够与大家分享我的项目。

ECS ComposeX 有何不同之处?

ECS ComposeX 与其他工具的不同之处在于,它分别为每个服务嵌入了安全性,因此,开发人员只需通过逻辑方式将资源连接在一起,方法与在 Docker Compose 定义中的微服务之间使用链接相同。需要将每个微服务显式声明为资源的使用者才能进行访问,否则,无法访问资源或其他微服务。这只需通过使用 AWS IAM 策略或安全组入口(如适用)即可实现。在未来的版本中,ECS ComposeX 允许将 AWS App Mesh 用于服务到服务的通信。这使云工程师可以放心,因为对每个微服务单独了进行隔离,所以在分布式环境中,对平台的攻击面将会受限。

这种方式简化了定义服务与资源之间的访问,有助于确定应用程序工程师与云工程师之间的责任共担模式。应用程序工程师必须了解其应用程序的作用,以及服务相互之间以及与外部服务之间如何连接。这赋予了 Docker Compose 文件维护人员一种自主感,让他们可以定义应用程序堆栈资源和服务以及资源访问和权限。

ECS ComposeX 可用于哪些领域?

当今面临的最大自动化挑战之一是,标准化 CI/CD 管道并提供与生产环境相同的临时环境。这些年以来,开发人员日益成熟,可以使用 TDD(测试驱动开发)或 BDD(行为驱动开发)方法之类的测试技术对开发的每项新功能进行测试。持续集成管道和测试得以简化,并且通过工具可以轻松对应用程序执行测试。

但是,所面临的挑战仍然是执行集成测试,尤其是在分布式环境中。Docker Compose 帮助开发人员弥合了这些鸿沟,但这往往仅适用于其本地环境,很少能够完全反映云环境的情况,并且通过笔记本电脑进行的测试根据无法让人接受。

因此,我们需要一种更合适的解决方案,用于像在生产的环境中一样部署整个应用程序堆栈、针对应用程序运行测试并获得结果。这时,ECS ComposeX 等软件就有了用武之地,它们可以帮助简化和降低获取高度并行部署的临时开发环境的复杂性。

功能揭秘

我认为 AWS CloudFormation 是 AWS 上的 IaC 的不二之选,并且我在五年以前编写的模板现在依然适用。另外,AWS CloudFormation 注册表为开创 AWS 服务范围之外的 AWS 即 IaC 服务带来了机会。

Amazon ECS 是一项功能强大的 Docker 编排服务, 专用于将应用程序部署到 AWS,通过在过去几年里向其添加的功能,您可以更轻松地部署具有高性能、控制、监控、日志记录和安全边界的应用程序,并且这些均紧密集成到 AWS 架构中,可实现架构最佳实践。

为了通过 Docker Compose 定义生成所有 CloudFormation 模板,我将使用 Python 和名为 Troposphere 的开源库。

我希望使用简单的原生云工具,这也是为什么选择 AWS CloudFormation 和 Amazon ECS 如此重要的原因;它允许用户根据其需要调整模板,并获得来自 AWS 社区以及直接来自 AWS 及其支持服务的支持。

开始使用 ECS ComposeX

撰写本文时,ECS ComposeX 及其示例是作为 CLI 工具呈现,该工具可以在 AWS CodeBuild 或 CircleCi 等内通过笔记本电脑或 CI/CD 管道执行;但是,由于 ECS ComposeX 是一个 Python 包,因此,其目标是允许将其作为 Python 库嵌入到另一个应用程序中,例如 Lambda 函数。为了实现此目标,ECS ComposeX 将作为任何人均可在其 Lambda 函数中使用的 Lambda 层提供。

使用案例

理念是使用 ECS ComposeX 生成集成环境所需的所有基础设施,因此,除了将服务部署到 Amazon ECS 外,我们还希望所需的 VPC。让我们来演示一下如何在命令行界面中使用该服务,然后将其实施到 AWS CodeBuild 中。

安装 ECS ComposeX

# 最好创建 venv 或仅针对用户安装
python3 -m venv venv
source venv/bin/active
pip install ecs_composex

## 仅限您的用户
pip install ecs_composex --user

您需要有效的凭证集才能运行此命令,以便执行 API 调用并在 Amazon Simple Storage Service (Amazon S3) 中创建文件。

我使用的是 awsume,它允许我从一个账户切换到另一个:

# 这将设置所有环境变量
$(awsume -s Lambda)

Docker Compose 文件

从原始 Docker Compose 文件开始:

services:
  app01:
    environment:
      NAME: DISPATCH
    image: 373709687836.dkr.ecr.eu-west-1.amazonaws.com/blog-app-01@sha256:0bf30cce6c4a58a9d494cd2dcada2c102a9d92e449059ca3d2d7d8c15980cc55
    ports:
      - 80:80
    links:
      - app02

  app02:
    environment:
      NAME: backend
    ports:
      - 8080
    image: 373709687836.dkr.ecr.eu-west-1.amazonaws.com/blog-app-03@sha256:e30331fe53304b5fd7ecce973d8e2a1cf91030f362c5df45c5c063d127d138e9

添加配置

ECS ComposeX 使用 Docker Compose 支持的配置部分扩展服务配置。例如,让我们定义 app01 为公共,可通过 AWS Application Load Balancer 访问,并且所有服务均应使用 Amazon Virtual Private Cloud (Amazon VPC) 命名空间中的 AWS Cloud Map 注册:

configs:
  app01:
    network:
      is_public: true
      use_alb: true
      use_nlb: false
  composex:
    network:
      use_cloudmap: true

此外,通常出于计费和自动化目的,我们可能需要在资源上定义 AWS 标签,以便跟踪拥有者、接触点等。借助 ECS ComposeX,可以通过在 Docker Compose 文件中定义 x-tags 部分来轻松添加标签。

x-tags:
  - name: costcentre
    value: LambdaMyAws
  - name: owner
    value: JohnPreston
  - name: mail
    value: john@lambda-my-aws.io

添加 Amazon RDS 集群

我们知道,应用程序需要一个数据库并且我们已选择 RDS Aurora。按照适用于 Amazon Relational Database Service (Amazon RDS) 的 ECS ComposeX 语法参考,向 Docker Compose 文件添加以下内容:

x-rds:
  dbA:
    Properties:
      Engine: aurora-mysql
      EngineVersion: 5.7.12
    Settings: {}
    Services:
      - name: app02
        access: RW

添加 SQS 队列

接着执行相同操作以添加两个 Amazon Simple Queue Service (Amazon SQS) 队列。其中一个队列被指定为前一个队列的死信队列:

x-sqs:
  DLQ:
    Properties: {}
    Services:
    - access: RWMessages
      name: app02
  Queue01:
    Properties:
      RedrivePolicy:
        deadLetterTargetArn: DLQ
        maxReceiveCount: 1
    Services:
    - access: RWMessages
      name: app01
    Settings:
      EnvNames:
        - APP_QUEUE
        - AppQueue

将它放在一起:

---
# 将 Docker Compose 文件放在一起
configs:
  app01:
    network:
      is_public: true
      use_alb: true
      use_nlb: false
  composex:
    network:
      use_cloudmap: true

services:
  app01:
    environment:
      NAME: DISPATCH
    image: 373709687836.dkr.ecr.eu-west-1.amazonaws.com/blog-app-01@sha256:0bf30cce6c4a58a9d494cd2dcada2c102a9d92e449059ca3d2d7d8c15980cc55
    ports:
      - 80:80
    links:
      - app02
  app02:
    environment:
      NAME: backend
      ports:
        - 8080
    image: 373709687836.dkr.ecr.eu-west-1.amazonaws.com/blog-app-03@sha256:e30331fe53304b5fd7ecce973d8e2a1cf91030f362c5df45c5c063d127d138e9

x-rds:
  dbA:
    Properties:
      Engine: aurora-mysql
      EngineVersion: 5.7.12
    Settings: {}
    Services:
      - name: app02
        access: RW

x-sqs:
  DLQ:
    Properties: {}
    Services:
      - access: RWMessages
        name: app02
  Queue01:
    Properties:
      RedrivePolicy:
        deadLetterTargetArn: DLQ
        maxReceiveCount: 1
    Services:
      - access: RWMessages
        name: app01
    Settings:
      EnvNames:
        - APP_QUEUE
        - AppQueue

x-tags:
  - name: costcentre
    value: LambdaMyAws
  - name: owner
    value: JohnPreston
  - name: mail
    value: john@lambda-my-aws.io

凭证已准备就绪,并且 Docker Compose 文件包含相应的服务和额外设置,可指示服务相互之间的连接方式:

  • app01 将通过 Application Load Balancer 公开可用。
    • app01 SG 将连接到容器。
    • 关联的 SG 将允许 Application Load Balancer 向其发送流量。
  • VPC 中的 app02 为专用,不允许任何入站访问。
  • app01 具有至 app02 的链接,因此我们将允许入站访问。
  • SQS 队列 DLQ,已授予 app02 访问权限。
  • SQS 队列 Queue01,已授予 app01 访问权限。
  • Amazon Aurora 集群,dbA,授予对服务 app02 的访问权限。
    • 在 Secrets Manager 中创建数据库凭证。
    • app02 提供入站访问。
    • app02执行角色提供密钥访问权限。

这时,您可能会认为通过现有 CloudFormation 模板或 Terraform 模块即可构建所有一切,您可能是正确的;但是,您可能需要单独编写模板或模块,并部署服务。

通过使用 Docker Compose 格式,开发人员无需进行复杂繁琐的学习即可快速部署基础设施。

# 创建一个输出文件文件夹,用于存储 S3 中内容的本地副本。
mkdir outputs
ecs_composex -f docker_compose.yml -d outputs -o demo.yml --create-vpc --create-cluster --single-nat
aws cloudformation  create-stack --capabilities CAPABILITY_IAM CAPABILITY_AUTO_EXPAND --template-body file://outputs.demo.yml --stack-name demo

就这么简单!现在,坐下来放松一下,AWS CloudFormation 将会神奇地部署基础设施。

让它在管道中发挥作用

我已经演示了如何使用 Docker Compose 文件和 ECS ComposeX 一次性部署基础设施。下一步是在部署管道内自动化此过程。通过将 Docker Compose 文件用作环境的定义并监控文件更改,我们可以在部署管道中配置触发器,以监控 Docker Compose 文件是否存在更改并创建新的环境部署。

阶段 1:检测文件更改

一般的可疑更改检测。在这里,我们将检测存储库主分支上是否存在可触发管道的更改。

阶段 2:生成 CFN 模板文件

通过使用 AWS CodeBuild,我们将从 PyPi 安装 ecs_composex,并根据我们的 Docker Compose 文件执行它。我们将收集构件,然后将它们加密并上传到 Amazon S3 中。下载示例:buildspec.yml

阶段 3:部署开发环境

AWS CodePipeline 可切换账户,并使用包含预先设定设置的 CloudFormation 部署临时环境。阶段 3.1(此处未显示)用于对新平台执行测试,但您可以在其中运行 Cucumber 或执行需要的其他测试,以确定服务在其环境中均正常运行,从而检查环境是否正常工作。

阶段 4:销毁开发环境

既然我们已执行完测试并且不再需要此环境,因此需要销毁该环境。

阶段 5:批准部署到生产

由于许多生产部署需要进过公司批准,因此,我们需要通过唯一的一项人工干预才能进入下一个阶段

阶段 6:部署到生产

通过使用相同的模板、相同的 Docker 镜像和相同的设置,我们可以使用更新的 Docker 版本和其他的新设置来部署我们的服务。

 

AWS CodeBuild 和 ECS ComposeX

适用于以上管道的模板可以在 GitHub 上找到。在这一整个管道中唯一需要手动进行的操作是在模板外创建 Amazon Simple Notification Service (Amazon SNS) 订阅。

请注意,在生产账户中,常常会遇到在单个堆栈(存储和服务都是紧密相连的)下没有基本的网络基础设施的情况。这就仍然需要耦合,ECS ComposeX 依赖获取正确的信息以传递其他信息。

在我的示例中,正好出现了这样的情况。在生产账户中,我使用 ecs_composex-vpc 创建了一个 VPC,以创建我的 VPC 网络。您不必用此创建您的 VPC;它只是便于我节省构建 VPC 的时间。在存储 Docker Compose 文件的存储库中,我存储了所需的 VPC 子网 ID 和其他输入,以便成功创建其他对象。

这只是部署的 CD 部分如何工作的快照。可以通过许多方法来思考和处理 CI/CD 管道,您可以在我的博文“适用于具有 ECS ComposeX 的 AWS ECS 上的多种服务的 CICD 管道 ”中找到完整的 CI/CD 管道实施示例。 接下来,我打算在 ECS ComposeX 中实施发现功能,以允许用户根据标签执行发现操作,以映射子网、VPC 等。

后续内容

在本博文中,我介绍了开发人员在编写应用程序时面临的架构部署自动化方面的挑战。这激励了我创建 ECS ComposeX 来帮助解决所面临的部分挑战。我将会继续为 ECS ComposeX 添加新功能,欢迎大家提供反馈和做出贡献,您可以在 GitHub 上找到该项目。

John Preston

John Preston

John Preston 早期的职业生涯使其快速走入 AWS,他很快就表现出了对最佳实践和架构部署自动化的热情。怀着对自动化、AWS 和开源的渴望,他开始研究 ECS ComposeX 以反馈这些社区,从而帮助提高 AWS 服务的采用率并简化最佳实践的实施。

本博文中的内容和意见属于第三方作者,AWS 不对本博文的内容或准确性负责。