在 Amazon ECS 上部署容器 Web 应用程序
入门指南
模块 2:创建基础设施并部署应用程序
在本模块中,您将创建一个 ECS 集群并使用 CDK 部署应用程序
简介
在本模块中,您将创建一个 AWS CDK 应用程序(该应用程序将创建设置 ECS 集群所需的所有基础设施),并向其部署示例容器。
您将学到的内容
- 创建简单的 CDK 应用程序
- 创建使用 Fargate 提供容量的 ECS 集群
- 创建任务定义和服务来部署我们的应用程序
完成所需时间
15 分钟
模块先决条件
- 具有管理员级访问权限的 AWS 账户**
- 推荐的浏览器:最新版 Chrome 或 Firefox
[**] 过去 24 小时内创建的账户可能尚不具有访问此教程所需服务的权限。
实施
创建 CDK 应用程序
首先,确保您已安装 CDK。如果您没有安装该应用程序,请遵照 AWS CDK 入门操作:
cdk --version
现在,我们将 TypeScript 用作我们选择的语言,创建框架 CDK 应用程序。在终端中运行以下命令:
mkdir cdk-ecs-infra
cd cdk-ecs-infra
cdk init app --language typescript
这将输出以下内容:
Applying project template app for typescript
# Welcome to your CDK TypeScript project!
This is a blank project for TypeScript development with CDK.
The `cdk.json` file tells the CDK Toolkit how to execute your app.
## Useful commands
* `npm run build` compile typescript to js
* `npm run watch` watch for changes and compile
* `npm run test` perform the jest unit tests
* `cdk deploy` deploy this stack to your default AWS account/region
* `cdk diff` compare deployed stack with current state
* `cdk synth` emits the synthesized CloudFormation template
Executing npm install...
✅ All done!
为资源堆栈创建代码
前往文件 /lib/cdk-ecs-infra-stack.ts,您将在该文件中为您即将创建的资源堆栈编写代码。
资源堆栈是一组云基础设施资源(在特定情况下,它们将为所有的 AWS 资源),将预置到特定账户中。预置这些资源所在的账户/区域可以在堆栈中配置(如 AWS CDK 入门指南中所述)。
在此资源堆栈中,您将创建以下资源:
- IAM 角色:此角色将被分配至容器,以允许它调用其他 AWS 服务。
- ECS 任务定义:启动容器时使用的具体参数。
- Fargate 负载均衡服务的 ECS 模式:此模式抽离了创建集群、负载均衡器、服务所需的所有组件的复杂性,并将所有组件配置为协同工作。
创建 ECS 集群
要开始创建 ECS 集群,首选需要导入正确的模块:
npm i @aws-cdk/aws-s3-assets
然后在您的 lib/cdk-eb-infra-stack.ts 文件中,将依赖项添加到文件顶部。
npm i @aws-cdk/aws-ec2 @aws-cdk/aws-ecs @aws-cdk/aws-ecs-patterns @aws-cdk/aws-iam
然后,您需要编辑 lib/cdk-eb-infra-stack.ts 文件以在文件顶部添加依赖项:
import ecs = require('@aws-cdk/aws-ecs'); // Allows working with ECS resources
import ec2 = require('@aws-cdk/aws-ec2'); // Allows working with EC2 and VPC resources
import iam = require('@aws-cdk/aws-iam'); // Allows working with IAM resources
import ecsPatterns = require('@aws-cdk/aws-ecs-patterns') // Helper to create ECS services with loadbalancers, and configure them
这些模块为您提供了对您部署 Web 应用程序所需的所有组件的访问权限。第一步是通过添加以下代码,在您的账户中查找现有的默认 VPC:
// Look up the default VPC
const vpc = ec2.Vpc.fromLookup(this, "VPC", {
isDefault: true
});
接下来,您需要定义要使用的容器以及应该如何配置它。这通过创建任务定义以提供容器端口、它需要的 CPU 和内存量以及要使用的容器映像来完成。对于本指南,我们将在 SampleApp 文件夹中构建随示例应用程序提供的容器映像,并通过 CDK 为我们管理容器的构建、上传和部署。我们还将创建一个空的 IAM 角色以附加到未来指南的任务定义。
要创建任务定义和 IAM 角色,请添加以下代码:
const taskIamRole = new iam.Role(this, "AppRole", {
roleName: "AppRole",
assumedBy: new iam.ServicePrincipal('ecs-tasks.amazonaws.com'),
});
const taskDefinition = new ecs.FargateTaskDefinition(this, 'Task', {
taskRole: taskIamRole,
});
taskDefinition.addContainer('MyContainer', {
image: ecs.ContainerImage.fromAsset('../SampleApp'),
portMappings: [{ containerPort: 80 }],
memoryReservationMiB: 256,
cpu : 256,
});
在上面的代码中,您可以看到,您通过使用 FargateTaskDefintion 和使用 ContainerImage.fromAsset 指定了要部署到 Fargate 的任务定义类型。CDK 将使用 SampleApp 目录中的 Dockerfile 来构建容器映像。
接下来,您需要设置 ECS 集群、定义服务、创建负载均衡器、配置它以连接到该服务,并设置所需的安全组规则。ECS 中的服务用于通过指定所需的副本数、部署策略和其他配置来启动任务定义。在这个例子中,我们将只启动容器的 1 个副本。安全组充当实例的虚拟防火墙以控制入站和出站流量,但您无需对其进行配置,因为您正在使用的 ECS 模式会为您完成此操作。
将以下代码添加到任务定义下方的项目中:
new ecsPatterns.ApplicationLoadBalancedFargateService(this, "MyApp", {
vpc: vpc,
taskDefinition: taskDefinition,
desiredCount: 1,
serviceName: 'MyWebApp',
assignPublicIp: true,
publicLoadBalancer: true,
})
您将传入之前查找的 vpc 对象,以指定在何处创建所有资源,以及定义要部署哪个容器映像的任务定义。desiredCount 表示您想要的副本数量、serviceName 表示您希望使用的服务名称,并且 publicLoadBalancer 设置为 true 以便您可以通过互联网访问它。 在此示例中,将 assignPublicIp 设置为 true 的行很重要,因为我们使用的是没有私有子网的默认 VPC。最佳实践建议在私有子网中启动服务,但本指南未涉及此内容。
您现在已准备好部署 Web 应用程序,但首先,您需要在要部署到的账户上设置 CDK。
编辑 bin/cdk-ecs-infra.ts 文件,并取消注释第 14 行:
env: { account: process.env.CDK_DEFAULT_ACCOUNT, region: process.env.CDK_DEFAULT_REGION },
这将使用在 AWS CLI 中配置的账户 ID 和区域。在使用 CDK 之前,您需要先对其进行引导 - 这将为 CDK 创建所需的基础设施,以管理您账户中的基础设施。要引导 CDK,请运行 cdk bootstrap。您应会收到类似如下的输出:
cdk bootstrap
#output
⏳ Bootstrapping environment aws://0123456789012/<region>...
✅ Environment aws://0123456789012/<region> bootstrapped
这将为 CDK 创建所需的基础设施以管理您账户中的基础设施 - 如果您不熟悉设置 CDK 应用程序,我们建议您阅读 AWS CDK 入门指南。
引导完成后,您将运行 cdk deploy 来部署容器、集群和所需的所有其他基础设施。您应会收到类似如下的输出:

