您好,我有兴趣从 EC2 主机内正在运行的容器内检索
Task ID
。
AWS ECS 文档指出有一个环境变量
ECS_CONTAINER_METADATA_FILE
包含此数据的位置,但只有在创建集群/EC2 实例时将 ECS_ENABLE_CONTAINER_METADATA
变量设置为 true 时,该变量才会被设置/可用。我不知道在 aws 控制台中哪里可以完成此操作。
此外,文档指出这可以通过在主机内将其设置为 true 来完成,但需要重新启动 docker 代理。
有没有其他方法可以做到这一点,而无需进入 EC2 内部进行设置并重新启动 docker 代理?
我使用的技术是在容器定义中设置环境变量。
如果您通过 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 地址。
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"
]
}
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();
#!/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()
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"