使用 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-service
、update-service
、start-task
或 run-task
。
例如,如果您运行以下命令,则会为新创建的服务启用 ECS Exec 功能。有关创建服务的更多信息,请参阅 create-service。
aws ecs create-service \ --cluster
cluster-name
\ --task-definitiontask-definition-name
\ --enable-execute-command \ --service-nameservice-name
\ --desired-count 1
为任务启用 ECS Exec 后,可以运行以下命令,确认任务是否可以使用。如果 ExecuteCommandAgent
的 lastStatus
属性列为 RUNNING
,enableExecuteCommand
的属性设置为 true
,那么您的任务就绪。
aws ecs describe-tasks \ --cluster
cluster-name
\ --taskstask-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
命令对名为
的容器使用 ID 为container-name
任务编号
。
aws ecs execute-command --cluster
cluster-name
\ --tasktask-id
\ --containercontainer-name
\ --interactive \ --command"/bin/sh"
使用 ECS Exec 进行日志记录和审计
在任务和服务中启用日志记录和审核
Amazon ECS 为使用 CloudWatch Logs 服务器执行运行的日志记录命令提供原定设置配置,方法是使用在任务定义中配置的 awslogs
日志驱动程序。如果您想要提供自定义配置,Amazon CLI 支持 create-cluster
和 update-cluster
命令的 --configuration
标志。还有重要的一点是要知道容器图像需要 script
和 cat
以便将命令日志正确上传到 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 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 终端节点,但没有一个用于系统管理器会话管理器