如何从ECS容器内获取任务ID?

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

您好,我有兴趣从 EC2 主机内正在运行的容器内检索

Task ID

AWS ECS 文档指出有一个环境变量

ECS_CONTAINER_METADATA_FILE
包含此数据的位置,但只有在创建集群/EC2 实例时将
ECS_ENABLE_CONTAINER_METADATA
变量设置为 true 时,该变量才会被设置/可用。我不知道在 aws 控制台中哪里可以完成此操作。

此外,文档指出这可以通过在主机内将其设置为 true 来完成,但需要重新启动 docker 代理。

有没有其他方法可以做到这一点,而无需进入 EC2 内部进行设置并重新启动 docker 代理?

docker containers aws-sdk aws-ecs
8个回答
26
投票

这不再适用于较新的 Amazon ECS 容器版本,事实上它现在更简单并且默认情况下也是启用的。请参阅此文档,但这里有一个TL;DR

如果您使用 Amazon ECS 容器代理版本 1.39.0 及更高版本,您可以在 docker 容器内执行此操作:

curl -s "$ECS_CONTAINER_METADATA_URI_V4/task" \
  | jq -r ".TaskARN" \
  | cut -d "/" -f 3

这是容器代理版本的列表,但如果您正在使用

:latest
– 绝对没问题。


16
投票

我使用的技术是在容器定义中设置环境变量。

如果您通过 Cloudformation 管理任务,相关的 yaml 如下所示:

Taskdef: Type: AWS::ECS::TaskDefinition Properties: ... ContainerDefinitions: - Name: some-name ... Environment: - Name: AWS_DEFAULT_REGION Value: !Ref AWS::Region - Name: ECS_ENABLE_CONTAINER_METADATA Value: 'true'

这种技术可以帮助您让一切变得简单且可重复。

如果您以编程方式需要元数据并且无权访问元数据文件,您可以查询

代理的元数据端点

curl http://localhost:51678/v1/metadata

请注意,如果您作为正在运行的任务获取此信息,您可能无法连接到环回设备,但您可以连接到 EC2 实例自己的 IP 地址。


6
投票
以前的答案是正确的,这是另一种方法:

从运行容器的 ec2 实例中,运行此命令

curl http://localhost:51678/v1/tasks | python -mjson.tool |less


5
投票
我们用所谓的用户数据来设置它,这些数据在机器启动时执行。有多种设置方法,例如:

https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/user-data.html#user-data-console

它可能看起来像这样:

#!/bin/bash cat <<'EOF' >> /etc/ecs/ecs.config ECS_CLUSTER=ecs-staging ECS_ENABLE_CONTAINER_METADATA=true EOF

重要:调整上面的ECS_CLUSTER

以匹配您的集群名称,否则实例将无法连接到该集群。


4
投票

来自 AWS ECS cli 文档

命令:

aws ecs list-tasks --cluster default

输出:

{ "taskArns": [ "arn:aws:ecs:us-east-1:<aws_account_id>:task/0cc43cdb-3bee-4407-9c26-c0e6ea5bee84", "arn:aws:ecs:us-east-1:<aws_account_id>:task/6b809ef6-c67e-4467-921f-ee261c15a0a1" ] }

列出特定容器实例上的任务

此示例命令使用容器实例 UUID 作为过滤器列出指定容器实例的任务。

命令:

aws ecs list-tasks --cluster default --container-instance f6bbb147-5370-4ace-8c73-c7181ded911f

输出:

{ "taskArns": [ "arn:aws:ecs:us-east-1:<aws_account_id>:task/0cc43cdb-3bee-4407-9c26-c0e6ea5bee84" ] }
    

1
投票
转储容器/ECS Fargate 执行环境中的所有环境变量后,使用:

foreach (string key in Environment.GetEnvironmentVariables().Keys) { string value = Environment.(key); Console.WriteLine($"{key} = {value}"); }
我发现环境变量

ECS_CONTAINER_METADATA_URI

包含TaskId/Container运行时ID,以及元数据端点和可以删除的无关值。

ECS_CONTAINER_METADATA_URI = http://169.254.170.2/v3/93e1ab7d263746bcbfe4cd94808c7044-3151447892


var taskId = Environment.GetEnvironmentVariable("ECS_CONTAINER_METADATA_URI_V4") .Split("/").Last() .Split("-").First();
    

0
投票
我的 ECS 解决方案为 bash 和 Python 片段。日志记录调用可以通过管道传输到 sys.stderr 进行打印以进行调试,而 print() 用于将值传递回 shell 脚本

#!/bin/bash TASK_ID=$(python3.8 get_ecs_task_id.py) echo "TASK_ID: ${TASK_ID}"
Python 脚本 - get_ecs_task_id.py

import json import logging import os import sys import requests # logging configuration # file_handler = logging.FileHandler(filename='tmp.log') # redirecting to stderr so I can pass back extracted task id in STDOUT stdout_handler = logging.StreamHandler(stream=sys.stderr) # handlers = [file_handler, stdout_handler] handlers = [stdout_handler] logging.basicConfig( level=logging.INFO, format="[%(asctime)s] {%(filename)s:%(lineno)d} %(levelname)s - %(message)s", handlers=handlers, datefmt="%Y-%m-%d %H:%M:%S", ) logger = logging.getLogger(__name__) def get_ecs_task_id(host): path = "/task" url = host + path headers = {"Content-Type": "application/json"} r = requests.get(url, headers=headers) logger.debug(f"r: {r}") d_r = json.loads(r.text) logger.debug(d_r) ecs_task_arn = d_r["TaskARN"] ecs_task_id = ecs_task_arn.split("/")[2] return ecs_task_id def main(): logger.debug("Extracting task ID from $ECS_CONTAINER_METADATA_URI_V4") logger.debug("Inside get_ecs_task_id.py, redirecting logs to stderr") logger.debug("so that I can pass the task id back in STDOUT") host = os.environ["ECS_CONTAINER_METADATA_URI_V4"] ecs_task_id = get_ecs_task_id(host) # This print statement passes the string back to the bash wrapper, don't remove logger.debug(ecs_task_id) print(ecs_task_id) if __name__ == "__main__": main()
    

0
投票
这就能解决问题:

aws ecs list-tasks --cluster $CLUSTER_NAME --service $SERVICE_NAME --查询“taskArns”--输出文本

Bash 脚本将使您更轻松,因为您不必每次都定义已定义的变量。

#!/bin/bash export AWS_PROFILE=$AWS_PROFILE CLUSTER_NAME=$CLUSTER_NAME SERVICE_NAME=$SERVICE_NAME CONTAINER_NAME=$CONTAINER_NAME TASK_ID=$(aws ecs list-tasks --cluster $CLUSTER_NAME --service $SERVICE_NAME --query "taskArns" --output text) aws ecs execute-command --cluster $CLUSTER_NAME \ --task $TASK_ID \ --container $CONTAINER_NAME \ --interactive \ --command "/bin/sh"
    
© www.soinside.com 2019 - 2024. All rights reserved.