AWS
docker
ECS

ECSで起動するDockerコンテナのルートボリュームの変更をスポットフリートを活用しながら変更してみる

今回、私が遭遇した問題としてECSが管理するDockerコンテナのルートボリュームはデフォルト約10GBがMAXであるが故にそれを超えてファイルの作成をしようとすると

No space left on device

といわれECSのタスクが途中で終了してしまいました。
ENTRYPOINTとして設定した独自のシェルで数Gのファイルを何個もおとしてくるようにしているんだから、そりゃおちるわ...(ため息)

解決しなければいけない課題

  • ルートボリューム10GBの制限を取っ払ってあげないといけません。
  • クラスターの設定で「プロビジョニングモデル」を選ぶといいインスタンスを安価に使えない...なんとかして低価格でいいインスタンスを使いたい

ざっくりとした解決方法

まず安価にコンテナインスタンスをたちあげるには「スポットリクエスト」もしくは「リザーブドインスタンス」を使うしか無いとおもいます。

今回はスポットリクエストを使って、安価でいいインスタンスを手に入れたいと思います。

そのスポットリクエストで立ち上がるインスタンス群に対して、

  • dockerdの設定を変更
    • 10GB制限を取り払う
    • docker用のボリュームを追加
  • ECSで立ち上げたクラスター傘下に入る
  • dockerdの再起動

これらのことをスポットリクエストで立ち上がるインスタンスが起動時に実行できるように ユーザーデータ にシェルを書きたいと思います。

やってみる

クラスター作成

まず、プロビジョニングモデルは オンデマンドインスタンス を選びます。

スクリーンショット 2018-02-06 18.24.34.png

それ以外を選ぶと、 AutoScalingグループ を作ってくれません。

スポットフリートでどのクラスターで管理するか指定するので、空のクラスターでもいいのですが、後々つくるのめんどくさそうだったので、とりあえずオンデマンドで。

このときつくったクラスタ名を覚えておいてください
例としてあげているクラスタ名はautoscale-clusterになります。

スポットフリートでスポットインスタンスを立ち上げる

スクリーンショット 2018-02-06 19.05.46.png

まずAMIはECS対応のAMIを選択してください。
ECS対応AMIは、ここから確認できます。

現時点(2018/02/07)ではamzn-ami-2017.09.g-amazon-ecs-optimized(ami-872c4ae1)が最新です。

ネットワークやサブネットに関しては、クラスターで設定したネットワークと同じネットワークを設定します。
(ココらへんは適当でもいいと思いますが)

スクリーンショット 2018-02-07 11.53.20.png

/dev/xvdaはOS用のボリュームです。Dockerイメージが管理されるボリュームはクラスターで設定されたとき(デフォルトであれば、22GiB)のものが使われます。動きはバージョンによって異なるみたいなので、公式ページを確認してください。

今回はdockerのためにEBSボリュームを追加しています。

スクリーンショット 2018-02-07 16.42.31.png

セキュリティグループやキーペアは作業する環境に合わせて設定してください。

IAMインスタンスプロフィールには、

  • AmazonEC2ContainerServiceforEC2Role
  • AmazonEC2ContainerRegistryReadOnly

のポリシーがアタッチされたIAMを使っています。
これらが無いとECSに参加できないはずです。

ここが今回の問題を解決するユーザーデータへの記述内容になります。

ユーザーデータに記述したシェル

#!/bin/bash
echo ECS_CLUSTER=autoscale-cluster >> /etc/ecs/ecs.config
echo ECS_ENGINE_TASK_CLEANUP_WAIT_DURATION=5m >> /etc/ecs/ecs.config
echo 'OPTIONS="${OPTIONS} --storage-opt dm.basesize=30G"' >> /etc/sysconfig/docker

sudo vgextend docker /dev/xvdba
sudo lvextend -L+30G /dev/docker/docker-pool
sudo service docker restart

やっていることは

  1. 指定クラスターへの参加
  2. コンテナのクリーナップを短く。
  3. 10GB制限を30GB制限まで拡張
  4. dockerのボリュームはデフォルト22GiBなので、新たに追加した前述のEBSボリュームを追加してあげる
  5. dockerdの再起動

となります。

このあとのスポット価格、いつまで継続するかなどの設定はご自身の環境に合わせて設定してください。

確認

ECSの設定確認

cat /etc/ecs/ecs.config

これを実行すると以下の結果が得られると思います。

ECS_CLUSTER=autoscale-cluster
ECS_ENGINE_TASK_CLEANUP_WAIT_DURATION=5m

dockerdの設定確認

ps aux | grep dockerd

を実行すると

root      3389  0.6  0.1 1109744 56948 ?       Sl   04:06   1:37 /usr/bin/dockerd --default-ulimit nofile=1024:4096 --storage-opt dm.basesize=30G --storage-driver devicemapper --storage-opt dm.thinpooldev=/dev/mapper/docker-docker--pool --storage-opt dm.use_deferred_removal=true --storage-opt dm.use_deferred_deletion=true --storage-opt dm.fs=ext4 --storage-opt dm.use_deferred_deletion=true

のような結果が得られると思います。
dm.basesize=30G がちゃんと考慮されてますね。

実際に起動しているdockerに入り、dfコマンドを打つなどしたら

スクリーンショット 2018-02-07 17.24.15.png

30GBに拡張されているのがわかりますね。

お世話になったサイト