使用 Amazon ECS Exec 進行除錯 - Amazon Elastic Container Service

使用 Amazon ECS Exec 進行除錯

使用 Amazon ECS Exec,您可以直接與容器互動,而無需先與主機容器作業系統互動、開啟傳入連接埠或管理 SSH 金鑰。您可以使用 ECS Exec 執行命令,或為在 Amazon EC2 執行個體或 AWS Fargate 上執行的容器取得 shell。如此一來就可以更輕鬆地收集診斷資訊並快速對錯誤進行故障診斷。例如,在開發環境中,您可以使用 ECS Exec 輕鬆地與容器中的各種程序互動,並對應用程式進行故障診斷。而且,在生產案例中,您可以使用它來取得容器的突破存取權,以對問題進行除錯。

您可以使用來自 Amazon ECS API、AWS Command Line Interface (AWS CLI)、AWS SDK 或 AWS Copilot CLI 的 ECS Exec 在執行中的 Linux 容器或 Windows 容器中執行命令。如需使用 ECS Exec 以及影片逐步解說、使用 AWS Copilot CLI 的詳細資訊,請參閱 Copilot Github 文件

您也可以使用 ECS Exec 來維護更嚴格的存取控制政策和稽核容器存取。透過選擇性地開啟此功能,您可以控制執行命令的人員,以及他們可以執行這些命令的任務。透過每個命令及其輸出的日誌,您可以使用 ECS Exec 稽核執行的任務,並可以使用 CloudTrail 稽核存取容器的人員。

架構

ECS Exec 利用 AWS Systems Manager (SSM) 工作階段管理工具建立與執行容器的連線,並使用 AWS Identity and Access Management (IAM) 政策控制對執行容器中執行命令的存取。將必要的 SSM 代理程式二進位檔繫結掛載至容器,即可達成此目的。Amazon ECS 或 AWS Fargate 代理程式負責在應用程式碼旁邊的容器內啟動 SSM 核心代理。如需詳細資訊,請參閱 Systems Manager 工作階段管理工具

您可以使用 AWS CloudTrail 稽核哪個使用者存取了容器,並將每個命令 (及其輸出) 記錄到 Amazon S3 或 Amazon CloudWatch Logs。若要使用您自己的加密金鑰來加密本機用戶端與容器之間的資料,您必須提供 AWS Key Management Service (AWS KMS) 金鑰。

使用 ECS Exec 的考量

在本主題中,您應該熟悉下列使用 ECS Exec 的相關方面:

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

  • ECS Exec 目前不支援使用 AWS Management Console。

  • 使用 Auto Scaling 群組容量提供者啟動的任務目前不支持 ECS Exec。

  • 如果您將界面 Amazon VPC 端點與 Amazon ECS 搭配使用,則必須為 Systems Manager 工作階段管理工具建立界面 Amazon VPC 端點。如需詳細資訊,請參閱 在使用 ECS Exec 功能時,建立 Systems Manager Session Manager VPC 端點。

  • 您無法針對現有任務啟用 ECS Exec。只有新任務才可啟用。

  • 當使用者使用 ECS Exec 在容器上執行命令時,這些命令會以 root 使用者執行。即使您指定容器的使用者 ID,SSM 代理程式及其子處理程序也會以根身分執行。

  • ECS Exec 工作階段的閒置逾時值為 20 分鐘。此值無法變更。

  • SSM 代理程式要求容器檔案系統能夠寫入,以建立必要的目錄和檔案。因此,不支援使用 readonlyRootFilesystem 任務定義參數或任何其他方法將根檔案系統設為唯讀。

  • 使用者可以執行容器內容中所有可用的命令。下列動作可能會導致孤立和廢止程序:終止容器的主要程序、終止命令代理程式,以及刪除相依性。為了清理廢止程序,建議將 initProcessEnabled 旗標新增至您的任務定義。

  • 可以啟動 execute-command 動作以外的 SSM 工作階段時,這會導致工作階段未被記錄,會計入工作階段限制。建議您限制此存取,方法是使用 IAM 政策拒絕 ssm:start-session 動作。如需詳細資訊,請參閱 限制存取「啟動工作階段」動作

  • ECS Exec 將使用一些 CPU 和記憶體。在任務定義中指定 CPU 和記憶體資源配置時,您需要適應這一點。

  • 您必須使用 AWS CLI 版本 1.22.3 或更新版本,或者 AWS CLI 版本 2.3.6 或更新版本。如需有關如何更新 AWS CLI 的資訊,請參閱《AWS CLI 使用者指南 2》https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html中的安裝或更新 AWS Command Line Interface 的最新版本

  • 如果您使用 run-task 在使用受管擴展和異步置放 (啟動沒有執行個體的任務) 的叢集上啟動任務,則無法使用 ECS Exec。

  • 您無法針對 Microsoft Nano Server 容器執行 ECS Exec。如需有關 Nano Server 容器的詳細資訊,請參閱 Docker 網站上的 Nano Server

使用 ECS Exec 的先決條件

開始使用 ECS Exec 之前,請確定您已完成下列動作:

  • 安裝及設定 AWS CLI。如需詳細資訊,請參閱 AWS CLI

  • 安裝 AWS CLI 的工作階段管理工具外掛程式。如需詳細資訊,請參閱為 AWS CLI 安裝工作階段管理工具外掛程式

  • ECS Exec 具有版本要求,取決於您的任務是否託管於 Amazon EC2 或 AWS Fargate:

    • 如果您使用的是 Amazon EC2,則必須使用在 2021 年 1 月 20 日之後發行的 Amazon ECS 最佳化 AMI,且代理程式版本為 1.50.2 或更高版本。如需詳細資訊,請參閱 Amazon ECS 最佳化 AMI

    • 如果您使用的是 AWS Fargate,則必須使用平台版本 1.4.0、更新版本 (Linux) 或 1.0.0 (Windows)。如需詳細資訊,請參閱 AWS Fargate 平台版本

