如何針對將環境變數傳遞到 Amazon ECS 任務時的問題進行疑難排解?

上次更新日期:2022 年 4 月 14 日

我想要針對將環境變數傳遞到 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 以環境變數的形式存放敏感資料。

通過上述方法之一來傳遞環境變數時,您可能會收到以下錯誤:

參數存放區:

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 參數存放擷取密碼資料:AccessDeniedException:使用者:arn:aws:sts::123456789:assumed-role/ecsExecutionRole/f512996041234a63ac354214 沒有權限執行:ssm:GetParameters 於資源:arn:aws:ssm:ap-south-1:12345678:parameter/狀態代碼: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

-或-

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 任務執行角色沒有所需的 IAM 許可

如果您在 Parameter Store 或 Secrets Manage 內使用環境變數,則請檢閱 AWS CloudTrail 事件中是否有以下任一 API 呼叫:

GetParameters (若為 Parameter Store)

-或-

GetSecretValue (若為 Secrets Manager)

如果您在 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 上允許輸出流量。
  • 使用 telnet 命令來驗證能否與 Systems Manager/Secrets Manager 和 Amazon S3 端點建立連線。
  • 如果您使用的是 NAT 閘道,請確定任務有通往 NAT 閘道的預設路由。
  • 確定您已為任務定義 VPC 端點。如果已定義 VPC 端點,則請確定有 Secrets Manager/Systems Manager Parameter StoreS3 所需的 VPC 端點。
  • 如果您使用的是 VPC 端點,請確定以下事項:
    • VPC 端點的安全群組在連接埠 443 上允許來自任務或服務的輸出流量。
    • VPC 端點與正確的 VPC 關聯。
    • VPC 屬性 enableDnsHostnamesenableDnsSupport 已開啟。

如果 ECS 任務位於公有子網路,請驗證以下事項:

  • 確定任務已啟用公有 IP 地址。
  • 確定 VPC 的安全群組在連接埠 443 上具有對外存取網際網路的權限。
  • 確定網路 ACL 組態允許所有流量在子網路與網際網路之間流動。

應用程式無法讀取環境變數

若要檢查任務容器內所填入的環境變數是否正確,請執行以下操作:

  1. 列出容器內公開的所有環境變數。
  2. 驗證此清單是否包含您在 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 程序使用。

此文章是否有幫助?


請求に関するサポートまたは技術サポートが必要ですか?