使用 ECS Exec 监控 Amazon ECS 容器 - Amazon Elastic Container Service
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

使用 ECS Exec 监控 Amazon ECS 容器

借助 Amazon ECS Exec,您可以直接与容器交互,而无需首先与主机容器操作系统交互、打开入站端口或管理 SSH 密钥。您可以使用 ECS Exec 在 Amazon EC2 实例或 Amazon Fargate 上运行的容器中运行命令或获取shell。这样,就可以更轻松地收集诊断信息并快速解决错误。例如,在开发环境中,您可以使用 ECS Exec 轻松地与容器中的各种流程进行交互,并对应用程序进行故障排除。而且,在生产场景中,您可以使用它来获得对容器的破坏式访问以调试问题。

您可以使用来自 Amazon ECS API、Amazon Command Line Interface(Amazon CLI)、Amazon 开发工具包或 Amazon Copilot CLI 的 ECS Exec 在正在运行的 Linux 或 Windows 容器中运行命令。有关使用 ECS Exec 的详细信息以及使用 Amazon Copilot CLI 的视频演练,请参阅 Copilot GitHub 文档

您还可以使用 ECS Exec 维护更严格的访问控制策略。通过选择性地启用此功能,您可以控制谁可以运行命令,以及他们可以在哪些任务上运行这些命令。通过每个命令及其输出的日志,您可以使用 ECS Exec 来查看已运行的任务,并可以使用 CloudTrail 来审核访问容器的人员。

使用 ECS Exec 的注意事项

对于本主题,您应熟悉使用 ECS Exec 所涉及的以下方面:

  • 当前不支持使用 Amazon Web Services Management Console ECS Exec。

  • 在以下基础设施上运行的任务支持 ECS Exec:

    • 任何经过 Amazon ECS 优化的 AMI(包括 Bottlerocket)上的 Amazon EC2 上的 Linux 容器

    • 外部实例上的 Linux 和 Windows 容器(Amazon ECS Anywhere)

    • Amazon Fargate 上的 Linux 和 Windows 容器

    • Amazon EC2 上的 Windows 容器在以下经过 Windows Amazon ECS 优化的 AMI(含容器代理版本 1.56 或更高版本)上:

      • 经 Amazon ECS 优化的 Windows Server 2022 Full AMI

      • 经 Amazon ECS 优化的 Windows Server 2022 Core AMI

      • 经 Amazon ECS 优化的 Windows Server 2019 Full AMI

      • 经 Amazon ECS 优化的 Windows Server 2019 Core AMI

      • Amazon ECS 经过优化的 Windows Server 20H2 Core AMI

  • ECS Exec 和 Amazon VPC

    • 如果您结合使用接口 Amazon VPC 端点与 Amazon ECS,则必须为 Systems Manager Session Manager(ssmmessages)创建接口 Amazon VPC 端点。有关 Systems Manager VPC 端点的更多信息,请参阅《Amazon Systems Manager 用户指南》中的使用 Amazon PrivateLink 为 Session Manager 设置 VPC 端点

    • 如果您结合使用接口 Amazon VPC 端点与 Amazon ECS,并且使用 Amazon KMS key 进行加密,则必须为 Amazon KMS key 创建接口 Amazon VPC 端点。有关更多信息,请参阅《Amazon Key Management Service 开发人员指南》中的通过 VPC 端点连接到 Amazon KMS key

    • 当您具有在 Amazon EC2 实例上运行的任务时,请使用 awsvpc 联网模式。如果您无法访问互联网(未配置为使用 NAT 网关),必须为 Systems Manager Session Manager(ssmmessages)创建接口 Amazon VPC 端点。有关 awsvpc 网络模式考虑因素的更多信息,请参阅考虑因素。有关 Systems Manager VPC 端点的更多信息,请参阅《Amazon Systems Manager 用户指南》中的使用 Amazon PrivateLink 为 Session Manager 设置 VPC 端点

  • ECS Exec 和 SSM

    • 当用户使用 ECS Exec 在容器上运行命令时,这些命令将作为 root 用户运行。即使您为容器指定用户 ID,SSM Agency及其子进程以根用户身份运行。

    • SSM 代理要求容器文件系统能够写入,以便创建所需的目录和文件。因此,不支持使用 readonlyRootFilesystem 任务定义参数或任何其他方法将根文件系统设置为只读。

    • 虽然可以在 execute-command 操作之外启动 SSM 会话,但这会导致会话未被记录并根据会话限制计数。我们建议通过使用 IAM policy 拒绝 ssm:start-session 操作来限制此访问。有关更多信息,请参阅 限制对 “启动会话” 操作的访问

  • 以下功能作为附加容器运行。因此,您必须指定要在其上运行命令的容器名称。

    • 运行时监控

    • Service Connect

  • 用户可以运行容器上下文中可用的所有命令。以下操作可能会导致孤立进程和僵尸进程:终止容器的主进程、终止命令代理和删除依赖关系。要清理僵尸进程,我们建议将 initProcessEnabled 标记添加到任务定义。

  • ECS Exec 使用一些 CPU 和内存。在任务定义中指定 CPU 和内存资源分配时,您需要适应这一点。

  • 您必须使用 Amazon CLI 版本 1.22.3 或更高版本,或者 Amazon CLI 版本 2.3.6 或更高版本。有关如何更新 Amazon CLI 的信息,请参阅 Amazon Command Line Interface 用户指南版本 2 中的安装或更新 Amazon CLI 的最新版本

  • 每个进程 ID(PID)命名空间只能有一个 ECS 执行会话。如果您在任务中共享 PID 命名空间,则只能在一个容器中启动 ECS Exec 会话。

  • ECS Exec 会话的空闲超时时间为 20 分钟。此值不能更改。

  • 无法为现有任务启用 ECS Exec。只能为新任务启用此功能。

  • 使用 run-task 时不能使用 ECS Exec 在使用托管扩缩和异步放置的集群上启动任务(启动没有实例的任务)。

  • 您不能对 Microsoft Nano Server 容器运行 ECS Exec。有关 Nano Server 容器的更多信息,请参阅 Docker 网站上的 Nano Server

