如何針對將環境變數傳遞到 Amazon ECS 任務時的問題進行疑難排解?
我想要針對將環境變數傳遞到 Amazon Elastic Container Service (Amazon ECS) 任務時的問題進行疑難排解。
簡短說明
您可以使用下列其中一種方式在 Amazon ECS 任務中傳遞環境變數:
- 將變數視為 Amazon Simple Storage Service (Amazon S3) 儲存貯體內的 environmentFiles 物件傳遞。
- 將變數存放在 AWS Systems Manager Parameter Store 内。
- 將變數存放在 ECS 任務定義中。
- 將變數存放在 AWS Secrets Manager 内。
**注意事項:**為求安全,最佳實務是使用 Parameter Store 或 Secrets Manager 以環境變數的形式存放敏感資料。透過上述其中一個方法來傳遞環境變數時,可能會收到以下錯誤:
Parameter Store
"Fetching secret data from SSM Parameter Store in region: AccessDeniedException: User: arn:aws:sts::123456789:assumed-role/ecsExecutionRole/f512996041234a63ac354214 is not authorized to perform: ssm:GetParameters on resource: arn:aws:ssm:ap-south-1:12345678:parameter/status code: 400, request id: e46b40ee-0a38-46da-aedd-05f23a41e861 (從區域中的 SSM Parameter Store 擷取秘密資料:AccessDeniedException:使用者:arn:aws:sts::123456789:assumed-role/ecsExecutionRole/f512996041234a63ac354214 無權執行:資源中的 ssm:GetParameters:arn:aws:ssm:ap-south-1:12345678:parameter/status 代碼:400,請求 ID:e46b40ee-0a38-46da-aedd-05f23a41e861)"
- 或 -
"ResourceInitializationError: unable to pull secrets or registry auth: execution resource retrieval failed: unable to retrieve secrets from ssm: service call has been retried 5 time(s): RequestCanceled (ResourceInitializationError:無法提取密碼或登錄檔授權:執行資源擷取失敗:無法從 SSM 擷取密碼:已重試 5 次服務呼叫:RequestCanceled)"
Secrets Manager
"ResourceInitializationError error (ResourceInitializationError 錯誤)"
- 或 -
"AccessDenied error on Amazon Elastic Compute Cloud (Amazon EC2) (Amazon Elastic Compute Cloud (Amazon EC2) 上出現 AccessDenied 錯誤)"
若要解決這些錯誤,請參閱如何對 Amazon ECS 中的 AWS Secrets Manager 機密相關問題進行疑難排解?
Amazon S3
“ResourceInitializationError: failed to download env files: file download command: non empty error stream (ResourceInitializationError:無法下載 env 檔案:檔案下載命令:非空白錯誤串流)”
由於以下原因,當您將環境變數傳遞到 Amazon ECS 任務時,您可能會遇到問題:
- 您的 Amazon ECS 任務執行角色沒有 AWS Identity and Management (IAM) 所需的權限。
- 您的網路設定有問題。
- 您的應用程式無法讀取環境變數。
- 容器定義中的變數格式不正確。
- 環境變數不會自動重新整理。
若要疑難排解無法啟動 Amazon ECS 任務的錯誤,請使用 AWSSupport-TroubleshootECSTaskFailedToStart 執行手冊。然後,請參閱針對問題的相關疑難排解步驟。
解決方案
重要事項:
- 在 ECS 叢集資源所在的相同 AWS 區域中使用 AWSSupport-TroubleshootECSTaskFailedToStart 執行手冊。
- 使用執行手冊時,您必須使用最近失敗的任務 ID。如果失敗的任務屬於 Amazon ECS 服務,請在服務中使用最近失敗的任務。失敗的任務必須在 ECS:DescribeTasks 自動化過程中可見。依預設,停止的 ECS 任務會在進入已停止狀態後顯示 1 小時。使用最近失敗的任務 ID 可防止任務狀態清除作業在自動化期間中斷分析。
如需有關如何啟動執行手冊的說明,請參閱 AWSSupport-TroubleshootECSTaskFailedToStart。根據自動化的輸出,使用下列其中一個手動疑難排解步驟。
您的 Amazon ECS 任務執行角色沒有 IAM 所需的權限
如果您在 Parameter Store 或 Secrets Manage 內使用環境變數,則請檢閱 AWS CloudTrail 事件中是否有以下任一 API 呼叫:
適用於 Parameter Store 的 GetParameters
- 或 -
適用於 Secrets Manager 的 GetSecretValue
如果您在 CloudTrail 事件中發現任務執行角色有 AccessDenied 錯誤,請以手動方式將所需權限以內嵌政策的形式新增到 ECS 任務執行 IAM 角色。您也可以建立客戶管理政策,並將政策新增至 ECS 任務執行角色。
如果您使用的是 Secrets Manager,請將下列權限納入任務執行角色:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "secretsmanager:GetSecretValue", "kms:Decrypt" ], "Resource": [ "arn:aws:secretsmanager:example-region:11112222333344445555:secret:example-secret", "arn:aws:kms:example-region:1111222233334444:key/example-key-id" ] } ] }
如果您使用的是 Parameter Store,請將下列權限納入任務執行角色:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ssm:GetParameters", "secretsmanager:GetSecretValue", "kms:Decrypt" ], "Resource": [ "arn:aws:ssm:example-region:1111222233334444:parameter/example-parameter", "arn:aws:secretsmanager:example-region:1111222233334444:secret:example-secret", "arn:aws:kms:example-region:1111222233334444:key/example-key-id" ] } ] }
您可以使用 S3 儲存貯體將環境變數儲存為 .env 檔案。不過,您必須以內嵌政策形式將下列權限手動新增至任務執行角色:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:GetObject" ], "Resource": [ "arn:aws:s3:::example-bucket/example-folder/example-env-file" ] }, { "Effect": "Allow", "Action": [ "s3:GetBucketLocation" ], "Resource": [ "arn:aws:s3:::example-bucket" ] } ] }
您的網路設定有問題
如果您的 ECS 任務位於私有子網路中,請驗證以下幾點:
- 請確定任務或服務的安全群組在連接埠 443 上允許輸出流量。
- 如果您使用 VPC 端點,請確定網路存取控制清單 (ACL) 在連接埠 443 上允許輸出流量。
- 驗證能否與 Systems Manager/Secrets Manager 和 Amazon S3 端點建立連線。若要執行此操作,請使用 telnet 命令。
- 如果您使用 NAT 閘道,請確定任務有通往 NAT 閘道的預設路由。
- 為您的任務定義 VPC 端點。驗證您擁有 Secrets Manager/Systems Manager Parameter Store 和 Amazon S3 所需的 VPC 端點。
如果您使用 VPC 端點,請驗證以下幾點:
- VPC 端點的安全群組在連接埠 443 上允許來自任務或服務的輸出流量。
- 將 VPC 端點與正確的 VPC 建立關聯。
- 開啟 VPC 屬性 enableDnsHostnames 和 enableDnsSupport。
如果您的 ECS 任務位於公有子網路中,請驗證以下幾點:
- 您必須啟用任務的公有 IP 地址。
- 確定 VPC 的安全群組在連接埠 443 上具有對外存取網際網路的權限。
- 網路 ACL 組態允許所有流量在子網路與網際網路之間流動。
您的應用程式無法讀取環境變數
若要檢查任務容器中是否已填入正確的環境變數,請執行下列動作:
- 列出容器內公開的所有環境變數。
- 驗證此清單是否包含您在 S3 的任務定義或 .env 檔案中定義的環境變數。
如果您使用的是 Amazon EC2 或 AWS Fargate 啟動類型,則最佳實務是使用 ECS Exec 功能。您可以使用此功能在 Amazon EC2 執行個體或 Fargate 中執行命令,或將 Shell 放到在 Amazon EC2 執行個體或 Fargate 上執行的容器。在啟用此功能後,請執行以下命令來與容器互動:
aws ecs execute-command --cluster example-cluster \--task example-task-id \ --container example-container \ --interactive \ --command "/bin/sh"
如果您使用 Amazon EC2 啟動類型,那麼也可以使用 Docker exec 命令來與容器互動。在此情況下,請完成下列步驟: 連線到任務執行所在的容器執行個體。然後,執行下列 Docker 命令以尋找任務容器的容器 ID:
docker container ps
若要與容器進行互動,請執行以下命令
docker exec -it example-container-id bash
注意事項: 請根據容器的預設 Shell 來選取 Shell。
在與容器建立連線後,請於容器上執行 env 命令以取得完整的環境變數清單。檢閱此清單以確定您在任務定義或 .env 檔案中定義的環境變數是否存在。
容器定義中的變數格式不正確
在容器定義內定義環境變數時,請將環境變數定義為 KeyValuePair 物件:
"environment": [{ "name": "foo", "value": "bar" }]
在 .env 檔案中定義環境變數時,也請務必使用此格式。
環境變數不會自動重新整理
在 .env 檔案中更新環境變數時,該變數不會在執行中的容器內自動重新整理。
若要在任務中插入更新後的環境變數值,請執行以下命令來更新服務:
aws ecs update-service --cluster example-cluster --service example-service --force-new-deployment
如果在容器定義中使用環境變數,則必須建立新的任務定義才能重新整理更新後的環境變數。使用這個新的任務定義時,您可以建立新的任務或更新 ECS 服務:
`aws ecs update-service --cluster example-cluster --service example-service --task-definition <family:revision>`;
注意事項: 將環境變數傳遞到任務時,請記住以下事項:
- 如果您在容器定義中使用 environment 參數指定環境變數,其優先順序會高於環境檔案內所包含的變數。
- 如果您指定多個環境檔案,且這些檔案包含相同的變數,則會以進入順序來處理。系統會使用變數的第一個值,並忽略重複變數的後續值。最佳實務是使用唯一的變數名稱。
- 如果您將環境檔案指定為容器覆寫,則會使用該檔案。容器定義中所指定的任何其他環境檔案則會被忽略。
- 環境變數可用於檔案 /proc/1/environ 中容器內的 PID 1 程序。如果容器執行多個程序或 init 程序 (例如包裝函式指令碼或 supervisord),則環境變數無法供非 PID 1 程序使用。
相關資訊
相關內容
- 已提問 1 年前lg...
- 已提問 2 年前lg...
- 已提問 1 年前lg...
- 已提問 4 個月前lg...
- AWS 官方已更新 3 年前
- AWS 官方已更新 6 個月前
- AWS 官方已更新 4 個月前