示例:使用 AWS CDK 创建 AWS Fargate 服务 - AWS Cloud Development Kit (AWS CDK) v2

这是 AWS CDK v2 开发者指南。旧版 CDK v1 于 2022 年 6 月 1 日进入维护阶段,并于 2023 年 6 月 1 日终止支持。

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

示例:使用 AWS CDK 创建 AWS Fargate 服务

在此示例中,我们将向您展示如何创建在 Amazon Elastic Container Service (Amazon ECS) 集群上运行的 AWS Fargate 服务,该集群采用来自 Amazon ECR 上映像的面向互联网的应用程序负载均衡器作为前端。

Amazon ECS 是一项高度可扩展的快速容器管理服务,它可轻松运行、停止和管理群集上的 Docker 容器。您可以通过使用 Fargate 启动类型启动服务或任务,将集群托管在由 Amazon ECS 管理的无服务器基础设施上。若要进行更多控制,您可以在使用 Amazon EC2 启动类型进行管理的 Amazon Elastic Compute Cloud(Amazon EC2)实例集群上托管您的任务。

在此示例中,我们使用 Fargate 启动类型启动一些服务。如果您曾使用 AWS 管理控制台创建 Fargate 服务,就会了解要完成该任务需要遵循许多步骤。AWS 有几个教程和文档主题可以指导您创建 Fargate 服务,包括:

本示例会使用 AWS CDK 创建类似的 Fargate 服务。

本示例中使用的 Amazon ECS 构造通过提供以下好处来帮助您使用 AWS 服务:

  • 自动配置负载均衡器。

  • 自动为负载均衡器打开安全组。这使负载均衡器无需显式创建安全组即可与实例通信。

  • 自动对服务与附加到目标组的负载均衡器之间的依赖项进行排序,其中 AWS CDK 强制执行在创建实例之前创建侦听器的正确顺序。

  • 自动配置自动扩缩组的用户数据。这将创建正确的配置以将集群关联到 AMI。

  • 尽早验证参数组合。这样可以更早地暴露 AWS CloudFormation 问题,从而节省部署时间。例如,根据任务的不同,很容易出现内存设置配置不当的情况。以前,在部署应用程序之前,我们不会遇到错误。但是现在,当我们合成应用程序时,AWS CDK 可能会检测到配置错误并发出错误。

  • 如果我们使用来自 Amazon ECR 的映像,会自动为 Amazon Elastic Container Registry(Amazon ECR)添加权限。

  • 自动扩缩。AWS CDK 提供了一种方法,这样我们就可以在使用 Amazon EC2 集群时自动扩缩实例。当我们在 Fargate 集群中使用实例时,会自动发生这种情况。

    此外,当自动扩展尝试停止实例,但任务正在运行或已安排在该实例上时,AWS CDK 可以防止实例被删除。

    以前,我们必须创建 Lambda 函数才能实现此功能。

  • 提供资产支持,这样我们就可以一步将源从机器部署到 Amazon ECS。以前,要使用应用程序源,我们必须手动执行几个步骤,例如上传到 Amazon ECR 和创建 Docker 映像。

重要

我们将要使用的 ApplicationLoadBalancedFargateService 构造包括许多 AWS 组件,其中一些组件如果留在 AWS 账户中预置,即使我们不使用它们,也会产生不小的费用。如果您按照本示例操作,请务必清理资源 (cdk destroy)。

创建 CDK 项目

我们首先创建一个 CDK 项目。这是一个存储 AWS CDK 代码的目录,包括 CDK 应用程序。

TypeScript
mkdir MyEcsConstruct cd MyEcsConstruct cdk init --language typescript
JavaScript
mkdir MyEcsConstruct cd MyEcsConstruct cdk init --language javascript
Python
mkdir MyEcsConstruct cd MyEcsConstruct cdk init --language python source .venv/bin/activate # On Windows, run '.\venv\Scripts\activate' instead pip install -r requirements.txt
Java
mkdir MyEcsConstruct cd MyEcsConstruct cdk init --language java

我们现在可以将 Maven 项目导入 IDE。

C#
mkdir MyEcsConstruct cd MyEcsConstruct cdk init --language csharp

我们现在可以在 Visual Studio 中打开 src/MyEcsConstruct.sln 了。

接下来,我们将运行应用程序并确认它创建了一个空堆栈。

cdk synth

创建 Fargate 服务

我们可以通过两种不同的方式使用 Amazon ECS 运行容器任务:

  • 使用 Fargate 启动类型,此时 Amazon ECS 为我们管理运行容器的物理机。

  • 使用 EC2 启动类型,此时我们进行管理,例如指定自动扩缩。

在本例中,我们将创建一个在 Amazon ECS 集群上运行的 Fargate 服务,该集群采用面向互联网的应用程序负载均衡器作为前端。

我们将以下 AWS 构造库模块导入添加到堆栈文件中:

TypeScript

文件:lib/my_ecs_construct-stack.ts

import * as ec2 from "aws-cdk-lib/aws-ec2"; import * as ecs from "aws-cdk-lib/aws-ecs"; import * as ecs_patterns from "aws-cdk-lib/aws-ecs-patterns";
JavaScript

