使用 CDK 定义具有服务发现功能的 ECS Fargate 集群,无需负载均衡器

Cla*_*dio 13 amazon-web-services amazon-ecs aws-cdk

我们使用CDK,并且开始在 ECS 服务中使用服务发现(因此,服务器到服务器而不是客户端到服务器)。这意味着我们不需要 ALB(至少目前,也许我们可以稍后重新考虑这个选择)。

\n

不幸的是,用于构建 ECS 服务 ( ecs_patterns.ApplicationLoadBalancedFargateService) 的 CDK 模式也会创建 ALB,因此我们不能按原样使用它,我们需要自己创建这些 CDK 步骤。

\n

这个想法基本上是从 AWS 将本教程从使用 AWS CLI移植到使用 CDK。

\n

问题是:是否有人已经这样做并想要分享它或者知道 CDK Patterns 没有该选项的原因?

\n

(如果没有人打算共享它,我们会这样做,然后当然会共享它;我认为这个选项应该立即出现在 CDK 中,这只是不浪费时间“只是”配置问题的问题\xe2\x80\x93\xc2\xa0除非有一些我们在这里看不到的东西...)。

\n

Cla*_*dio 25

好的,所以最后比预想的要容易。这是我的最终解决方案(并查看评论,因为我被卡住了几次):

/*
 * ECS Fargate with service discovery but without Load Balancing
 */
import * as cdk from "@aws-cdk/core";
import * as ec2 from "@aws-cdk/aws-ec2";
import * as ecs from "@aws-cdk/aws-ecs";
import * as servicediscovery from "@aws-cdk/aws-servicediscovery";
import * as iam from "@aws-cdk/aws-iam";
import * as logs from "@aws-cdk/aws-logs";
import { DnsRecordType } from "@aws-cdk/aws-servicediscovery";

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

    const serviceName = "zambulo";
    const namespace = "caludio.magic";

    const vpc = ec2.Vpc.fromLookup(this, "VPC", {
      isDefault: true,
    });

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

    const dnsNamespace = new servicediscovery.PrivateDnsNamespace(
      this,
      "DnsNamespace",
      {
        name: namespace,
        vpc: vpc,
        description: "Private DnsNamespace for my Microservices",
      }
    );

    const taskrole = new iam.Role(this, "ecsTaskExecutionRole", {
      assumedBy: new iam.ServicePrincipal("ecs-tasks.amazonaws.com"),
    });

    taskrole.addManagedPolicy(
      iam.ManagedPolicy.fromAwsManagedPolicyName(
        "service-role/AmazonECSTaskExecutionRolePolicy"
      )
    );

    /*
     * Check the doc for the allowed cpu/mem combiations:
     * https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-ecs.FargateTaskDefinition.html
     */
    const serviceTaskDefinition = new ecs.FargateTaskDefinition(
      this,
      `${serviceName}ServiceTaskDef`,
      {
        cpu: 256,
        memoryLimitMiB: 512,
        taskRole: taskrole,
      }
    );

    const serviceLogGroup = new logs.LogGroup(
      this,
      `${serviceName}ServiceLogGroup`,
      {
        logGroupName: `/ecs/${serviceName}Service`,
        removalPolicy: cdk.RemovalPolicy.DESTROY,
      }
    );

    /* Fargate only support awslog driver */
    const serviceLogDriver = new ecs.AwsLogDriver({
      logGroup: serviceLogGroup,
      streamPrefix: `${serviceName}Service`,
    });

    /*
     * If you chose a public image from the registry (like in this case),
     * the `assignPublicIp` in the Fargate definition (below) must be true
     */
    const serviceContainer = serviceTaskDefinition.addContainer(
      `${serviceName}ServiceContainer`,
      {
        image: ecs.ContainerImage.fromRegistry("amazon/amazon-ecs-sample"),
        logging: serviceLogDriver,
      }
    );

    serviceContainer.addPortMappings({
      containerPort: 80,
    });

    const serviceSecGrp = new ec2.SecurityGroup(
      this,
      `${serviceName}ServiceSecurityGroup`,
      {
        allowAllOutbound: true,
        securityGroupName: `${serviceName}ServiceSecurityGroup`,
        vpc: vpc,
      }
    );

    serviceSecGrp.connections.allowFromAnyIpv4(ec2.Port.tcp(80));

    new ecs.FargateService(this, `${serviceName}Service`, {
      cluster: cluster,
      taskDefinition: serviceTaskDefinition,
      // Must be `true` when using public images
      assignPublicIp: true,
      // If you set it to 0, the deployment will finish succesfully anyway
      desiredCount: 1,
      securityGroup: serviceSecGrp,
      cloudMapOptions: {
        // This will be your service_name.namespace
        name: serviceName,
        cloudMapNamespace: dnsNamespace,
        dnsRecordType: DnsRecordType.A,
      },
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 那么,一个任务中的一个容器如何通过上述 DNS 设置来寻址另一个任务中的另一个容器呢? (3认同)
  • 我找到了另一种获取 **PrivateDnsNamespace** 的方法: `const dnsNamespace = cluster.addDefaultCloudMapNamespace({ vpc, name: namespace, type: servicediscovery.NamespaceType.DNS_PRIVATE });` (2认同)