如何获取本地ec2实例的container-instance-id

Posted

技术标签:

【中文标题】如何获取本地ec2实例的container-instance-id【英文标题】:How to get the container-instance-id of the local ec2 instance 【发布时间】:2018-10-17 06:05:28 【问题描述】:

我在重启之前运行以下 shell 命令来耗尽我的 ECS 实例:

INSTANCE_ID=$(curl http://169.254.169.254/latest/meta-data/instance-id)
aws ecs update-container-instances-state \
  --region eu-central-1 \
  --cluster mycluster \
  --status DRAINING \
  --container-instances $INSTANCE_ID

它给了我以下错误:

调用UpdateContainerInstancesState操作时出错(InvalidParameterException):instanceId小于36。

显然这是因为它需要与 ec2InstanceId 不同的 ECS containerInstanceId。找出本地机器的containerInstanceId最好的方法是什么?

到目前为止我想出的方法是

    使用aws ecs list-container-instances获取集群中的所有容器实例ID 使用aws ecs describe-container-instances获取对应的EC2实例ID 使用实例元数据 (http://169.254.169.254/latest/meta-data/instance-id) 找出本地 EC2 实例 ID 使用jq 结合grep 或其他工具进行过滤

这似乎有点复杂。有没有更简单的方法?

【问题讨论】:

我相信您应该输入容器实例 ID 而不是 EC2 实例 ID。容器实例 ID 如下所示:1c3be8ed-df30-47b4-8f1e-6e68ebd01f34。我从 AWS API 指南中提取了它:docs.aws.amazon.com/AmazonECS/latest/APIReference/… 你说得对。我通过使用 aws ecs list-container-instances,然后使用 aws ecs describe-container-instances 以及一些 grepping 和 awking 解决了这个问题。这么简单的任务似乎有点复杂 【参考方案1】:

另一个选项是在包含实例 ID 的实例上填充自定义属性。例如,在您的 /etc/ecs/ecs.config 中,您可能有以下内容:

ECS_INSTANCE_ATTRIBUTES=\"ec2_instance\":\"i-0000000000000000000\"

这可以与 list-container-instances--filter 参数一起使用来查找关联的容器实例。

aws ecs list-container-instances --cluster <MY Cluster> --filter attribute:ec2_instance==i-0000000000000000000

如果您使用的是 cfn-init 脚本和 CloudFormation,则可以在创建 EC2 实例时自动执行此操作。

....
MyLaunchConfiguration:
  Type: AWS::AutoScaling::LaunchConfiguration
  Metadata:
    AWS::CloudFormation::Init:
      config: 
        commands: 
          00_configure_ecs_agent:
            command: |
              #!/bin/bash
                echo ECS_INSTANCE_ATTRIBUTES=\"ec2_instance\":\"$(wget -q -O - http://169.254.169.254/latest/meta-data/instance-id)\" >> /etc/ecs/ecs.config
...

参考资料:

https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-agent-config.html https://docs.aws.amazon.com/cli/latest/reference/ecs/list-container-instances.html https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-init.html

【讨论】:

自发布以来,Jose 注意到现在有一​​个“ec2InstanceId”属性自动填充并可用于列表容器实例。无需对自定义属性大惊小怪。【参考方案2】:

如果您在实例上运行脚本,您可以从 ECS 代理的introspection API 中找到容器实例 ID。

如果您在 ECS 任务中运行脚本,则可以使用 container metadata file。

【讨论】:

【参考方案3】:

安装了jq,这相当简单。

使用ECS Container Introspection 端点,您可以获取这些值并将它们传递给aws ecs update-container-instances-state 命令。

在user data 中执行此操作并将结果添加到/etc/environment 中会很有用,因此它们始终可用。

#!/usr/bin/env bash
set -euo pipefail

CONTAINER_INSTANCE_ARN="$(curl -s --fail http://localhost:51678/v1/metadata | jq -er '.ContainerInstanceArn')"
CLUSTER="$(curl -s --fail http://localhost:51678/v1/metadata | jq -er '.Cluster')"

aws ecs update-container-instances-state --cluster "$CLUSTER" \
    --container-instances "$CONTAINER_INSTANCE_ARN" --status "DRAINING"

通过用户数据将它们添加到/etc/environment

cat<<-EOF>>/etc/environment
CONTAINER_INSTANCE_ARN="$(curl -s --fail http://localhost:51678/v1/metadata | jq -er '.ContainerInstanceArn')"
CLUSTER="$(curl -s --fail http://localhost:51678/v1/metadata | jq -er '.Cluster')"
EOF
source /etc/environment

注意事项:

jq -e flag 表示如果没有找到密钥,设置退出代码。 jq -r 标志表示将输出转储为原始文本而不是 json。

【讨论】:

【参考方案4】:

这是我用于此的 ruby​​ 代码:

require 'aws-sdk-ecs'

region = JSON.parse(`curl --silent http://169.254.169.254/latest/dynamic/instance-identity/document`)['region']
instance_id = `ec2metadata --instance-id`.strip
cluster_name = `cat /etc/ecs/ecs.config | grep '^ECS_CLUSTER=' | cut -d "=" -f2`.strip

container_instance_arn = lambda do
  ECS_CLIENT.describe_container_instances(
    :cluster => cluster_name,
    :container_instances => ECS_CLIENT.list_container_instances(
      :cluster => cluster_name,
    ).container_instance_arns
  ).container_instances.select do |instance|
    instance.ec2_instance_id == instance_id
  end.first.container_instance_arn
end.call

【讨论】:

以上是关于如何获取本地ec2实例的container-instance-id的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 AWS *** 从 EC2 实例 ping 到本地 Windows Server?

如何从 ec2 实例获取电子邮件信息?

如何从 EC2 连接到本地 ***?

如何在Python AWS boto API中获取EC2实例ID的容器实例列表

如何使用 Amazon PHP SDK 2 获取 EC2 实例列表?

如何使用powershell获取EC2实例的公共IP和私有IP地址?并列出这些实例的IP