今回、私が遭遇した問題としてECSが管理するDockerコンテナのルートボリュームはデフォルト約10GBがMAXであるが故にそれを超えてファイルの作成をしようとすると
No space left on device
といわれECSのタスクが途中で終了してしまいました。
ENTRYPOINTとして設定した独自のシェルで数Gのファイルを何個もおとしてくるようにしているんだから、そりゃおちるわ...(ため息)
解決しなければいけない課題
- ルートボリューム10GBの制限を取っ払ってあげないといけません。
- クラスターの設定で「プロビジョニングモデル」を選ぶといいインスタンスを安価に使えない...なんとかして低価格でいいインスタンスを使いたい
ざっくりとした解決方法
まず安価にコンテナインスタンスをたちあげるには「スポットリクエスト」もしくは「リザーブドインスタンス」を使うしか無いとおもいます。
今回はスポットリクエストを使って、安価でいいインスタンスを手に入れたいと思います。
そのスポットリクエストで立ち上がるインスタンス群に対して、
- dockerdの設定を変更
- 10GB制限を取り払う
- docker用のボリュームを追加
- ECSで立ち上げたクラスター傘下に入る
- dockerdの再起動
これらのことをスポットリクエストで立ち上がるインスタンスが起動時に実行できるように ユーザーデータ にシェルを書きたいと思います。
やってみる
クラスター作成
まず、プロビジョニングモデルは オンデマンドインスタンス を選びます。
それ以外を選ぶと、 AutoScalingグループ を作ってくれません。
スポットフリートでどのクラスターで管理するか指定するので、空のクラスターでもいいのですが、後々つくるのめんどくさそうだったので、とりあえずオンデマンドで。
このときつくったクラスタ名を覚えておいてください
例としてあげているクラスタ名はautoscale-cluster
になります。
スポットフリートでスポットインスタンスを立ち上げる
まずAMIはECS対応のAMIを選択してください。
ECS対応AMIは、ここから確認できます。
現時点(2018/02/07)ではamzn-ami-2017.09.g-amazon-ecs-optimized(ami-872c4ae1)
が最新です。
ネットワークやサブネットに関しては、クラスターで設定したネットワークと同じネットワークを設定します。
(ココらへんは適当でもいいと思いますが)
/dev/xvda
はOS用のボリュームです。Dockerイメージが管理されるボリュームはクラスターで設定されたとき(デフォルトであれば、22GiB)のものが使われます。動きはバージョンによって異なるみたいなので、公式ページを確認してください。
今回はdockerのためにEBSボリュームを追加しています。
セキュリティグループやキーペアは作業する環境に合わせて設定してください。
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
やっていることは
- 指定クラスターへの参加
- コンテナのクリーナップを短く。
- 10GB制限を30GB制限まで拡張
- dockerのボリュームはデフォルト22GiBなので、新たに追加した前述のEBSボリュームを追加してあげる
- 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コマンドを打つなどしたら
30GBに拡張されているのがわかりますね。