十分なディスク容量がない Amazon Linux 1 AMI で実行する Amazon ECS コンテナインスタンスに、タスクを配置しないようにするにはどうすればよいですか ?

最終更新日: 2020 年 3 月 25 日

十分なディスク容量がない Amazon Linux 1 で、Amazon マシンイメージ (AMI) を使用している Amazon Elastic Container Service (Amazon ECS) コンテナインスタンスのタスクが開始できません。この現象は、Docker デーモンが Docker イメージリポジトリから Docker イメージをプルし、タスクを実行しようとしたときに発生します。

簡単な説明

起動タイプに Amazon Elastic Compute Cloud (Amazon EC2) を使用しタスクを起動すると、タスク定義に記述された CPU、メモリ、ポートなどの要件に基き、Amazon ECS がタスクの配置場所を決定します。Amazon ECS は、コンテナインスタンスで利用可能なディスク容量について考慮しません。

この問題の解決には、ディスク容量をモニタリングするスクリプトを使います。これにより、Amazon ECS コンテナインスタンスで使用可能なディスク容量を値で返すことができます。この値は、カスタム属性としてコンテナインスタンスに関連付けられています。コンテナインスタンスのインスタンスプロファイルに関連付けられた AWS Identity and Access Management (IAM) ロールには、このカスタム属性値を変更するアクセス権限があります。スクリプトをインストールした後、タスク定義 を使って、コンテナインスタンスに十分なディスク容量がない場合のタスク配置の制約事項を指定します。

解決方法

Amazon ECS に最適化された Amazon Linux AMI を使用してコンテナインスタンスを起動する

1.    次のコマンドを実行し、コンテナインスタンスの ユーザーデータ セクションに、AWS コマンドラインインターフェイス (AWS CLI) と jq パッケージをインストールします。

yum install -y aws-cli jq

注: 起動時にこのコマンドを実行すると、ユーザーデータセクションが Amazon EC2 インスタンスをブートストラップします。

2.    IAM コンソールを開き、次のようなインラインポリシーを作成します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "ecs:PutAttributes",
            "Resource": "*"
        }
    ]
}

注 : このインラインポリシーにより、コンテナインスタンスにアタッチされている IAM インスタンスプロファイルに関連付けられた IAM ロールに対し、アクセス権限が付与されます。

3.    IAM ロール ecsInstanceRole に対し、インラインポリシーを関連付けます。

注: AWS CLI の aws ecs put-attribute コマンドを使うと、IAM のアクセス権限により、コンテナインスタンスに対し 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 パスに追加することができます。また、コンテナインスタンスのユーザーデータの一部として、このディスク容量モニタリングスクリプトを定義することも可能です。

2.    コンテナインスタンスで、次のスクリプトを実行します。

$echo "* * * * * root /home/ec2-user/diskspaceMonitoring.sh" >> /etc/crontab

注: スクリプトを cron ジョブの一部とすると、毎分、あるいは任意の間隔で定期的に実行することができます。

3.    Amazon ECS コンソール を開き、Amazon ECS タスク定義に、タスク配置の制約事項 を追加します。次に、その例を示します。

"placementConstraints": [
    {
        "expression": "attribute:SpaceLeft >= 0.1",
        "type": "memberOf"
    }
]

注: ここで関連付けたタスク定義により、十分なディスク容量がないコンテナインスタンスでタスク配置を行う場合の制約事項が指定されるようになります。


この記事はお役に立ちましたか?

改善できることはありますか?


さらにサポートが必要な場合