ECS任务无法访问公网资源

问题描述 投票:0回答:1

我有以下设置:

  • 具有底层 EC2 实例的 ECS 集群
  • 连接到我的 vpc 的互联网网关
  • 我的 igw 和公共子网之间的路由表关联

目前,我的 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,但没有效果。另外,我对不同的网络配置也不是很了解。

我希望你们能够帮助我解决这个问题 - 非常感谢!

amazon-web-services docker amazon-ecs
1个回答
0
投票

您正在使用

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 网关相比,这将花费您多少费用。

© www.soinside.com 2019 - 2024. All rights reserved.