如何获取本地 EC2 实例的容器实例 ID

4

在重新启动我的ECS实例之前,我运行以下shell命令来排空它:

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。

显然,这是因为它想要ECS containerInstanceId,而不是ec2InstanceId。找出本地机器的containerInstanceId的最佳方法是什么?

到目前为止,我想到的方法是:

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

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


我认为您应该输入容器实例ID而不是EC2实例ID。容器实例ID看起来像这样:1c3be8ed-df30-47b4-8f1e-6e68ebd01f34。我从AWS API指南中获取了这个信息:https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_UpdateContainerInstancesState.html - krishna_mee2004
1
你说得完全正确。我通过使用aws ecs list-container-instances,然后结合一些grepping和awking的方法来解决了它。不过对于这样一个简单的任务来说,似乎有点复杂了。 - Bastian Voigt
4个回答

4
另一种选项是在实例上填充一个包含实例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

如果您正在使用脚本和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
...

参考资料:


自从发布以来,Jose注意到现在有一个“ec2InstanceId”属性自动填充并可用于使用list-container-instances。不需要纠结于自定义属性。 - tgoodhart

3
如果您在实例上运行脚本,可以从ECS代理的内省API中找到容器实例ID。
如果您在ECS任务中运行脚本,可以使用容器元数据文件。

0
这是我用的 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

0

如果已安装jq,那么这就相当简单了。

使用ECS容器内省端点,获取这些值并将它们传递给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 标志意味着如果未找到键,则设置退出代码。
  • jq -r 标志意味着将输出转储为原始文本而不是 json。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接