CDK 将在创建基础设施之前提示您,因为它会创建更改安全配置的基础设施 - 在您的案例中,将通过创建 IAM 角色和安全组的方式进行提示。按 y,然后按 Enter 进行部署。CDK 现在将设置您定义的所有基础设施,这将需要几分钟时间才能完成。
在它运行时,您将看到如下更新:

运行完成后,您将看到包含公共 URL 链接的输出,可从中访问您的服务,如下所示:

完整代码示例
import * as cdk from '@aws-cdk/core';
import ecs = require('@aws-cdk/aws-ecs');
import ec2 = require('@aws-cdk/aws-ec2');
import iam = require('@aws-cdk/aws-iam');
import ecsPatterns = require('@aws-cdk/aws-ecs-patterns')
export class CdkEcsInfraStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// Look up the default VPC
const vpc = ec2.Vpc.fromLookup(this, "VPC", {
isDefault: true
});
const taskIamRole = new iam.Role(this, "AppRole", {
roleName: "AppRole",
assumedBy: new iam.ServicePrincipal('ecs-tasks.amazonaws.com'),
});
const taskDefinition = new ecs.FargateTaskDefinition(this, 'Task', {
taskRole: taskIamRole,
});
taskDefinition.addContainer('MyContainer', {
image: ecs.ContainerImage.fromAsset('../SampleApp'),
portMappings: [{ containerPort: 80 }],
memoryReservationMiB: 256,
cpu : 256,
});
new ecsPatterns.ApplicationLoadBalancedFargateService(this, "MyApp", {
vpc: vpc,
taskDefinition: taskDefinition,
desiredCount: 1,
serviceName: 'MyWebApp',
assignPublicIp: true,
publicLoadBalancer: true,
})
}
}