ECS optimized AMIはAmazon LinuxでDockerを動かす様になっている。
Amazon LinuxのDockerはデフォルトでdevice mapperをストレージのバックエンドにしている。
device mapperではコンテナに変更が入った時のレイヤーやベースイメージがsnapshotで表現されており、その上限が10GBになっている。
つまり、10GB以上の変更を加えられないので、例えば10GBを越えるファイルを一度にDLしてきて一時ファイルとして保持するとかの場合にディスクが足りなくなる。
バッチ処理のワーカーとかだと割とそれを越えるのはあり得る。
イメージごとカスタマイズしてしまえば簡単に実現できるが、管理イメージが増えるより、起動時のコンフィグという形で定義できる方が良かったので、どういう順序で設定が行われているかを調べてみた。
ECS optimized AMIは起動時にcloud-initが/etc/cloud/cloud.cfg.d/
以下にある設定を読み、bootcmdフックでdocker-storage-setup
というシェルスクリプトを実行する。
そこで/etc/sysconfig/docker-storage-setup
を読んで、その設定に合わせてdevice mapperのボリュームを構築し、DOCKERの起動オプションを定義したファイルを生成する。
なので、こいつより前に/etc/sysconfig/docker-storage-setup
に--storage-opt dm.basesize=40GB
って感じの値を書く様にしなければならない。
bootcmdはかなり速い段階で実行されるフックなので、どうしたもんかなーと思ってたらcloud-initには最速で実行されるboothookというものがあるらしい。
(cf. http://cloudinit.readthedocs.io/en/latest/topics/format.html#cloud-boothook)
multipartで起動設定を作り込んで、boothookとユーザースクリプトの両方を起動時にuser-dataとして送り込むと上手く設定できそう。
で、terraformで設定書いてみた。
data "template_file" "ecs_config" {
template = "${file("${path.module}/ecs_config.sh.tpl")}"
}
data "template_file" "add_docker_storage_option" {
template = "${file("${path.module}/add_docker_storage_option.sh.tpl")}"
vars {
dm_base_size = "${var.dm_base_size}"
}
}
data "template_cloudinit_config" "config" {
gzip = true
base64_encode = true
part {
content_type = "text/cloud-boothook"
filename = "add_docker_storage_option.sh"
content = "${data.template_file.add_docker_storage_option.rendered}"
}
part {
filename = "ecs_config.sh"
content_type = "text/x-shellscript"
content = "${data.template_file.ecs_config.rendered}"
}
}
resource "aws_launch_configuration" "ecs" {
# 省略
user_data = "${data.template_cloudinit_config.config.rendered}"
}
#!/bin/bash
echo 'EXTRA_DOCKER_STORAGE_OPTIONS="$EXTRA_DOCKER_STORAGE_OPTIONS --storage-opt dm.basesize=${dm_base_size}"' >> /etc/sysconfig/docker-storage-setup
こんな感じ。
これで起動してみたら、想定通りBaseSizeが変更できた。
ちなみにboothookは起動時には毎回問答無用で実行されるらしいので、再起動するとかを想定している場合は、ガード機構をスクリプトに組み込んでおく必要があるだろう。
ECSのクラスタに組込む場合、落としたら普通ノードごと破棄することがほとんどだと思うので、自分は気にしないことにした。