Answer a question

I'd like to use Fargate to run two containers - one for the main project's backend, and another for the database (MongoDB). The basic example included in the GitHub repo shows how to run a single container on Fargate using CDK, however I still have 2 issues:

  1. The example doesn't show how to run two containers.
  2. I'd like to scale the database containers but have them share the data storage (so that the data gets stored in a central place and stays synchronized between the different containers).

I've figured out how to (sort of) fixed the first issue, similarly to how ecs.LoadBalancedFargateService is implemented, however the second issue still remains.

For reference, this is what I have so far in stack.ts (the rest is the basic boilerplate cdk init app --language typescript generates for you):

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
        });
    }
}

Thanks in advance.

Answers

Generally, running a database in a Fargate container is not recommended since there is not currently a good solution for persisting data. You could integrate a hook that copies data into something like S3 prior to a task stopping, but generally those kinds of solutions are very fragile and not recommended.

You may want to check out DocumentDB as an alternative to running your own MongoDB instances, though support for DocumentDB constructs in the CDK are not yet fully fleshed out.

Another alternative is to run regular ECS tasks and attach an EBS volume on your EC2 Instance. Then you can use docker volumes to mount the EBS volume to your container. With this approach, you'll need to tag the instance metadata and use an ECS placement constraint to ensure that your task gets placed on the instance that has the EBS volume attached.

If either of these approaches works for you, feel free to open a feature request on the CDK repository. Hope this helps!

Logo

MongoDB社区为您提供最前沿的新闻资讯和知识内容

更多推荐