如何避免在具有 Amazon Linux 1 AMI 且磁碟空間不足的 Amazon ECS 容器執行個體上置放任務?

2 分的閱讀內容
0

我使用具有 Amazon Linux 1 Amazon Machine Images (AMI) 的 Amazon Elastic Container Service (Amazon ECS) 容器執行個體。但是,我無法在磁碟空間不足的具有 Linux 1 AMI 的Amazon ECS 容器執行個體上啟動任務。當 Docker 常駐程式嘗試從我的 Docker 映像儲存庫中提取 Docker 映像然後再執行任務時,就會發生這種情況。如何才能防止這個問題?

簡短說明

使用 Amazon Elastic Compute Cloud (Amazon EC2) 啟動類型啟動任務時,Amazon ECS 不會考慮容器執行個體上的磁碟空間可用性。Amazon ECS 會 根據任務定義中指定的需求 (例如 CPU、記憶體和連接埠) 來確定任務置放的位置。 若要解決此問題,您可以使用監控磁碟空間的磁碟空間監控指令碼。此指令碼會傳回顯示 Amazon ECS 容器執行個體上可用磁碟空間的值。傳回的值與容器執行個體相關聯,做為自訂屬性。與容器執行個體設定檔相關聯的 AWS Identity and Access Management (IAM) 角色必須具有更新此自訂屬性值的權限。

然後,使用任務定義來指定任務置放限制條件,以限制在磁碟空間不足的容器執行個體上置放任務。

注意: Amazon Linux 1 的支援服務於 2020 年 12 月 31 日終止。最佳做法是在支援結束前將工作負載遷移至 Amazon Linux 2。

解決方法

啟動具有 Amazon ECS 最佳化 Amazon Linux AMI 的容器執行個體

**重要事項:**最佳做法是啟動具有已設定多個可用區域的 Auto Scaling 群組的執行個體。您可以新增命令來引導啟動組態使用者資料中的執行個體。

注意: 如果您在執行 AWS Command Line Interface (AWS CLI) 命令時收到錯誤訊息,請確認您使用的是最新的 AWS CLI 版本

  1. 執行下列命令,在容器執行個體啟動組態的使用者資料區段中安裝 AWS CLI 和 jq 套件。如需詳細資訊,請參閱在 jq 網站上的 ./jq
yum install -y aws-cli jq

**注意:**使用者資料區段透過在啟動時執行命令來引導 Amazon EC2 執行個體。

  1. 開啟 IAM 主控台,然後建立下列內嵌政策
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "ecs:PutAttributes",
            "Resource": "*"
        }
    ]
}

**重要事項:**上述策略使用萬用字元參數,可讓主體針對帳戶中任何相容資源 (容器執行個體) 呼叫 ecs:PutAttributes。此範例是為了方便使用,但最佳做法是儘可能授予最低權限。如需詳細資訊,請參閱 Amazon Elastic Container Service 以身分為基礎的政策範例。下列範例政策會限制只對特定叢集中的容器執行個體進行呼叫:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ecs:PutAttributes"
            ],
            "Resource": [
                "arn:aws:ecs:<region>:<accountId>:container-instance/<clusterName>/*"
            ]
        }
    ]
}
  1. 將內嵌政策ecsInstanceRole IAM 角色建立關聯。

**注意:**IAM 權限在 AWS CLI 中使用 aws ecs put-attribute 命令,將 SpaceLeft 自訂屬性與容器執行個體建立關聯。SpaceLeft 自訂屬性是由磁碟空間監控指令碼計算。

在 Amazon ECS 容器執行個體上安裝並執行磁碟空間監控指令碼

  1. 若要監控叢集的磁碟空間 (以 GB 為單位),請在容器執行個體上安裝下列指令碼:
#! /usr/bin/env bash
set -o pipefail
set -o nounset
set -o errexit

until curl -s http://localhost:51678/v1/metadata
do
   sleep 1
done

clusterName=$(curl -s http://localhost:51678/v1/metadata | jq .Cluster | tr -d '"' )
SpaceLeft=$(docker info | grep 'Data Space Available' | cut -d':' -f2)
Unit=$(echo "$SpaceLeft" | grep -o '..$')
if [ "$Unit" != GB ]; then
    SpaceLeft=$(echo "$SpaceLeft" | sed 's/[A-Za-z]*//g' | cut -d '.' -f1)
    SpaceLeftValue=$(echo "$SpaceLeft" | awk '{$1=$1/(1000); print $1;}')
else
        SpaceLeftValue=$(echo "$SpaceLeft" | sed 's/[A-Za-z]*//g')
fi

instanceArn=$(curl -s http://localhost:51678/v1/metadata | jq -r '. | .ContainerInstanceArn' | awk -F/ '{print $NF}' )
region=$(curl -s http://localhost:51678/v1/metadata | jq -r '. | .ContainerInstanceArn' | awk -F: '{print $4}')

aws ecs put-attributes \
  --cluster "$clusterName" \
  --attributes name="SpaceLeft",value="$SpaceLeftValue",targetType="container-instance",targetId="$instanceArn" \
  --region "$region"

**注意:您可以將指令碼命名為 ** diskspaceMonitoring.sh,然後將其新增至叢集中每個 Amazon ECS 容器執行個體的 **/home/ec2-user/diskspaceMonitoring.sh ** 路徑。您也可以指定磁碟空間監控指令碼,作為容器執行個體啟動組態上使用者資料的一部分。

  1. 在容器執行個體上,執行下列指令碼:
$echo "* * * * * root /home/ec2-user/diskspaceMonitoring.sh" >> /etc/crontab

**注意:**您可以將指令碼作為 Cron 工作的一部分,以一分鐘的間隔定期執行。您也可以選擇不同的時間間隔。您可以將指令碼新增至啟動組態上的使用者資料。

  1. 開啟 Amazon ECS 主控台,然後使用 Amazon ECS 任務定義建立任務置放限制。例如:
"placementConstraints": [
    {
        "expression": "attribute:SpaceLeft >= 0.1",
        "type": "memberOf"
    }
]

關聯的任務定義現在具有置放限制條件,限制在磁碟空間不足的容器執行個體上置放任務。


相關資訊

CannotCreateContainerError: API 錯誤 (500):devmapper

AMI 儲存體組態

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