运行 Fargate 上使用 CDK 的两个容器
Running two containers on Fargate using CDK
我想使用 Fargate 来 运行 两个容器 - 一个用于主项目的后端,另一个用于数据库 (MongoDB)。 GitHub 存储库中包含的 The basic example 展示了如何使用 CDK 运行 Fargate 上的单个容器,但是我仍然有 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
});
}
}
提前致谢。
一般来说,运行不建议在 Fargate 容器中连接数据库,因为目前没有好的持久化数据解决方案。您 可以 集成一个钩子,在任务停止之前将数据复制到 S3 之类的东西中,但通常这种解决方案非常脆弱,不推荐使用。
您可能想查看 DocumentDB 作为 运行 自己的 MongoDB 实例的替代方法,尽管 CDK 中对 DocumentDB 构造的支持尚未完全充实。
另一种选择是 运行 常规 ECS 任务并在您的 EC2 实例上附加 EBS 卷。然后您可以使用 docker volumes 将 EBS 卷挂载到您的容器中。使用这种方法,您需要标记实例元数据并使用 ECS 放置约束来确保您的任务放置在附加了 EBS 卷的实例上。
如果这些方法中的任何一种适合您,请随时在 CDK repository 上打开功能请求。希望这对您有所帮助!
AWS Fargate 是硬性要求吗?
如果没有,你可以选择简单的ECS + Ec2,它supports使用持久数据卷:
Fargate tasks only support nonpersistent storage volumes.
For EC2 tasks, use data volumes in the following common examples:
- To provide persistent data volumes for use with a container
- To define an empty, nonpersistent data volume and mount it on multiple containers
- To share defined data volumes at different locations on different containers on the same container instance
- To provide a data volume to your task that is managed by a third-party volume driver
我自己没试过,不过好像CDK对ECS + Ec2的支持比较稳定
PS 基本示例的 link 已损坏,我试图找到新位置但在新 example repository 中没有成功。
我想使用 Fargate 来 运行 两个容器 - 一个用于主项目的后端,另一个用于数据库 (MongoDB)。 GitHub 存储库中包含的 The basic example 展示了如何使用 CDK 运行 Fargate 上的单个容器,但是我仍然有 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
});
}
}
提前致谢。
一般来说,运行不建议在 Fargate 容器中连接数据库,因为目前没有好的持久化数据解决方案。您 可以 集成一个钩子,在任务停止之前将数据复制到 S3 之类的东西中,但通常这种解决方案非常脆弱,不推荐使用。
您可能想查看 DocumentDB 作为 运行 自己的 MongoDB 实例的替代方法,尽管 CDK 中对 DocumentDB 构造的支持尚未完全充实。
另一种选择是 运行 常规 ECS 任务并在您的 EC2 实例上附加 EBS 卷。然后您可以使用 docker volumes 将 EBS 卷挂载到您的容器中。使用这种方法,您需要标记实例元数据并使用 ECS 放置约束来确保您的任务放置在附加了 EBS 卷的实例上。
如果这些方法中的任何一种适合您,请随时在 CDK repository 上打开功能请求。希望这对您有所帮助!
AWS Fargate 是硬性要求吗?
如果没有,你可以选择简单的ECS + Ec2,它supports使用持久数据卷:
Fargate tasks only support nonpersistent storage volumes.
For EC2 tasks, use data volumes in the following common examples:
- To provide persistent data volumes for use with a container
- To define an empty, nonpersistent data volume and mount it on multiple containers
- To share defined data volumes at different locations on different containers on the same container instance
- To provide a data volume to your task that is managed by a third-party volume driver
我自己没试过,不过好像CDK对ECS + Ec2的支持比较稳定
PS 基本示例的 link 已损坏,我试图找到新位置但在新 example repository 中没有成功。