使用 ECS Exec 的先决条件

开始使用 ECS Exec 前,请确保您已完成以下操作:

  • 安装和配置 Amazon CLI。有关更多信息,请参阅 Amazon CLI

  • 安装 Amazon CLI Session Manager 插件 有关更多信息,请参阅安装 Amazon CLI Session Manager 插件

  • 您必须使用具有 ECS Exec 相应权限的任务角色。有关更多信息,请参阅任务 IAM 角色

  • ECS Exec 具有版本要求,具体取决于您的任务是托管在 Amazon EC2 上还是 Amazon Fargate:

    • 如果您使用的是 Amazon EC2,必须使用 2021 年 1 月 20 日之后发布的经 Amazon ECS 优化的 AMI,代理版本为 1.50.2 或更高。有关更多信息,请参阅经 Amazon ECS 优化的 AMI

    • 如果您使用的是 Amazon Fargate,则必须使用平台版 1.4.0 或更高版本(Linux)或 1.0.0(Windows)。有关平台版本的更多信息,请参阅 Amazon Fargate 平台版本

架构

ECS Exec 使用 Amazon Systems Manager (SSM) Session Manager 与正在运行的容器建立连接,并使用 Amazon Identity and Access Management (IAM) 策略来控制对正在运行的容器中运行的命令的访问。这是通过将必要的 SSM Agency 二进制文件绑定到容器中来实现的。Amazon ECS 或 Amazon Fargate 代理负责启动在应用程序代码旁边的容器内的 SSM 核心代理。有关更多信息,请参阅 Systems Manager Systems Manager

您可以使用 Amazon CloudTrail 中的 ExecuteCommand 事件审核访问容器的用户并将每个命令(及其输出)记录到 Amazon S3 或 Amazon CloudWatch Logs。要使用自己的加密密钥加密本地客户端和容器之间的数据,必须提供 Amazon Key Management Service (Amazon KMS) 键。

使用 ECS Exec

可选任务定义更改

如果您将任务定义参数 initProcessEnabled 设置为 true,这将启动容器内的 init 进程,从而删除找到的任何僵尸 SSM 代理子进程。示例如下。

{ "taskRoleArn": "ecsTaskRole", "networkMode": "awsvpc", "requiresCompatibilities": [ "EC2", "FARGATE" ], "executionRoleArn": "ecsTaskExecutionRole", "memory": ".5 gb", "cpu": ".25 vcpu", "containerDefinitions": [ { "name": "amazon-linux", "image": "amazonlinux:latest", "essential": true, "command": ["sleep","3600"], "linuxParameters": { "initProcessEnabled": true } } ], "family": "ecs-exec-task" }

为任务和服务启用 ECS Exec

您可以在使用下列 Amazon CLI 命令之一时,通过指定 --enable-execute-command 标记为您的服务和独立任务启用 ECS Exec 功能:create-serviceupdate-servicestart-taskrun-task

例如,如果您运行以下命令,则会为运行在 Fargate 上的新创建的服务启用 ECS Exec 功能。有关创建服务的更多信息,请参阅 create-service

