高级 ECS 建构库 CDK
AWS CDK v1在2023-06-01上达到了支持结束. 此软件包不再更新,用户应该迁移到 AWS CDK v2.
关于如何移徙的更多信息,请参见: 移动到 AWS CDK v2 指南。 。 。 .
这个库提供更高级的亚马逊ECS构造,遵循共同的建筑模式. 它包含:
- 应用程序负载平衡服务
- 网络负载平衡服务
- 队列处理服务
- 计划任务( 长期任务)
- 其他实例
应用程序负载平衡服务
要定义应用程序负载平衡器背后的 Amazon ECS 服务,请立即跳出以下之一:
ApplicationLoadBalancedEc2Service
declare const cluster: ecs.Cluster;
const loadBalancedEcsService = new ecsPatterns.ApplicationLoadBalancedEc2Service(this, 'Service', {
cluster,
memoryLimitMiB: 1024,
taskImageOptions: {
image: ecs.ContainerImage.fromRegistry('test'),
environment: {
TEST_ENVIRONMENT_VARIABLE1: "test environment variable 1 value",
TEST_ENVIRONMENT_VARIABLE2: "test environment variable 2 value",
},
},
desiredCount: 2,
});
ApplicationLoadBalancedFargateService
declare const cluster: ecs.Cluster;
const loadBalancedFargateService = new ecsPatterns.ApplicationLoadBalancedFargateService(this, 'Service', {
cluster,
memoryLimitMiB: 1024,
cpu: 512,
taskImageOptions: {
image: ecs.ContainerImage.fromRegistry("amazon/amazon-ecs-sample"),
},
});
loadBalancedFargateService.targetGroup.configureHealthCheck({
path: "/custom-health-path",
});
CDK将创建一个新的ECS集群. 如果您部署多个服务 CDK 将只创建每个 VPC 一个集群 .
可以省略 cluster 财务报告和审定财务报表 vpc 使 CDK 创建一个新的带有两个 AZ 的 VPC ,并在 VPC 内部创建一个集群 .
您可以自定义对象群的健康检查; 否则默认为 HTTP 超过端口 80 点击路径 /。 。 。 .
远门服务将使用 LATEST 平台版本默认,但您可以通过提供值来覆盖 platformVersion 建构器中的属性.
远端服务使用默认 VPC 安全组, 除非使用 securityGroups 建构器中的属性.
通过设置 redirectHTTP 至 true, CDK 将在端口 80 上自动创建一个将 HTTP 流量重定向到 HTTPS 端口的收听器.
如果您指定了选项 recordType 您可以决定是否要使用 CNAME 或 Route53-Aliases 作为记录集.
如果您需要加密负载平衡器和ECS任务之间的流量,您可以设置 targetProtocol 改为 HTTPS。 。 。 .
此外,如果需要多个应用目标群体,则立即采取以下一种:
ApplicationMultipleTargetGroupsEc2Service
// One application load balancer with one listener and two target groups.
declare const cluster: ecs.Cluster;
const loadBalancedEc2Service = new ecsPatterns.ApplicationMultipleTargetGroupsEc2Service(this, 'Service', {
cluster,
memoryLimitMiB: 256,
taskImageOptions: {
image: ecs.ContainerImage.fromRegistry("amazon/amazon-ecs-sample"),
},
targetGroups: [
{
containerPort: 80,
},
{
containerPort: 90,
pathPattern: 'a/b/c',
priority: 10,
},
],
});
ApplicationMultipleTargetGroupsFargateService
// One application load balancer with one listener and two target groups.
declare const cluster: ecs.Cluster;
const loadBalancedFargateService = new ecsPatterns.ApplicationMultipleTargetGroupsFargateService(this, 'Service', {
cluster,
memoryLimitMiB: 1024,
cpu: 512,
taskImageOptions: {
image: ecs.ContainerImage.fromRegistry("amazon/amazon-ecs-sample"),
},
targetGroups: [
{
containerPort: 80,
},
{
containerPort: 90,
pathPattern: 'a/b/c',
priority: 10,
},
],
});
网络负载平衡服务
要定义网络负载平衡器背后的亚马逊ECS服务,请即时跳出以下之一: 1
NetworkLoadBalancedEc2Service
declare const cluster: ecs.Cluster;
const loadBalancedEcsService = new ecsPatterns.NetworkLoadBalancedEc2Service(this, 'Service', {
cluster,
memoryLimitMiB: 1024,
taskImageOptions: {
image: ecs.ContainerImage.fromRegistry('test'),
environment: {
TEST_ENVIRONMENT_VARIABLE1: "test environment variable 1 value",
TEST_ENVIRONMENT_VARIABLE2: "test environment variable 2 value",
},
},
desiredCount: 2,
});
NetworkLoadBalancedFargateService
declare const cluster: ecs.Cluster;
const loadBalancedFargateService = new ecsPatterns.NetworkLoadBalancedFargateService(this, 'Service', {
cluster,
memoryLimitMiB: 1024,
cpu: 512,
taskImageOptions: {
image: ecs.ContainerImage.fromRegistry("amazon/amazon-ecs-sample"),
},
});
CDK 将创建一个新的 Amazon ECS 集群, 如果您指定了 VPC 并省略 cluster。如果您部署多种服务,CDK将只创建一个集群.
若为 cluster 财务报告和审定财务报表 vpc cDK创建了一个新的VPC,在两个可提供区和本VPC内的一个集群中设有子网.
如果您指定了选项 recordType 您可以决定是否要使用 CNAME 或 Route53-Aliases 作为记录集.
此外,如果需要一个以上的网络目标群体,则立即采取以下行动之一:
- 网络多目标组 Ec2 服务
// Two network load balancers, each with their own listener and target group.
declare const cluster: ecs.Cluster;
const loadBalancedEc2Service = new ecsPatterns.NetworkMultipleTargetGroupsEc2Service(this, 'Service', {
cluster,
memoryLimitMiB: 256,
taskImageOptions: {
image: ecs.ContainerImage.fromRegistry("amazon/amazon-ecs-sample"),
},
loadBalancers: [
{
name: 'lb1',
listeners: [
{
name: 'listener1',
},
],
},
{
name: 'lb2',
listeners: [
{
name: 'listener2',
},
],
},
],
targetGroups: [
{
containerPort: 80,
listener: 'listener1',
},
{
containerPort: 90,
listener: 'listener2',
},
],
});
- 网络多目标组
// Two network load balancers, each with their own listener and target group.
declare const cluster: ecs.Cluster;
const loadBalancedFargateService = new ecsPatterns.NetworkMultipleTargetGroupsFargateService(this, 'Service', {
cluster,
memoryLimitMiB: 512,
taskImageOptions: {
image: ecs.ContainerImage.fromRegistry("amazon/amazon-ecs-sample"),
},
loadBalancers: [
{
name: 'lb1',
listeners: [
{
name: 'listener1',
},
],
},
{
name: 'lb2',
listeners: [
{
name: 'listener2',
},
],
},
],
targetGroups: [
{
containerPort: 80,
listener: 'listener1',
},
{
containerPort: 90,
listener: 'listener2',
},
],
});
队列处理服务
要定义创建队列并从队列中读取的服务,请即时跳出以下之一:
QueueProcessingEc2Service
declare const cluster: ecs.Cluster;
const queueProcessingEc2Service = new ecsPatterns.QueueProcessingEc2Service(this, 'Service', {
cluster,
memoryLimitMiB: 1024,
image: ecs.ContainerImage.fromRegistry('test'),
command: ["-c", "4", "amazon.com"],
enableLogging: false,
desiredTaskCount: 2,
environment: {
TEST_ENVIRONMENT_VARIABLE1: "test environment variable 1 value",
TEST_ENVIRONMENT_VARIABLE2: "test environment variable 2 value",
},
maxScalingCapacity: 5,
containerName: 'test',
});
QueueProcessingFargateService
declare const cluster: ecs.Cluster;
const queueProcessingFargateService = new ecsPatterns.QueueProcessingFargateService(this, 'Service', {
cluster,
memoryLimitMiB: 512,
image: ecs.ContainerImage.fromRegistry('test'),
command: ["-c", "4", "amazon.com"],
enableLogging: false,
desiredTaskCount: 2,
environment: {
TEST_ENVIRONMENT_VARIABLE1: "test environment variable 1 value",
TEST_ENVIRONMENT_VARIABLE2: "test environment variable 2 value",
},
maxScalingCapacity: 5,
containerName: 'test',
});
当用户未提供队列时, CDK 将创建主队列和死信队列, 并带有默认的再驱动策略, 并附加任务权限, 以便访问主队列 .
计划任务
要确定一项定期执行的任务,有两个选项:
ScheduledEc2Task
// Instantiate an Amazon EC2 Task to run at a scheduled interval
declare const cluster: ecs.Cluster;
const ecsScheduledTask = new ecsPatterns.ScheduledEc2Task(this, 'ScheduledTask', {
cluster,
scheduledEc2TaskImageOptions: {
image: ecs.ContainerImage.fromRegistry('amazon/amazon-ecs-sample'),
memoryLimitMiB: 256,
environment: { name: 'TRIGGER', value: 'CloudWatch Events' },
},
schedule: appscaling.Schedule.expression('rate(1 minute)'),
enabled: true,
ruleName: 'sample-scheduled-task-rule',
});
ScheduledFargateTask
declare const cluster: ecs.Cluster;
const scheduledFargateTask = new ecsPatterns.ScheduledFargateTask(this, 'ScheduledFargateTask', {
cluster,
scheduledFargateTaskImageOptions: {
image: ecs.ContainerImage.fromRegistry('amazon/amazon-ecs-sample'),
memoryLimitMiB: 512,
},
schedule: appscaling.Schedule.expression('rate(1 minute)'),
platformVersion: ecs.FargatePlatformVersion.LATEST,
});
其他实例
除了使用构造,用户还可以添加逻辑来自定义这些构造:
在应用程序LoadBalancedFargateService上配置 HTTPS
import { HostedZone } from '@aws-cdk/aws-route53';
import { Certificate } from '@aws-cdk/aws-certificatemanager';
import { SslPolicy } from '@aws-cdk/aws-elasticloadbalancingv2';
const domainZone = HostedZone.fromLookup(this, 'Zone', { domainName: 'example.com' });
const certificate = Certificate.fromCertificateArn(this, 'Cert', 'arn:aws:acm:us-east-1:123456:certificate/abcdefg');
declare const vpc: ec2.Vpc;
declare const cluster: ecs.Cluster;
const loadBalancedFargateService = new ecsPatterns.ApplicationLoadBalancedFargateService(this, 'Service', {
vpc,
cluster,
certificate,
sslPolicy: SslPolicy.RECOMMENDED,
domainName: 'api.example.com',
domainZone,
redirectHTTP: true,
taskImageOptions: {
image: ecs.ContainerImage.fromRegistry("amazon/amazon-ecs-sample"),
},
});
在应用程序LoadBalancedFargateService中添加基于时间表的自动缩放
declare const cluster: ecs.Cluster;
const loadBalancedFargateService = new ecsPatterns.ApplicationLoadBalancedFargateService(this, 'Service', {
cluster,
memoryLimitMiB: 1024,
desiredCount: 1,
cpu: 512,
taskImageOptions: {
image: ecs.ContainerImage.fromRegistry("amazon/amazon-ecs-sample"),
},
});
const scalableTarget = loadBalancedFargateService.service.autoScaleTaskCount({
minCapacity: 5,
maxCapacity: 20,
});
scalableTarget.scaleOnSchedule('DaytimeScaleDown', {
schedule: appscaling.Schedule.cron({ hour: '8', minute: '0'}),
minCapacity: 1,
});
scalableTarget.scaleOnSchedule('EveningRushScaleUp', {
schedule: appscaling.Schedule.cron({ hour: '20', minute: '0'}),
minCapacity: 10,
});
在应用程序LoadBalancedFargate Service中添加基于计量的自动缩放
declare const cluster: ecs.Cluster;
const loadBalancedFargateService = new ecsPatterns.ApplicationLoadBalancedFargateService(this, 'Service', {
cluster,
memoryLimitMiB: 1024,
desiredCount: 1,
cpu: 512,
taskImageOptions: {
image: ecs.ContainerImage.fromRegistry("amazon/amazon-ecs-sample"),
},
});
const scalableTarget = loadBalancedFargateService.service.autoScaleTaskCount({
minCapacity: 1,
maxCapacity: 20,
});
scalableTarget.scaleOnCpuUtilization('CpuScaling', {
targetUtilizationPercent: 50,
});
scalableTarget.scaleOnMemoryUtilization('MemoryScaling', {
targetUtilizationPercent: 50,
});
更改默认的部署控制器
declare const cluster: ecs.Cluster;
const loadBalancedFargateService = new ecsPatterns.ApplicationLoadBalancedFargateService(this, 'Service', {
cluster,
memoryLimitMiB: 1024,
desiredCount: 1,
cpu: 512,
taskImageOptions: {
image: ecs.ContainerImage.fromRegistry("amazon/amazon-ecs-sample"),
},
deploymentController: {
type: ecs.DeploymentControllerType.CODE_DEPLOY,
},
});
部署断路和回滚
亚马逊ECS 部署断路器
自动减少不健康的服务部署,而不需要人工干预。 使用 circuitBreaker 启用
部署断路器和可选启用 rollback 自动回滚。 见 使用部署断路器
更多细节.
declare const cluster: ecs.Cluster;
const service = new ecsPatterns.ApplicationLoadBalancedFargateService(this, 'Service', {
cluster,
memoryLimitMiB: 1024,
desiredCount: 1,
cpu: 512,
taskImageOptions: {
image: ecs.ContainerImage.fromRegistry("amazon/amazon-ecs-sample"),
},
circuitBreaker: { rollback: true },
});
在队列处理中设置部署配置 服务
declare const cluster: ecs.Cluster;
const queueProcessingFargateService = new ecsPatterns.QueueProcessingFargateService(this, 'Service', {
cluster,
memoryLimitMiB: 512,
image: ecs.ContainerImage.fromRegistry('test'),
command: ["-c", "4", "amazon.com"],
enableLogging: false,
desiredTaskCount: 2,
environment: {},
maxScalingCapacity: 5,
maxHealthyPercent: 200,
minHealthyPercent: 66,
});
设置任务子网和任务安全组
declare const vpc: ec2.Vpc;
declare const securityGroup: ec2.SecurityGroup;
const queueProcessingFargateService = new ecsPatterns.QueueProcessingFargateService(this, 'Service', {
vpc,
memoryLimitMiB: 512,
image: ecs.ContainerImage.fromRegistry('test'),
securityGroups: [securityGroup],
taskSubnets: { subnetType: ec2.SubnetType.PRIVATE_ISOLATED },
});
定义 QueeProcessingFargate Service 的公共 IP 任务
declare const vpc: ec2.Vpc;
const queueProcessingFargateService = new ecsPatterns.QueueProcessingFargateService(this, 'Service', {
vpc,
memoryLimitMiB: 512,
image: ecs.ContainerImage.fromRegistry('test'),
assignPublicIp: true,
});
为 QueeProcessingFargate Service 定义自定义队列参数的任务
declare const vpc: ec2.Vpc;
const queueProcessingFargateService = new ecsPatterns.QueueProcessingFargateService(this, 'Service', {
vpc,
memoryLimitMiB: 512,
image: ecs.ContainerImage.fromRegistry('test'),
maxReceiveCount: 42,
retentionPeriod: Duration.days(7),
visibilityTimeout: Duration.minutes(5),
});
设置 QueecuringFargate Services 的容量配置策略
declare const cluster: ecs.Cluster;
cluster.enableFargateCapacityProviders();
const queueProcessingFargateService = new ecsPatterns.QueueProcessingFargateService(this, 'Service', {
cluster,
memoryLimitMiB: 512,
image: ecs.ContainerImage.fromRegistry('test'),
capacityProviderStrategies: [
{
capacityProvider: 'FARGATE_SPOT',
weight: 2,
},
{
capacityProvider: 'FARGATE',
weight: 1,
},
],
});
为 QueeProcessingFargate Service 设置自定义的容器级别健康检查
declare const vpc: ec2.Vpc;
declare const securityGroup: ec2.SecurityGroup;
const queueProcessingFargateService = new ecsPatterns.QueueProcessingFargateService(this, 'Service', {
vpc,
memoryLimitMiB: 512,
image: ecs.ContainerImage.fromRegistry('test'),
healthCheck: {
command: [ "CMD-SHELL", "curl -f http://localhost/ || exit 1" ],
// the properties below are optional
interval: Duration.minutes(30),
retries: 123,
startPeriod: Duration.minutes(30),
timeout: Duration.minutes(30),
},
});
设置排队处理的容量
import * as autoscaling from '@aws-cdk/aws-autoscaling';
const vpc = new ec2.Vpc(this, 'Vpc', { maxAzs: 1 });
const cluster = new ecs.Cluster(this, 'EcsCluster', { vpc });
const autoScalingGroup = new autoscaling.AutoScalingGroup(this, 'asg', {
vpc,
instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.MICRO),
machineImage: ecs.EcsOptimizedImage.amazonLinux2(),
});
const capacityProvider = new ecs.AsgCapacityProvider(this, 'provider', {
autoScalingGroup,
});
cluster.addAsgCapacityProvider(capacityProvider);
const queueProcessingFargateService = new ecsPatterns.QueueProcessingFargateService(this, 'Service', {
cluster,
memoryLimitMiB: 512,
image: ecs.ContainerImage.fromRegistry('test'),
capacityProviderStrategies: [
{
capacityProvider: capacityProvider.capacityProviderName,
},
],
});
选择应用程序LoadBalancedFargate Service 的特定 vpc 子网
declare const cluster: ecs.Cluster;
const loadBalancedFargateService = new ecsPatterns.ApplicationLoadBalancedFargateService(this, 'Service', {
cluster,
memoryLimitMiB: 1024,
desiredCount: 1,
cpu: 512,
taskImageOptions: {
image: ecs.ContainerImage.fromRegistry("amazon/amazon-ecs-sample"),
},
taskSubnets: {
subnets: [ec2.Subnet.fromSubnetId(this, 'subnet', 'VpcISOLATEDSubnet1Subnet80F07FA0')],
},
});
设置已排定的远端任务平台
declare const cluster: ecs.Cluster;
const scheduledFargateTask = new ecsPatterns.ScheduledFargateTask(this, 'ScheduledFargateTask', {
cluster,
scheduledFargateTaskImageOptions: {
image: ecs.ContainerImage.fromRegistry('amazon/amazon-ecs-sample'),
memoryLimitMiB: 512,
},
schedule: appscaling.Schedule.expression('rate(1 minute)'),
platformVersion: ecs.FargatePlatformVersion.VERSION1_4,
});
设置任务列表的安全组
const vpc = new ec2.Vpc(this, 'Vpc', { maxAzs: 1 });
const cluster = new ecs.Cluster(this, 'EcsCluster', { vpc });
const securityGroup = new ec2.SecurityGroup(this, 'SG', { vpc });
const scheduledFargateTask = new ecsPatterns.ScheduledFargateTask(this, 'ScheduledFargateTask', {
cluster,
scheduledFargateTaskImageOptions: {
image: ecs.ContainerImage.fromRegistry('amazon/amazon-ecs-sample'),
memoryLimitMiB: 512,
},
schedule: appscaling.Schedule.expression('rate(1 minute)'),
securityGroups: [securityGroup],
});
使用 REMOVE DEFAULT DESIRED COUNT 特性旗
REMOVE DEFAULT DESIRED COUNT 特性旗用于覆盖由 CDK 自动生成的默认所期望的状态 。 这将设定以下任何构造所创建的任何服务的预期对象为未定义.
- 应用程序 LoadBalancedEc2 服务
- 应用程序 LoadBalancedFargate Service
- 网络LoadBalancedEc2服务
- 网络LoadBalancedFargate服务
- 队列处理 Ec2 服务
- 队列处理 Fargate 服务
如果一个理想的Count没有作为对上述构造的输入被传递,CloudFormation要么创建一个新的服务开始一个理想的Count 1,要么更新一个现有的服务开始一个与更新之前相同的理想的Count.
为启用特性旗, 确保应用程序堆栈上下文中的 REMOVE DEFAULT DESIRED COUNT 旗帜设置为真实, 如 :
declare const stack: Stack;
stack.node.setContext(cxapi.ECS_REMOVE_DEFAULT_DESIRED_COUNT, true);
以下是使用启用的REMOVE DEFAULT DESIRED COUNT功能旗的应用程序实例 :
import { App, Stack } from '@aws-cdk/core';
import * as ec2 from '@aws-cdk/aws-ec2';
import * as ecs from '@aws-cdk/aws-ecs';
import * as ecsPatterns from '@aws-cdk/aws-ecs-patterns';
import * as cxapi from '@aws-cdk/cx-api';
import * as path from 'path';
const app = new App();
const stack = new Stack(app, 'aws-ecs-patterns-queue');
stack.node.setContext(cxapi.ECS_REMOVE_DEFAULT_DESIRED_COUNT, true);
const vpc = new ec2.Vpc(stack, 'VPC', {
maxAzs: 2,
});
new ecsPatterns.QueueProcessingFargateService(stack, 'QueueProcessingService', {
vpc,
memoryLimitMiB: 512,
image: new ecs.AssetImage(path.join(__dirname, '..', 'sqs-reader')),
});
部署应用程序和度量衡车
下面是部署一个应用程序以及一个使用 dockerLabels 用于发现:
declare const cluster: ecs.Cluster;
declare const vpc: ec2.Vpc;
const service = new ecsPatterns.ApplicationLoadBalancedFargateService(this, 'Service', {
cluster,
vpc,
desiredCount: 1,
taskImageOptions: {
image: ecs.ContainerImage.fromRegistry("amazon/amazon-ecs-sample"),
dockerLabels: {
'application.label.one': 'first_label',
'application.label.two': 'second_label',
},
},
});
service.taskDefinition.addContainer('Sidecar', {
image: ecs.ContainerImage.fromRegistry('example/metrics-sidecar'),
});
选择特定的负载平衡器名称应用程序LoadBalancedFargateService
declare const cluster: ecs.Cluster;
const loadBalancedFargateService = new ecsPatterns.ApplicationLoadBalancedFargateService(this, 'Service', {
cluster,
memoryLimitMiB: 1024,
desiredCount: 1,
cpu: 512,
taskImageOptions: {
image: ecs.ContainerImage.fromRegistry("amazon/amazon-ecs-sample"),
},
taskSubnets: {
subnets: [ec2.Subnet.fromSubnetId(this, 'subnet', 'VpcISOLATEDSubnet1Subnet80F07FA0')],
},
loadBalancerName: 'application-lb-name',
});