使用 Amazon ECS Exec进行调试 - Amazon ECS
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

使用 Amazon ECS Exec进行调试

借助 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 使用 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 审核访问容器的用户并将每个命令(及其输出)记录到 Amazon S3 或 Amazon CloudWatch Logs。要使用自己的加密密钥加密本地客户端和容器之间的数据,必须提供 Amazon Key Management Service (Amazon KMS) 键。

使用 ECS Exec 的注意事项

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

  • 对于 Amazon Fargate、外部实例(ECS Anywhere)、托管在 Amazon EC2 上的 Linux 容器以及以下 Windows Amazon ECS 优化 AMI(含容器代理版本 1.56 或更高版本)都支持 ECS Exec:

    • 经 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

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

  • 使用 自动扩缩组容量提供程序启动的任务目前不支持 ECS Exec。

  • 如果您使用 Amazon VPC 终端节点与 Amazon ECS 接口,则必须为 Systems Manager Session Manager 创建接口 Amazon VPC 终端节点。有关更多信息,请参阅使用 ECS 执行功能时,创建 Systems Manager Session Manager VPC 终端节点

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

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

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

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

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

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

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

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

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

  • 使用 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 具有版本要求,具体取决于您的任务是托管在 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

ECS Exec 所需的 IAM 权限

ECS Exec 功能需要一个任务 IAM 角色来授予容器在托管 SSM Agency之间进行通信所需的权限(execute-command 代理)和 SSM 服务。有关更多信息,请参阅 Amazon ECS 的 IAM 角色。您应向任务 IAM 角色添加以下权限,并在任务定义中包含任务 IAM 角色。有关更多信息,请参阅添加和删除 IAM policy

对于您的任务 IAM 角色使用以下策略来添加所需的 SSM 权限。

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ssmmessages:CreateControlChannel", "ssmmessages:CreateDataChannel", "ssmmessages:OpenControlChannel", "ssmmessages:OpenDataChannel" ], "Resource": "*" } ] }

可选任务定义更改

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

{ "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

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

aws ecs create-service \ --cluster cluster-name \ --task-definition task-definition-name \ --enable-execute-command \ --service-name service-name \ --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 标记。

以下命令将运行一个交互式 /bin/sh 命令对名为 container-name 的容器使用 ID 为任务编号

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

使用 ECS Exec 进行日志记录和审计

在任务和服务中启用日志记录和审核

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 所需的 IAM 权限

{ "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 policy 条件键限制用户对执行命令 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/*", "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:*:111122223333:task/cluster-name/*" } ] }

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

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

排查 ECS Exec 的相关问题

以下是故障排除说明,帮助诊断使用 ECS Exec 时出现错误的原因。

使用 Amazon ECS Exec 检查器进行验证

Amazon ECS Exec Checker 脚本提供了一种验证和验证您的 Amazon ECS 集群和任务是否符合使用 ECS Exec 功能的先决条件。Exec Checker 脚本通过代表您调用各种 API 来验证您的 Amazon CLI 环境和集群以及任务是否为 ECS Exec 准备好。此工具需要安装最新版本的 Amazon CLI,jq 可用。有关更多信息,请参阅 GitHub 上的 Amazon ECS Exec Checker

调用 execute-command 时出错

如果发生 The execute command failed 错误,可能是下列原因。

  • 任务没有所需的权限。验证用于启动任务的任务定义是否定义了任务 IAM 角色,以及该角色是否具有所需的权限。有关更多信息,请参阅ECS Exec 所需的 IAM 权限

  • SSM 代理未安装或未运行

  • 有一个用于 Amazon ECS 的接口 Amazon VPC 终端节点,但没有一个用于系统管理器会话管理器