我正在使用AWS CDK来创建一个应该是简单的基础设施:
- 单个EC2实例;
- 从Docker镜像运行web服务器;
- 使用弹性容器服务(ECS)所以我不必管理容器
我可以让它全部启动并运行,但无法到达web服务器(例如通过访问浏览器中的EC2实例的IP,或与wget
),我无法找出为什么我无法到达它。
我尝试过/发现过的事情:
- 在同一个CDK脚本中,我可以直接创建一个EC2实例,运行docker映像,并通过Internet连接到它。因此,图像和VPC正常工作。
- 我在任务定义中尝试了
AWS_VPC
和BRIDGE
网络模式,结果相同(一切运行,但我无法连接到服务器) - 如果我使用
AWS_VPC
模式,我最终有两个网络接口与我的EC2实例相关联。即使我确保两者都有允许传入端口80流量的安全组,我仍然不能直接连接到EC2实例。 我已经看过所有的官方ecs和ec2的例子。我正在做同样的事情,这些例子正在做,虽然没有一个例子似乎建立一个web可见的服务器。 - 我已经阅读了ecs和ec2的CDK文档,但在那里找不到解释。
- 我已经对网络进行了并排比较& &;可以访问的普通EC2实例的安全设置与不能的EC2-由ecs管理的实例的安全设置——它们在功能上似乎是等同的。
容器之外的一切似乎都被设置为能够通过web与EC2实例交谈,所以我假设这是关于任务/容器本身的事情。我最好的猜测是,它与任务的网络模式有关,但我还没有找到一个配置或文档,让我得到答案。
有没有人知道为什么我不能到达这个EC2实例?或者有任何示例CDK脚本做类似的事情供参考?
这里是最小的CDK脚本,我希望在一个可达的web服务器(但没有),使用演示nginx容器作为hello-world:
import {
Stack,
StackProps,
aws_ec2 as ec2,
aws_ecs as ecs,
} from 'aws-cdk-lib';
import { Construct } from 'constructs';
export class MyStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
// VPC
const vpc = new ec2.Vpc(this, 'VPC', {
enableDnsSupport: true,
enableDnsHostnames: true,
subnetConfiguration: [{ name: 'PublicSubnet', subnetType: ec2.SubnetType.PUBLIC }],
});
// ECS
const cluster = new ecs.Cluster(this, 'Cluster', {
vpc,
capacity: {
instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.NANO),
machineImage: ecs.EcsOptimizedImage.amazonLinux(),
desiredCapacity: 1,
},
});
cluster.connections.allowFromAnyIpv4(ec2.Port.tcp(80));
// TASK DEFINITION
const taskDefinition = new ecs.Ec2TaskDefinition(this, 'TaskDef', {
networkMode: ecs.NetworkMode.AWS_VPC,
});
const container = taskDefinition.addContainer('HelloWorldContainer', {
image: ecs.ContainerImage.fromRegistry('nginxdemos/hello'),
memoryReservationMiB: 256,
portMappings: [
{
containerPort: 80,
protocol: ecs.Protocol.TCP,
},
],
});
const service = new ecs.Ec2Service(this, 'Service', {
cluster,
taskDefinition,
});
service.connections.allowFromAnyIpv4(ec2.Port.tcp(80));
}
}
终于找到了答案:
要直接连接到由ECS管理的EC2实例,任务Network Mode需要为"host";。这样就可以像使用普通的EC2实例一样使用实例。
回想起来,相关的文档非常清楚,我只是第一次没有完全理解它们。