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

Posted

技术标签:

【中文标题】CDK Fargate:将子域映射到不同的容器端口【英文标题】:CDK Fargate: Map subdomain to different container port 【发布时间】:2021-12-12 19:05:55 【问题描述】:

看下面的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。

我怎样才能做到这一点?

【问题讨论】:

【参考方案1】:

我可以用以下方法解决它

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

【讨论】:

哇,似乎有很多与问题不严格相关的额外代码。我的答案是否不适用于为子域指定端口? @gshpychka 不,没有用。我必须移植 80 和 containerPort 3000。可能是 CDK 中的错误 出了什么问题? @gshpychka 50x 错误 好的,我明白了。有趣,谢谢。

以上是关于CDK Fargate:将子域映射到不同的容器端口的主要内容,如果未能解决你的问题,请参考以下文章

Nginx 多个子域名映射到不同的端口或 ip

将新映像推送到 ECR 存储库时如何自动部署到 ECS Fargate

将本地端口映射子域名

将本地端口映射子域名

触发 Fargate 处理上传到 S3 的文件

frp使用不同子域名映射本地的多个服务