当任务在 AWS Fargate 内启动时,它有一个用于 Cloudwatch 日志的任务 ID (guid),可用作唯一的“运行 ID”。我正在将 .NET 核心应用程序启动到 AWS 容器中,并希望找到一种以编程方式提取任务 ID 的方法。
我参考了Amazon ECS Container Metadata File上的 AWS 文档
但似乎没有为 Fargate 打开代理,因为 ECS_CONTAINER_METADATA_FILE 环境变量似乎不可用。
有什么方法可以从正在运行的容器内部获取任务 ID (guid)?
已解决 - 注意:
ECS 任务端点提供了所需的信息。在 Docker 容器内,您可以从 URL http://169.254.170.2/v2/metadata 中curl(或以编程方式拉取),它将为您提供进行调用的容器的任务元数据。我能够在两个单独运行的容器上对此进行测试,并取回它们的特定任务 ARN 值(每个容器的唯一 GUID。)
请注意,对于 Farpoint,您必须使用端点的 v2。
2018 年 11 月 5 日更新
我创建了一个名为 AwsContainerInspection 的 .NET 标准库,它有助于解析来自 AWS ECS 任务元数据端点的元数据并返回一个类对象。我在我的代码中使用它来获取用于日志记录和其他事情的任务 GUID。
GitHub - https://github.com/tgourley/AwsContainerInspection
Nuget - https://www.nuget.org/packages/AwsContainerInspection/
.net amazon-web-services visual-studio amazon-ecs aws-sdk-net
我编写了一个.NET核心控制台应用程序,作为AWS ECS Fargate中的任务运行.基本上,控制台应用程序启动一个处理线程,然后需要继续运行(很像Kestrel Web主机.)
最初,我放入一个Console.ReadKey(),认为它永远不会命中,应用程序将继续运行.那导致.NET异常......
Cannot read keys when either application does not have a console
or when console input has been redirected. Try Console.Read.
Run Code Online (Sandbox Code Playgroud)
所以我然后用Console.Read()替换ReadKey.应用程序的行为就像它不存在,继续移动,应用程序一开始就退出.
通过研究,我发现了Console.CancelKeyPress事件.我实现了它,它的工作原理是控制台应用程序将继续运行.
ManualResetEvent _quitEvent = new ManualResetEvent(false);
Console.CancelKeyPress += (sender, eArgs) => {
Console.WriteLine("Shutting down.");
_quitEvent.Set();
eArgs.Cancel = true;
};
_quitEvent.WaitOne();
Run Code Online (Sandbox Code Playgroud)
但是,当发生这种情况时,我想优雅地处理应用程序的关闭.
通过进一步的研究,我发现当AWS ECS停止任务时,它不会发送Ctrl-C(SIGINT)而是发送SIGTERM. https://docs.aws.amazon.com/cli/latest/reference/ecs/stop-task.html
然后我实现我认为是.NET中SIGTERM的标准事件处理(见下文).
AssemblyLoadContext.Default.Unloading += ctx =>
{
Console.WriteLine("Shutting down.");
_quitEvent.Set();
};
_quitEvent.WaitOne();
Run Code Online (Sandbox Code Playgroud)
这在ECS中编译并运行良好.但是......我通过AWS ECS控制台点击"停止"按钮,它停止任务并重新启动新任务.当我查看该停止任务的日志时,没有关闭日志消息,没有正常关闭的指示,什么也没有.它似乎只是被迫杀死了.
我在这里错过了什么吗?我可以做些什么来优雅地捕获AWS ECS中的停止任务以优雅地关闭任务?