【以下的问题经过翻译处理】 我有一个CDK脚本,尝试创建ECS集群、任务和ApplicationLoadBalancedEc2Service,但是当我部署它时,Ec2实例被创建,但未注册到LB目标组或集群。因此,我的任务从未启动。它还在完成了67个服务中的65个服务之后卡住了,无法结束。我认为这是因为Ec2实例没有注册到集群,因此没有启动任何内容,CDK脚本正在等待它变为健康状态。我还发现我的任务在比较与我的ECS JSON配置文件时没有分配CPU、OS或内存。
我真正不理解的是哪个部分创建了Ec2实例?是addCapacity调用声明Ec2机器的规格吗?如果是这样,为什么它不会自动注册到集群呢?还是ApplicationLoadBalancedEc2Service构造函数?如果是这样,为什么不使用.cluster()
方法将其注册到集群?如果创建它,它怎么知道什么是需要启动的Ec2规格?
这是我的脚本
.maxAzs(2) // Default is all AZs in region
.natGateways(1)
.enableDnsHostnames(true)
.enableDnsSupport(true)
.ipAddresses(IpAddresses.cidr("10.0.0.0/16"))
.subnetConfiguration(Arrays.asList(
SubnetConfiguration.builder()
.name("Web")
.subnetType(SubnetType.PUBLIC)
.cidrMask(24)
.build(),
SubnetConfiguration.builder()
.name("App")
.subnetType(SubnetType.PRIVATE_WITH_EGRESS)
.cidrMask(24)
.build(),
SubnetConfiguration.builder()
.name("Storage")
.subnetType(SubnetType.PRIVATE_WITH_EGRESS)
.cidrMask(24)
.build()
))
.build();
vpc.addGatewayEndpoint("s3Endpoint", GatewayVpcEndpointOptions.builder()
.service(GatewayVpcEndpointAwsService.S3)
.build());
vpc.addInterfaceEndpoint("ssmEndpoint", InterfaceVpcEndpointOptions.builder()
.service(InterfaceVpcEndpointAwsService.SSM)
.privateDnsEnabled(true)
.build());
vpc.addInterfaceEndpoint("cloudWatchEndpoint", InterfaceVpcEndpointOptions.builder()
.service(InterfaceVpcEndpointAwsService.CLOUDWATCH)
.privateDnsEnabled(true)
.build());
vpc.addInterfaceEndpoint("ec2MessagesEndpoint", InterfaceVpcEndpointOptions.builder()
.service(InterfaceVpcEndpointAwsService.EC2_MESSAGES)
.privateDnsEnabled(true)
.build());
ILogGroup appLogGroup = LogGroup.fromLogGroupName(this, "my." + settings.getEnv() + ".archiver", "my." + settings.getEnv() + ".archiver");
if( appLogGroup == null ) {
appLogGroup = new LogGroup(this, "my." + settings.getEnv() + ".archiver", LogGroupProps.builder()
.logGroupName("my." + settings.getEnv() + ".archiver")
.retention(RetentionDays.ONE_YEAR)
.build());
}
IHostedZone domainZone = HostedZone.fromLookup(this, getStackId(), HostedZoneProviderProps
.builder()
.domainName(settings.get("hostname"))
.build());
Cluster cluster = Cluster.Builder.create(this, "MyAppCluster")
.containerInsights(true)
.capacity(AddCapacityOptions.builder()
.vpcSubnets(SubnetSelection.builder().subnets(vpc.getPrivateSubnets()).build())
.desiredCapacity(1)
.minCapacity(1)
.maxCapacity(1)
.instanceType(InstanceType.of(InstanceClass.T3A, InstanceSize.LARGE))
.machineImage(MachineImage.latestAmazonLinux())
.machineImageType(MachineImageType.AMAZON_LINUX_2)
.keyName(settings.get("ssh.key.name"))
.build())
.vpc(vpc)
.build();
ICertificate myAppCert = Certificate.fromCertificateArn(this, settings.get("ssl.key.id"), settings.get("ssl.key.arn") );
Ec2TaskDefinition appTask = Ec2TaskDefinition.Builder.create(this, "MyAppTask")
.family("MyApp")
.networkMode(NetworkMode.AWS_VPC)
.executionRole(Role.fromRoleArn(this,
settings.get("execution.role.id"),
settings.get("execution.role.arn")))
.build();
ContainerDefinition container = appTask.addContainer("MyApp-" + settings.getEnv(), ContainerDefinitionOptions.builder()
.image(ContainerImage.fromRegistry("ecr.repo.url/myApp:1.8.0"))
.essential(true)
.cpu(2048)
.memoryLimitMiB(4096)
.memoryReservationMiB(1024)
.portMappings(Arrays.asList(
portMapping(8443,8443),
portMapping(8080,8080),
portMapping(9013,9013),
portMapping(9012,9012)
))
.logging(LogDriver.awsLogs(AwsLogDriverProps.builder()
.logGroup(appLogGroup)
.streamPrefix("MyApp-" + settings.getEnv() + "-")
.build()))
.build());
ApplicationLoadBalancedEc2Service ec2 = ApplicationLoadBalancedEc2Service.Builder
.create(this, "MyAppService")
.cluster(cluster) // I thought this point of this was to allow the Ec2 instance to registered with the cluster?!
.taskDefinition(appTask)
.cpu(2048)
.memoryReservationMiB(1024)
.memoryLimitMiB(16000 )
.desiredCount(1)
.domainName(settings.get("hostname"))
.domainZone(domainZone)
.certificate( myAppCert )
.redirectHttp(true)
.protocol(ApplicationProtocol.HTTPS)
.targetProtocol(ApplicationProtocol.HTTPS)
.publicLoadBalancer(true)
.build();
ec2.getTargetGroup().configureHealthCheck(HealthCheck.builder()
.path("/health-check.txt")
.interval(Duration.minutes(2))
.enabled(true)
.unhealthyThresholdCount(5)
.port("8443")
.protocol(Protocol.HTTPS)
.build());