#java #amazon-web-services #amazon-ec2 #amazon-ecs #aws-cdk
#java #amazon-веб-сервисы #amazon-ec2 #amazon-ecs #aws-cdk
Вопрос:
Нам нужно создать кластер ECS с EC2 и использовать существующий балансировщик нагрузки приложения.
После многих проб и ошибок мне удалось заставить его работать, однако он всегда создает дополнительную целевую группу по умолчанию на порту 80.
Это код, который у меня есть (с использованием Java в соответствии с требованиями):
cluster = Cluster.Builder.create(scope, "my-ecs-cluster")
.vpc(awsNetwork.getVpc())
.capacity(
AddCapacityOptions.builder()
.instanceType(new InstanceType("m5n.xlarge"))
.minCapacity(1)
.maxCapacity(1)
.desiredCapacity(1)
.associatePublicIpAddress(true)
.vpcSubnets(
SubnetSelection.builder()
.subnetType(SubnetType.PUBLIC)
.availabilityZones(Arrays.asList("us-west-2a", "us-west-2c"))
.build()
)
.build()
).build();
taskDefinition = Ec2TaskDefinition.Builder.create(scope, "my-taskDefinition")
.executionRole(Role.fromRoleArn(scope, "my-exec-role", "role-arn..."))
.build();
containerDef = ContainerDefinition.Builder.create(scope, "my-ecs-container")
.essential(true)
.memoryLimitMiB(2048)
.memoryReservationMiB(2048)
.image(ContainerImage.fromEcrRepository(
Repository.fromRepositoryName(scope,
"my-ecr",
"my-image"
),
"latest")
)
.taskDefinition(taskDefinition)
.build();
containerDef.addPortMappings(PortMapping.builder()
.hostPort(0)
.containerPort(443)
.protocol(Protocol.TCP)
.build());
taskDefinition.setDefaultContainer(containerDef);
ApplicationLoadBalancerLookupOptions balancerLookupOptions = ApplicationLoadBalancerLookupOptions.builder()
.loadBalancerArn("arn:aws:my-alb-arn")
.build();
loadBalancer = ApplicationLoadBalancer.fromLookup(scope, "my-alb", balancerLookupOptions);
balancedEc2Service = ApplicationLoadBalancedEc2Service.Builder.create(scope, "my-ec2-service")
.cluster(cluster)
.desiredCount(1)
.taskDefinition(taskDefinition)
.loadBalancer(loadBalancer)
.cpu(1)
.memoryLimitMiB(2048)
.build();
balancedEc2Service.getService().addPlacementStrategies(PlacementStrategy.spreadAcross("attribute:ecs.availability-zone", "instanceId"));
HealthCheck healthCheck = HealthCheck.builder()
.path("/healthCheck")
.protocol(software.amazon.awscdk.services.elasticloadbalancingv2.Protocol.HTTPS)
.port("traffic-port")
.unhealthyThresholdCount(2)
.interval(Duration.seconds(30))
.healthyThresholdCount(5)
.timeout(Duration.seconds(5))
.build();
balancedEc2Service.getTargetGroup().setHealthCheck(healthCheck);
ListenerCertificate listenerCertificate = ListenerCertificate.fromCertificateManager(Certificate.fromCertificateArn(scope, "dis-certificate-1", "arn:aws:acm:us-west-2:245459132561:certificate/d2962594-8a40-4f36-abd4-62a6d91d0250"));
ApplicationTargetGroup targetGroup = ApplicationTargetGroup.Builder.create(scope, "dis-receiver-targetGroup")
.protocol(ApplicationProtocol.HTTPS)
.port(443)
.healthCheck(healthCheck)
.vpc(awsNetwork.getVpc())
.build();
ApplicationListener.Builder.create(scope, "dis-receiver-listener")
.loadBalancer(loadBalancer)
.defaultTargetGroups(Collections.singletonList(targetGroup))
.protocol(ApplicationProtocol.HTTPS)
.port(443)
.certificates(Collections.singletonList(listenerCertificate))
.build();
balancedEc2Service.getService().attachToApplicationTargetGroup(targetGroup);
Одна из целевых групп — это та, которую я создал в коде.
Другая создается автоматически и указывает на порт 80:
Если вместо использования balancedEc2Service.getService().attachToApplicationTargetGroup(targetGroup);
я устанавливаю его непосредственно в сервис, например:
balancedEc2Service = ApplicationLoadBalancedEc2Service.Builder.create(scope, "my-ec2-service")
.cluster(cluster)
.desiredCount(1)
.taskDefinition(taskDefinition)
.loadBalancer(loadBalancer)
.cpu(1)
.memoryLimitMiB(2048)
// New code
.listenerPort(443)
.protocol(ApplicationProtocol.HTTPS)
.certificate(myCertificate)
.domainName(myDomainName)
.domainZone(myDomainZone)
//
.build();
Он создает только одну целевую группу и связан с портом 443 в ECS:
Однако сама целевая группа находится на порту 80, и поэтому время ожидания приложения истекает:
Как я могу настроить единую целевую группу, используя HTTPS?