2

我想使用 Fargate 运行两个容器 - 一个用于主项目的后端,另一个用于数据库 (MongoDB)。GitHub 存储库中包含的基本示例展示了如何使用 CDK 在 Fargate 上运行单个容器,但是我仍然有 2 个问题:

  1. 该示例未显示如何运行两个容器。
  2. 我想扩展数据库容器,但让它们共享数据存储(以便数据存储在一个中心位置并在不同容器之间保持同步)。

我已经想出了如何(某种程度上)解决第一个问题,类似于如何ecs.LoadBalancedFargateService实施,但是第二个问题仍然存在。

作为参考,这是我到目前为止所拥有的stack.ts(其余的是cdk init app --language typescript为您生成的基本样板):

import cdk = require("@aws-cdk/cdk");
import ec2 = require("@aws-cdk/aws-ec2");
import ecs = require("@aws-cdk/aws-ecs");
import elbv2 = require("@aws-cdk/aws-elasticloadbalancingv2");

const {ApplicationProtocol} = elbv2;

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

        // Create VPC and Fargate Cluster
        const vpc = new ec2.VpcNetwork(this, "FargateVPC", {
            maxAZs: 2
        });
        const cluster = new ecs.Cluster(this, "Cluster", {vpc});

        // Create task definition
        const fargateTaskDefinition = new ecs.FargateTaskDefinition(this, "FargateTaskDef", {
            memoryMiB: "512",
            cpu: "256"
        });

        // Create container from local `Dockerfile`
        const appContainer = fargateTaskDefinition.addContainer("Container", {
            image: ecs.ContainerImage.fromAsset(this, "Image", {
                directory: ".."
            })
        });
        // Set port mapping
        appContainer.addPortMappings({
            containerPort: 5000
        });

        // Create container from DockerHub image
        const mongoContainer = fargateTaskDefinition.addContainer("MongoContainer", {
            image: ecs.ContainerImage.fromDockerHub("mongo")
        });
        // Set port mapping
        mongoContainer.addPortMappings({
            containerPort: 27017
        });

        // Create service
        const service = new ecs.FargateService(this, "Service", {
            cluster,
            taskDefinition: fargateTaskDefinition,
            desiredCount: 2
        });

        // Configure task auto-scaling      
        const scaling = service.autoScaleTaskCount({
            maxCapacity: 5
        });
        scaling.scaleOnCpuUtilization("CpuScaling", {
            targetUtilizationPercent: 70
        });

        // Create service with built-in load balancer
        const loadBalancer = new elbv2.ApplicationLoadBalancer(this, "AppLB", {
            vpc,
            internetFacing: true
        });
        // Allow incoming connections
        loadBalancer.connections.allowFromAnyIPv4(new ec2.TcpPort(5000), "Allow inbound HTTP");

        // Create a listener and listen to incoming requests
        const listener = loadBalancer.addListener("Listener", {
            port: 5000,
            protocol: ApplicationProtocol.Http
        });
        listener.addTargets("ServiceTarget", {
            port: 5000,
            protocol: ApplicationProtocol.Http,
            targets: [service]
        });

        // Output the DNS where you can access your service
        new cdk.Output(this, "LoadBalancerDNS", {
            value: loadBalancer.dnsName
        });
    }
}

提前致谢。

4

2 回答 2

1

通常,不建议在 Fargate 容器中运行数据库,因为目前没有很好的数据持久化解决方案。您可以集成一个钩子,在任务停止之前将数据复制到 S3 之类的东西中,但通常这些解决方案非常脆弱,不推荐使用。

您可能希望查看DocumentDB作为运行您自己的 MongoDB 实例的替代方案,尽管 CDK 中对 DocumentDB 构造的支持尚未完全充实。

另一种选择是运行常规 ECS 任务并在您的 EC2 实例上附加 EBS 卷。然后,您可以使用 docker 卷将 EBS 卷挂载到您的容器中。使用这种方法,您需要标记实例元数据并使用 ECS 放置约束来确保您的任务被放置在附加了 EBS 卷的实例上。

如果这些方法中的任何一种对您有用,请随时在CDK 存储库上打开功能请求。希望这可以帮助!

于 2019-02-07T22:21:14.903 回答
0

AWS Fargate 是硬性要求吗?

如果没有,您可以选择简单的 ECS + Ec2,它支持使用持久数据卷:

Fargate 任务仅支持非持久性存储卷。

对于 EC2 任务,请在以下常见示例中使用数据卷:

  • 提供与容器一起使用的持久数据卷
  • 定义一个空的非持久数据卷并将其挂载到多个容器上
  • 在同一个容器实例的不同容器的不同位置共享定义的数据卷
  • 为您的任务提供由第三方卷驱动程序管理的数据卷

我自己没有尝试过,但似乎CDK对ECS + Ec2有稳定的支持。

PS基本示例的链接已损坏,我试图找到新位置,但在新示例存储库中没有成功。

于 2020-02-01T08:36:42.533 回答