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

最終更新日: 2020 年 8 月 20 日

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

簡単な説明

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

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

注意: Amazon Linux 1 のサポートは 2020 年 12 月 31 日に終了します。ベストプラクティスとして、サポートが終了する前にワークロードを Amazon Linux 2 に移行してください。

解決方法

Amazon ECS-optimized Amazon Linux AMI でコンテナインスタンスを起動する

重要: 複数のアベイラビリティーゾーンで設定された Auto Scaling グループを使用してインスタンスを起動することがベストプラクティスです。インスタンスをブーストラップするコマンドは、起動設定のユーザーデータに追加できます。

1.    コンテナインスタンスの起動設定にあるユーザーデータセクションに AWS コマンドラインインターフェイス (AWS CLI) と jq パッケージ (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"
    }
]

注意: これで、関連付けられたタスク定義に、十分なディスク容量がないコンテナインスタンスへのタスクの配置を制限する配置制約が設定されました。


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


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