ApplicationLoadBalancedEc2Service无法在集群中注册的问题。

0

【以下的问题经过翻译处理】 我有一个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());
profile picture
专家
已提问 5 个月前13 查看次数
1 回答
0

【以下的回答经过翻译处理】 从代码中可以看出,我使用的是默认的亚马逊Linux镜像。它不是自定义镜像或特殊的AMI。

但这似乎与ECS集群要求不兼容。修复方法很简单:通过切换EcsOptimizedImage对象,我可以启动一个满足要求的ECS镜像。一旦我部署了它,我就看到它已经注册到集群中,我的镜像也开始运行。我还有很多其他问题要解决,它仍然没有完全运行,但至少它现在已经注册到集群中了。

profile picture
专家
已回答 5 个月前

您未登录。 登录 发布回答。

一个好的回答可以清楚地解答问题和提供建设性反馈,并能促进提问者的职业发展。

回答问题的准则