CDK Fargate:将子域映射到不同的容器端口

CDK Fargate: Map subdomain to different container port

看下面的CDK栈定义:

export class AwsStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const myHostedZone = new route53.HostedZone(this, "HostedZone", {
      zoneName: domain,
    });

    const certificate = new acm.Certificate(this, "Certificate", {
      domainName: `*.${domain}`,
      validation: acm.CertificateValidation.fromDns(myHostedZone),
    });

    const image = new ecr.DockerImageAsset(this, "Image", { directory: "." });

    const vpc = new ec2.Vpc(this, "ApplicationVpc", { maxAzs: 2 });

    const cluster = new ecs.Cluster(this, "Cluster", {
      clusterName: "Cluster",
      vpc,
    });

    const taskDefinition = new ecs.FargateTaskDefinition(this, "TaskDef");
    taskDefinition.addContainer("DefaultContainer", {
      image: ecs.ContainerImage.fromDockerImageAsset(image),
      portMappings: [
        { containerPort: 3000, hostPort: 3000 },
        { containerPort: 3001, hostPort: 3001 },
      ],
    });

    const service = new ecsPatterns.ApplicationLoadBalancedFargateService(this, "Service", {
      cluster,
      publicLoadBalancer: true,
      taskDefinition,
      certificate,
    });

    service.loadBalancer.addRedirect()

    service.listener.addTargets("api", {
      priority: 10,
      conditions: [elb.ListenerCondition.hostHeaders([`api.${domain}`])],
      // what to do???
    });
  }
}

我想将 api.domain 的传入流量映射到端口 3001,其他所有内容都应映射到端口 3000。

我怎样才能做到这一点?

我可以用下面的方法解决它

export class AwsStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const zone = new route53.HostedZone(this, "HostedZone", {
      zoneName: domain,
    });

    //const certificate = acm.Certificate.fromCertificateArn(this, "Certificate", certificateArn);

    const certificate = new acm.Certificate(this, "Certificate", {
      domainName: domain,
      subjectAlternativeNames: [`*.${domain}`],
      validation: acm.CertificateValidation.fromDns(zone),
    });

    const image = new ecr.DockerImageAsset(this, "Image", { directory: "." });

    const vpc = new ec2.Vpc(this, "ApplicationVpc", { maxAzs: 2 });

    const cluster = new ecs.Cluster(this, "Cluster", {
      clusterName: "Cluster",
      vpc,
    });

    const taskDefinition = new ecs.FargateTaskDefinition(this, "TaskDef");
    taskDefinition.addContainer("DefaultContainer", {
      image: ecs.ContainerImage.fromDockerImageAsset(image),
      portMappings: [
        { containerPort: 3000, hostPort: 3000 },
        { containerPort: 3001, hostPort: 3001 },
      ],
      logging: new ecs.AwsLogDriver({
        streamPrefix: domain,
      }),
    });

    const service = new ecs.FargateService(this, "Service", {
      cluster,
      taskDefinition,
      assignPublicIp: true,
    });

    const lb = new elb.ApplicationLoadBalancer(this, "LoadBalancer", {
      vpc,
      internetFacing: true,
    });

    const listener = lb.addListener("Listener", {
      port: 443,
      certificates: [certificate],
    });

    listener.addTargets("API", {
      priority: 10,
      conditions: [elb.ListenerCondition.hostHeaders([`api.${domain}`])],
      port: 80,
      targets: [service.loadBalancerTarget({ containerName: "DefaultContainer", containerPort: 3001 })],
      healthCheck: {
        healthyHttpCodes: "200-399",
      },
    });

    listener.addTargets("UI", {
      port: 80,
      targets: [service.loadBalancerTarget({ containerName: "DefaultContainer", containerPort: 3000 })],
      healthCheck: {
        healthyHttpCodes: "200-399",
      },
    });

    new route53.ARecord(this, "AliasRecord", {
      zone,
      target: route53.RecordTarget.fromAlias(new alias.LoadBalancerTarget(lb)),
    });

    new route53.ARecord(this, "AliasRecordAPI", {
      recordName: `api.${domain}`,
      zone,
      target: route53.RecordTarget.fromAlias(new alias.LoadBalancerTarget(lb)),
    });
  }
}

我仍然想知道为什么 listener.addTargets 需要端口 80