使用 Amazon ECS Exec进行调试 - Amazon Elastic Container Service
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 软件开发工具包或 Cop Amazon ilot CLI 中的 ECS Exec 在正在运行的 Linux 或 Windows 容器中运行命令。有关使用 ECS Exec 的详细信息以及使用 Cop Amazon ilot CLI 的视频演练,请参阅 Copilot 文档。GitHub

您还可以使用 ECS Exec 执行更严格的访问控制策略和审核容器访问权限。通过选择性地启用此功能,您可以控制谁可以运行命令,以及他们可以在哪些任务上运行这些命令。有了每条命令及其输出的日志,您可以使用 ECS Exec 来审核运行了哪些任务,也可以 CloudTrail 用来审核谁访问了容器。

架构

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

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

使用 ECS Exec 的注意事项

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

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

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

    • 外部实例上的 Linux 和 Windows 容器(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 Web Services Management Console

  • 如果您结合使用接口 Amazon VPC 端点与 Amazon ECS,则必须为 Systems Manager Session Manager(ssmmessages)创建接口 Amazon VPC 端点。有关 Systems Manager VPC 终端节点的更多信息,请参阅Amazon Systems Manager 用户指南中的使用 Amazon PrivateLink 为会话管理器设置 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

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

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

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

    • 运行时监控

    • Service Connect

使用 ECS Exec 的先决条件

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

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

  • 为安装会话管理器插件 Amazon CLI。有关更多信息,请参阅为 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

可选任务定义更改

如果您将任务定义参数从 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-task、或run-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 为任务编号

任务 ID 是任务的亚马逊资源名称 (ARN)。

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

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

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

重要

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

Amazon ECS 使用任务定义中配置的日志驱动程序向 CloudWatch 日志发送日志,从而为使用 ECS Exec 运行的awslogs日志命令提供了默认配置。如果您想要提供自定义配置, Amazon CLI 支持 create-clusterupdate-cluster 命令的 --configuration 标志。为了将命令日志正确上传到 Amazon S3 或 CloudWatch 日志,还需要script安装容器映像。cat有关创建集群的更多信息,请参阅创建 create-cluster

注意

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

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

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

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: 日志被发送到提供的亚马逊日 CloudWatch 志 LogGroup、Amazon S3 存储桶,或两者兼而有之

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

要启用日志记录,您的任务定义中引用的 Amazon ECS 任务角色需要具有其他权限。这些附加权限可以作为策略添加到任务角色。它们会有所不同,具体取决于您将日志定向到 Amazon Log CloudWatch s 还是 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 密钥的更多信息,请参阅创建密钥

您可以将以下内联策略添加到需要 Amazon KMS 权限的任务 IAM 角色中。有关更多信息,请参阅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/*", "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" } } } ] }

排查 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是可用的。有关更多信息,请参阅上的 Amazon ECS Exec Checker。 GitHub

调用 execute-command 时出错

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

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

  • SSM 代理未安装或未运行。

  • 有一个用于 Amazon ECS 的接口 Amazon VPC 端点,但没有一个用于 Systems Manager Session Manager。