aws ecs create-service \ --cluster cluster-name \ --task-definition task-definition-name \ --enable-execute-command \ --service-name service-name \ --launch-type FARGATE --network-configuration "awsvpcConfiguration={subnets=[subnet-12344321],securityGroups=[sg-12344321],assignPublicIp=ENABLED}" \ --desired-count 1

为任务启用 ECS Exec 后,可以运行以下命令,确认任务是否可以使用。如果 ExecuteCommandAgentlastStatus 属性列为 RUNNINGenableExecuteCommand 的属性设置为 true,那么您的任务就绪。

aws ecs describe-tasks \ --cluster cluster-name \ --tasks task-id

以下输出代码段是您可能看到的内容的示例。

{ "tasks": [ { ... "containers": [ { ... "managedAgents": [ { "lastStartedAt": "2021-03-01T14:49:44.574000-06:00", "name": "ExecuteCommandAgent", "lastStatus": "RUNNING" } ] } ], ... "enableExecuteCommand": true, ... } ] }

使用 ECS Exec 运行命令

确认 ExecuteCommandAgent 正在运行后,可以使用以下命令在容器上打开交互式 shell。如果任务包含多个容器,则必须使用 --container 标记。Amazon ECS 仅支持启动交互式会话,因此您必须使用 --interactive 标记。

以下命令将对 ID 为 task-id 的任务的名为 container-name 的容器运行一个交互式 /bin/sh 命令。

task-id 是任务的 Amazon 资源名称(ARN)。

aws ecs execute-command --cluster cluster-name \ --task task-id \ --container container-name \ --interactive \ --command "/bin/sh"

使用 ECS Exec 进行日志记录

在任务和服务中开启日志记录

重要

有关 CloudWatch 定价的信息,请参阅 CloudWatch 定价。Amazon ECS 还提供了不产生额外成本的监控指标。有关更多信息,请参阅 使用 CloudWatch 监控 Amazon ECS

Amazon ECS 为使用 CloudWatch Logs 服务器执行运行的日志记录命令提供原定设置配置,方法是使用在任务定义中配置的 awslogs 日志驱动程序。如果您想要提供自定义配置,Amazon CLI 支持 create-clusterupdate-cluster 命令的 --configuration 标志。还有重要的一点是要知道容器图像需要 scriptcat 以便将命令日志正确上传到 Amazon S3 或 CloudWatch Logs。有关创建集群的更多信息,请参阅创建 create-cluster

注意

此配置仅处理 execute-command 会话的记录。它不会影响应用程序的日志记录。

下面的示例创建一个集群,然后将输出记录到名为 cloudwatch-log-group-name 的 CloudWatch Logs 日志组和名为 s3-bucket-name 的 Amazon S3 存储桶。

当您设置 CloudWatchEncryptionEnabled 选项设置为 true 时,您必须使用 Amazon KMS 客户托管的密钥来加密日志组。。有关如何加密日志组的信息,请参阅 Amazon CloudWatch Logs 用户指南中的使用 Amazon Key Management Service 加密 CloudWatch Logs 中的日志数据

aws ecs create-cluster \ --cluster-name cluster-name \ --configuration executeCommandConfiguration="{ \ kmsKeyId=string, \ logging=OVERRIDE, \ logConfiguration={ \ cloudWatchLogGroupName=cloudwatch-log-group-name, \ cloudWatchEncryptionEnabled=true, \ s3BucketName=s3-bucket-name, \ s3EncryptionEnabled=true, \ s3KeyPrefix=demo \ } \ }"

logging 属性决定 ECS Exec 的日志记录功能的行为:

  • NONE:日志记录处于关闭状态。

  • DEFAULT:日志已发送到配置的 awslogs 驱动程序。如果未配置驱动程序,则不会保存任何日志。

  • OVERRIDE:日志将发送到提供的 Amazon CloudWatch Logs 日志组和/或 Amazon S3 存储桶。

Amazon CloudWatch Logs 或 Amazon S3 日志记录所需的 IAM 权限

要启用日志记录,您的任务定义中引用的 Amazon ECS 任务角色需要具有其他权限。这些附加权限可以作为策略添加到任务角色。根据将您的日志定向到 Amazon CloudWatch Logs 还是 Amazon S3,权限会有所不同。

Amazon CloudWatch Logs

以下示例策略添加了所需的 Amazon CloudWatch Logs 权限。

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "logs:DescribeLogGroups" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "logs:CreateLogStream", "logs:DescribeLogStreams", "logs:PutLogEvents" ], "Resource": "arn:aws:logs:region:account-id:log-group:/aws/ecs/cloudwatch-log-group-name:*" } ] }
Amazon S3