文件:lib/my_ecs_construct-stack.js

const ec2 = require("aws-cdk-lib/aws-ec2"); const ecs = require("aws-cdk-lib/aws-ecs"); const ecs_patterns = require("aws-cdk-lib/aws-ecs-patterns");
Python

文件:my_ecs_construct/my_ecs_construct_stack.py

from aws_cdk import (aws_ec2 as ec2, aws_ecs as ecs, aws_ecs_patterns as ecs_patterns)
Java

文件:src/main/java/com/myorg/MyEcsConstructStack.java

import software.amazon.awscdk.services.ec2.*; import software.amazon.awscdk.services.ecs.*; import software.amazon.awscdk.services.ecs.patterns.*;
C#

文件:src/MyEcsConstruct/MyEcsConstructStack.cs

using Amazon.CDK.AWS.EC2; using Amazon.CDK.AWS.ECS; using Amazon.CDK.AWS.ECS.Patterns;

在堆栈中,我们添加了以下代码:

TypeScript
const vpc = new ec2.Vpc(this, "MyVpc", { maxAzs: 3 // Default is all AZs in region }); const cluster = new ecs.Cluster(this, "MyCluster", { vpc: vpc }); // Create a load-balanced Fargate service and make it public new ecs_patterns.ApplicationLoadBalancedFargateService(this, "MyFargateService", { cluster: cluster, // Required cpu: 512, // Default is 256 desiredCount: 6, // Default is 1 taskImageOptions: { image: ecs.ContainerImage.fromRegistry("amazon/amazon-ecs-sample") }, memoryLimitMiB: 2048, // Default is 512 publicLoadBalancer: true // Default is true });
JavaScript
const vpc = new ec2.Vpc(this, "MyVpc", { maxAzs: 3 // Default is all AZs in region }); const cluster = new ecs.Cluster(this, "MyCluster", { vpc: vpc }); // Create a load-balanced Fargate service and make it public new ecs_patterns.ApplicationLoadBalancedFargateService(this, "MyFargateService", { cluster: cluster, // Required cpu: 512, // Default is 256 desiredCount: 6, // Default is 1 taskImageOptions: { image: ecs.ContainerImage.fromRegistry("amazon/amazon-ecs-sample") }, memoryLimitMiB: 2048, // Default is 512 publicLoadBalancer: true // Default is true });
Python
vpc = ec2.Vpc(self, "MyVpc", max_azs=3) # default is all AZs in region cluster = ecs.Cluster(self, "MyCluster", vpc=vpc) ecs_patterns.ApplicationLoadBalancedFargateService(self, "MyFargateService", cluster=cluster, # Required cpu=512, # Default is 256 desired_count=6, # Default is 1 task_image_options=ecs_patterns.ApplicationLoadBalancedTaskImageOptions( image=ecs.ContainerImage.from_registry("amazon/amazon-ecs-sample")), memory_limit_mib=2048, # Default is 512 public_load_balancer=True) # Default is True
Java
Vpc vpc = Vpc.Builder.create(this, "MyVpc") .maxAzs(3) // Default is all AZs in region .build(); Cluster cluster = Cluster.Builder.create(this, "MyCluster") .vpc(vpc).build(); // Create a load-balanced Fargate service and make it public ApplicationLoadBalancedFargateService.Builder.create(this, "MyFargateService") .cluster(cluster) // Required .cpu(512) // Default is 256 .desiredCount(6) // Default is 1 .taskImageOptions( ApplicationLoadBalancedTaskImageOptions.builder() .image(ContainerImage.fromRegistry("amazon/amazon-ecs-sample")) .build()) .memoryLimitMiB(2048) // Default is 512 .publicLoadBalancer(true) // Default is true .build();
C#
var vpc = new Vpc(this, "MyVpc", new VpcProps { MaxAzs = 3 // Default is all AZs in region }); var cluster = new Cluster(this, "MyCluster", new ClusterProps { Vpc = vpc }); // Create a load-balanced Fargate service and make it public new ApplicationLoadBalancedFargateService(this, "MyFargateService", new ApplicationLoadBalancedFargateServiceProps { Cluster = cluster, // Required DesiredCount = 6, // Default is 1 TaskImageOptions = new ApplicationLoadBalancedTaskImageOptions { Image = ContainerImage.FromRegistry("amazon/amazon-ecs-sample") }, MemoryLimitMiB = 2048, // Default is 256 PublicLoadBalancer = true // Default is true } );

接下来,我们通过运行以下命令合成堆栈,以验证代码:

cdk synth

堆栈有数百行,所以我们不在这里显示。堆栈应包含一个默认实例、三个可用区的私有子网和公有子网以及一个安全组。

要部署堆栈,请运行以下命令:

cdk deploy

AWS CloudFormation 显示有关它在部署应用程序时所执行的数十个步骤的信息。

部署完成后,我们成功创建了由 Fargate 提供支持的 Amazon ECS 服务运行 Docker 映像。

清理

作为一般维护的最佳实践,为了最大限度地减少不必要的成本,我们会在完成任务后将堆栈删除:

cdk destroy