为什么我的 ECS 服务无法向我的 ELB 注册可用的 EC2 实例?

Why can't my ECS service register available EC2 instances with my ELB?

我有一个构建 ECS 优化 AMI 的 EC2 启动配置。我有一个自动缩放组,可确保我始终至少有两个可用实例。最后,我有一个负载均衡器。

我正在尝试创建一个 ECS 服务,将我的任务分配到负载均衡器中的各个实例。

阅读 ECS 负载平衡的文档后,我的理解是我的 ASG 不应自动将我的 EC2 实例注册到 ELB,因为 ECS 会处理这件事。所以,我的 ASG 没有指定 ELB。同样,我的 ELB 没有任何已注册的 EC2 实例。

创建 ECS 服务时,我选择了 ELB 以及 select ecsServiceRole。创建服务后,我从未在 ECS 实例选项卡中看到任何可用实例。该服务也无法启动任何任务,出现非常普遍的错误...

服务无法放置任务,因为找不到资源。

我已经在这个问题上待了大约两天了,似乎无法弄清楚哪些配置设置没有正确配置。有没有人知道什么可能导致它不起作用?

更新 @ 06/25/2015:

我认为这可能与ECS_CLUSTER用户数据设置有关。

在我的 EC2 自动缩放启动配置中,如果我将用户数据输入完全留空,则创建的实例的 ECS_CLUSTER 值为 "default"。发生这种情况时,我会看到一个自动创建的集群,名为 "default"。在这个默认集群中,我看到了实例并且可以像预期的那样向 ELB 注册任务。一旦任务注册到 ELB,我的 ELB 健康检查 (HTTP) 就通过了,一切都很好。

但是,如果我将 ECS_CLUSTER 设置更改为自定义设置,我将永远看不到使用该名称创建的集群。如果我手动创建一个具有该名称的集群,实例将永远不会在集群中可见。在这种情况下,我无法向 ELB 注册任务。

有什么想法吗?

最后,我的 EC2 实例没有被分配 public IP 地址。看起来 ECS 需要能够直接与每个 EC2 实例通信,这将要求每个实例都有一个 public IP。我没有分配我的容器实例 public IP 地址,因为我认为我会将它们全部放在 public 负载平衡器后面,并且每个容器实例都是私有的。

可能出现的另一个问题是没有将具有适当策略的角色分配给启动配置。我的角色没有 AmazonEC2ContainerServiceforEC2Role 策略(或其包含的权限),如 specified here

也可能是 ECS 代理在 /var/lib/ecs/data 中创建了一个文件来存储集群名称。

如果代理首先以 'default' 的集群名称启动,您需要删除此文件,然后重新启动代理。

我有类似的症状,但最终在日志文件中找到了答案:

/var/log/ecs/ecs-agent.2016-04-06-03:

2016-04-06T03:05:26Z [ERROR] Error registering: AccessDeniedException: User: arn:aws:sts::<removed>:assumed-role/<removed>/<removed is not authorized to perform: ecs:RegisterContainerInstance on resource: arn:aws:ecs:us-west-2:<removed:cluster/MyCluster-PROD
    status code: 400, request id: <removed>

就我而言,资源存在但无法访问。听起来 OP 指向不存在或不可见的资源。你们的集群和实例在同一个地域吗?日志应确认详细信息。

回应其他帖子:

您不需要 public IP 地址。

您确实需要:ecsServiceRole 或分配给 EC2 实例的等效 IAM 角色,以便与 ECS 服务对话。您还必须指定 ECS 集群,并且可以在实例启动或启动配置定义期间通过用户数据完成,如下所示:

#!/bin/bash
echo ECS_CLUSTER=GenericSericeECSClusterPROD >> /etc/ecs/ecs.config

如果您在新启动的实例上执行此操作失败,您可以在实例启动后执行此操作,然后重新启动服务。

在我们的案例中存在几层问题。我会把它们列出来,这样可能会让您对要解决的问题有所了解。

我的监狱是在 1 台主机上有 1 个 ECS。但是 ECS 强制您在 VPC 下有 2 个子网,每个子网有 1 个 docker 主机实例。我试图在 1 个可用区中仅拥有 1 docker 主机,但无法使其正常工作。

然后另一个问题是,只有一个子网有一个面向 Internet 的附加网关。因此无法从 public 访问其中之一。

最终结果是 DNS 为我的 ELB 提供了 2 个 IP。其中一个 IP 可以工作,而另一个则不能。因此,在使用 public DNS 访问 NLB 时,我看到了随机 404。

您绝对不需要每个私有实例的 public IP 地址。正确(也是最安全)的方法是设置 NAT 网关并将该网关附加到附加到您的私有子网的路由 table。

这在 VPC 文档中有详细记录,特别是 Scenario 2: VPC with Public and Private Subnets (NAT)