啟用和使用 ECS Exec

ECS Exec 所需的 IAM 許可

ECS Exec 功能需要任務 IAM 角色,以授予容器在受管 SSM 代理程式 (execute-command 代理程式) 和 SSM 服務之間通訊所需的許可。如需詳細資訊,請參閱 Amazon ECS 任務 IAM 角色。您應將下列許可新增至任務 IAM 角色,並在任務定義中包含任務 IAM 角色。如需詳細資訊,請參閱新增和移除 IAM 政策

針對您的任務 IAM 角色使用下列政策來新增所需的 SSM 許可。

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

可選任務定義變更

如果您將任務定義參數 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

您可以為您的服務和獨立任務啟用 ECS Exec 功能,方法是使用以下其中一個 AWS CLI 命令指定 --enable-execute-command 旗標: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 旗標。

對於 ID 為 task-id 的任務,下面的命令會針對名為 container-name 的容器執行交互式 /bin/sh 命令。

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

使用 ECS Exec 進行日誌記錄和稽核

在任務和服務中啟用日誌記錄和稽核

Amazon ECS 為使用 ECS Exec 執行的日誌記錄命令提供預設組態,方法是使用在任務定義中設定的 awslogs 日誌驅動程式將日誌傳送至 CloudWatch Logs。如果您想要提供自訂組態,AWS CLI 支援 create-clusterupdate-cluster 命令的 --configuration 旗標。同樣重要的是要知道容器映像需要安裝 scriptcat,以便將命令日誌正確上傳到 Amazon S3 或 CloudWatch Logs。如需建立叢集的詳細資訊,請參閱 create-cluster

注意

此組態只會處理 execute-command 工作階段的日誌記錄。它不會影響應用程式的日誌記錄。

下列範例會建立服務,然後將輸出記錄至名為 cloudwatch-log-group-name 的 CloudWatch Logs LogGroup 和名為 s3-bucket-name 的 Amazon S3 儲存貯體。

CloudWatchEncryptionEnabled 選項設定為 true 時,您必須使用 AWS KMS 客戶受管金鑰來加密日誌群組。如需如何加密日誌群組的詳細資訊,請參閱《Amazon CloudWatch Logs 使用者指南》中的使用 AWS 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 LogGroup、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/*" } ] }

使用您自己的 AWS KMS key (KMS 金鑰) 加密所需的 IAM 許可

根據預設,您的本機用戶端和容器之間傳輸的資料會使用 AWS 提供的 TLS 1.2 加密。若要使用您自己的 KMS 金鑰進一步加密資料,您必須建立 KMS 金鑰並新增 kms:Decrypt 許可至您的任務 IAM 角色。您的容器使用此許可來解密資料。如需建立 KMS 金鑰的詳細資訊,請參閱建立金鑰

您可以將以下內嵌政策新增至您的任務 IAM 角色中,該角色需要 AWS 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 政策限制 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 政策,使用者可以在任務內執行的容器中執行命令,任務標籤具有 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 政策範例中,當容器名稱為 production-app 時,使用者無法使用 execute-command API。

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

使用下列 IAM 政策,使用者只能在 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 政策條件索引鍵的詳細資訊,請參閱《服務授權參考》中的 Amazon Elastic Container Service 的動作、資源與條件索引鍵

限制存取「啟動工作階段」動作

雖然可以在 ECS Exec 之外的容器上啟動 SSM 工作階段,但這可能會導致工作階段未被記錄。在 ECS Exec 以外啟動的工作階段也會計入工作階段配額。建議您透過直接拒絕針對使用 IAM 政策之 Amazon ECS 任務的 ssm:start-session 動作來限制此存取。您可以根據使用的標籤拒絕存取所有 Amazon ECS 任務或特定任務。

以下為範例 IAM 政策,它會針對具有特定叢集名稱之所有區域中的任務,拒絕存取 ssm:start-session 動作。您可以選擇包含具有 cluster-name 的萬用字元。

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

以下為範例 IAM 政策,它會針對所有具有標籤鍵 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 Checker 進行驗證

Amazon ECS Exec Checker 指令碼提供了確認和驗證您的 Amazon ECS 叢集和任務是否符合使用 ECS Exec 功能之先決條件的方法。Exec Checker 指令碼可以透過代表您呼叫各種 API,來驗證您的 AWS CLI 環境和叢集以及您是否準備好使用 ECS Exec。此工具需要使用最新版本 AWS CLI,並且 jq 可供使用。如需詳細資訊,請參閱 GitHub 上的 Amazon ECS Exec Checker

呼叫 execute-command 時發生錯誤

如果發生 The execute command failed 錯誤,則可能的原因如下。

  • 此任務沒有必要的許可。確認用來啟動任務的任務定義已定義任務 IAM 角色,且該角色具有必要的許可。如需詳細資訊,請參閱 ECS Exec 所需的 IAM 許可

  • SSM Agent 尚未安裝或未執行

  • 有一個適用於 Amazon ECS 的 Amazon VPC 端點介面,但沒有適用於 Systems Manager Session Manager 的介面