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

4 分的閱讀內容
0

我想要針對將環境變數傳遞到 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 StoreAmazon S3 所需的 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 程序使用。

相關資訊

將環境變數傳遞給容器

AWS 官方
AWS 官方已更新 1 年前