如何获取本地ec2实例的container-instance-id
How to get the container-instance-id of the local ec2 instance
我 运行 使用以下 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
或其他一些工具来过滤
这似乎有点复杂。有没有更简单的方法?
如果您是 运行 实例上的脚本,您可以从 ECS 代理的 introspection API.
中找到容器实例 ID
如果您是 运行 ECS 任务中的脚本,您可以使用 container metadata file.
另一种选择是在包含实例 ID 的实例上填充自定义属性。例如,在您的 /etc/ecs/ecs.config 中,您可能有以下内容:
ECS_INSTANCE_ATTRIBUTES={\"ec2_instance\":\"i-0000000000000000000\"}
这可以与 --filter 参数一起使用 list-container-instances 来查找关联的容器实例.
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
...
参考文献:
安装 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。
这是我为此使用的 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
我 运行 使用以下 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
或其他一些工具来过滤
这似乎有点复杂。有没有更简单的方法?
如果您是 运行 实例上的脚本,您可以从 ECS 代理的 introspection API.
中找到容器实例 ID如果您是 运行 ECS 任务中的脚本,您可以使用 container metadata file.
另一种选择是在包含实例 ID 的实例上填充自定义属性。例如,在您的 /etc/ecs/ecs.config 中,您可能有以下内容:
ECS_INSTANCE_ATTRIBUTES={\"ec2_instance\":\"i-0000000000000000000\"}
这可以与 --filter 参数一起使用 list-container-instances 来查找关联的容器实例.
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
...
参考文献:
安装 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。
这是我为此使用的 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