我有以下设置:
目前,我的 API 前面有一个 API 网关,我使用服务发现将流量路由到 ECS 中的容器。
接着,我的集群位于公共子网中,主要原因是我试图尽可能节省成本,即放弃 NAT。
对于 ecs 中的底层 ec2 实例,关联了公共 IP,安全组仅允许来自 api 网关的入口,但允许所有出口流量。
我最初的想法是,我的容器实例访问公共端点(即 stripe api 和 cognito-idp)就足够了,但由于某种原因,我的容器实例没有公共互联网访问权限。
我的任务配置如下:
resource "aws_ecs_task_definition" "aws-ecs-api-task" {
family = "myservice-api-task"
container_definitions = <<DEFINITION
[
{
"name": "${local.api_container_name}",
"image": "${aws_ecr_repository.aws-ecr-api.repository_url}:latest",
"cpu": ${var.api_container_cpu},
"memory": ${var.api_container_memory},
"portMappings": [
{
"containerPort": ${var.api_container_port},
"hostPort": ${var.api_container_host_port}
}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "${aws_cloudwatch_log_group.api-log-group.id}",
"awslogs-region": "${var.region}",
"awslogs-stream-prefix": "${var.app_name}-${var.environment}"
}
},
"healthcheck": {
"command": ["CMD-SHELL", "curl -f http://localhost:${var.api_container_port}/api/1.0/general/version || exit 1"]
},
"essential": true,
"networkMode": "awsvpc"
}
]
DEFINITION
requires_compatibilities = ["EC2"]
network_mode = "awsvpc"
memory = var.api_container_memory
cpu = var.api_container_cpu
execution_role_arn = aws_iam_role.ecsTaskExecutionRole.arn
task_role_arn = aws_iam_role.ecs_task_role.arn
tags = {
Name = "${var.app_name}-ecs-api-task-definition"
Environment = var.environment
}
}
服务:
resource "aws_ecs_service" "aws-ecs-service_api" {
name = "ecs_service-api-${var.environment}"
cluster = var.ecs_cluster_id
task_definition = aws_ecs_task_definition.aws-ecs-api-task.arn
deployment_maximum_percent = 200 #during red/green it is allowed to spawn 200% of desired tasks
deployment_minimum_healthy_percent = 100 #always have one healthy pod
desired_count = var.api_container_desired_count
scheduling_strategy = "REPLICA"
force_new_deployment = false
capacity_provider_strategy {
capacity_provider = var.capacity_provider_name
weight = 100
base = 1
}
network_configuration {
subnets = var.ecs_service_subnet_ids
assign_public_ip = false
security_groups = [aws_security_group.ecs_service_api_sg.id]
}
service_registries {
registry_arn = aws_service_discovery_service.ecs-discovery-service.arn
port = var.api_container_port
}
tags = {
Name = "${var.app_name}-ecs_service-api"
Environment = var.environment
}
}
我尝试将网络类型更改为host,但没有效果。另外,我对不同的网络配置也不是很了解。
我希望你们能够帮助我解决这个问题 - 非常感谢!
您正在使用
awsvpc
网络模式。这意味着每个 ECS 任务都有自己的弹性网络接口 (ENI)。通过此配置,ECS 任务不使用底层 EC2 实例的网络连接,它们拥有自己的网络连接和自己的 IP 地址。
您当前正在 ECS 服务
network_configuration
块中禁用对 ECS 任务的公共 IP 分配。您需要将 assign_public_ip
更改为 true
,以便 ECS 为 ECS 任务的 ENI 分配公有 IP 地址,以便 ECS 任务可以访问 VPC 外部的资源。
“接下来,我的集群位于公共子网中,主要原因是我试图尽可能节省成本,即放弃 NAT。”
请注意,在不久的将来,AWS 将开始对您帐户中的每个公共 IP 进行收费,并且您可以通过将公共 IP 分配给 EC2 实例,然后使用
awsvpc
来加倍使用公共 IP。
网络模式也需要它们(如上所述)。您可能想计算一下与 NAT 网关相比,这将花费您多少费用。