以下示例策略添加了所需的 Amazon S3 权限。

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:GetBucketLocation" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "s3:GetEncryptionConfiguration" ], "Resource": "arn:aws:s3:::s3-bucket-name" }, { "Effect": "Allow", "Action": [ "s3:PutObject" ], "Resource": "arn:aws:s3:::s3-bucket-name/*" } ] }

使用您自己的 Amazon KMS key(KMS 密钥)加密所需的IAM权限

预设情况下,本地客户端和容器之间传输的数据使用 Amazon 提供的 TLS 1.2加密。要使用自己的 KMS 密钥进一步加密数据,必须创建 KMS 密钥并将 kms:Decrypt 权限添加到任务 IAM 角色。您的容器将使用此权限解密数据。有关创建 KMS 密钥的更多信息,请参阅创建密钥

您需要将以下内联策略添加到您的任务 IAM 角色,该角色需要 Amazon KMS 权限。有关更多信息,请参阅 ECS Exec 所需的权限

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "kms:Decrypt" ], "Resource": "kms-key-arn" } ] }

对于要使用您自己 KMS 密钥加密的数据,必须向使用 execute-command 操作的用户或组授予 kms:GenerateDataKey 权限。

以下针对您的用户或组的示例策略包含使用您自己的 KMS 密钥所需的权限。您必须指定 KMS 密钥 Amazon Resource Name (ARN)。

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "kms:GenerateDataKey" ], "Resource": "kms-key-arn" } ] }

使用 IAM policy 限制对 ECS Exec 的访问权限

使用以下一个或多个 IAM 策略条件键限制用户对执行命令 API 操作的访问权限:

  • aws:ResourceTag/clusterTagKey

  • ecs:ResourceTag/clusterTagKey

  • aws:ResourceTag/taskTagKey

  • ecs:ResourceTag/taskTagKey

  • ecs:container-name

  • ecs:cluster

  • ecs:task

  • ecs:enable-execute-command

使用以下示例 IAM policy,用户可以在任务中运行的容器中运行命令,这些容器具有 environment 密钥和development 值,并在名为 cluster-name 的集群中。

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ecs:ExecuteCommand", "ecs:DescribeTasks" ], "Resource": [ "arn:aws:ecs:region:aws-account-id:task/cluster-name/*", "arn:aws:ecs:region:aws-account-id:cluster/*" ], "Condition": { "StringEquals": { "ecs:ResourceTag/environment": "development" } } } ] }

在以下 IAM policy 示例中,当容器名称为 production-app 时,用户不能使用 execute-command API。

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Deny", "Action": [ "ecs:ExecuteCommand" ], "Resource": "*", "Condition": { "StringEquals": { "ecs:container-name": "production-app" } } } ] }

使用以下 IAM policy,用户只能在关闭 ECS Exec 时启动任务。

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ecs:RunTask", "ecs:StartTask", "ecs:CreateService", "ecs:UpdateService" ], "Resource": "*", "Condition": { "StringEquals": { "ecs:enable-execute-command": "false" } } } ] }
注意

由于 execute-command API 操作仅包含请求中的任务和集群资源,仅评估群集和任务标签。

有关 IAM policy 条件密钥的更多信息,请参阅服务授权参考中的 Amazon Elastic Container Service 的操作、资源和条件键

限制对 “启动会话” 操作的访问

在 ECS Exec 以外的容器上启动 SSM 会话是可能的,这可能会导致无法记录会话。在 ECS Exec 以外开始的会话也会计入会话配额。我们建议通过使用 IAM policy 直接拒绝 Amazon ECS 任务的 ssm:start-session 操作来限制此访问。您可以根据所使用的标签拒绝对所有 Amazon ECS 任务或特定任务的访问。

以下是一个 IAM policy 示例,该策略拒绝访问具有指定群集名称的所有区域中的任务的 ssm:start-session 操作。可以选择在 cluster-name 中包含通配符。

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Deny", "Action": "ssm:StartSession", "Resource": [ "arn:aws:ecs:region:aws-account-id:task/cluster-name/*", "arn:aws:ecs:region:aws-account-id:cluster/*" ] } ] }

以下是一个 IAM policy 示例,该策略拒绝访问标记有标记键 Task-Tag-Key 和标记值 Exec-Task 的所有区域中的资源上的 ssm:start-session 操作。

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Deny", "Action": "ssm:StartSession", "Resource": "arn:aws:ecs:*:*:task/*", "Condition": { "StringEquals": { "aws:ResourceTag/Task-Tag-Key": "Exec-Task" } } } ] }

有关您在使用 Amazon ECS Exec 时可能遇到的任何问题的帮助,请参阅排查 Exec 问题