はじめに
Amazon ECS が やっと Docker Volumes をサポートしました。
これまでも使用できていた Bind Mounts と Docker Volumes の違いについては
Docker のドキュメントを参照いただくのがよいかと思います。
Use volumes
https://docs.docker.com/storage/volumes/
また Docker Volumes は Fargate ではサポートされてません。
Fargate の場合はこれまでどおり Bind Mounts を使用します。
Docker Volumes
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/docker-volumes.html
Bind Mounts
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/bind-mounts.html
環境情報
以下で検証しています。
- リージョン : 東京
- AMI: amzn-ami-2018.03.d-amazon-ecs-optimized [ami-256c15c8]
- Dockerバージョン: 18.03.1-ce
- ECS Agentバージョン: 1.20.0
タスク定義の作成
既存のタスク定義から新しいリビジョンを作成するか、タスク定義自体を新たに作成します。
ここでは既存のタスク定義を使用するため割愛しますが、検証用の Docker イメージがない場合は
以下の公式 Hello Wolrd や サンプルアプリケーションを活用するのが良いかと思います。
- Dockerイメージの作成
- Amazon ECS PHP Simple Demo App
タスク定義の最下部からボリュームの追加を選択します。
ボリュームドライバーを選択してください にチェックを入れます。
ライフサイクルの違いで、2種類のスコープが利用できます。
- task : タスクの開始時に自動的にプロビジョニングされ、タスクの終了とともに削除される
- shared : タスクが停止した後も削除されない
ここでは検証のため両方のタイプのボリュームを追加します。
shared の場合は事前に作成済みのボリュームを指定することも可能ですが、存在しない場合は
自動プロビジョニングを有効にする にチェックすることで、自動で作成できます。
追加したボリュームをコンテナから参照するには、コンテナ定義の ストレージとログ を設定します。
ソースボリュームで作成したボリュームを、コンテナパスでコンテナ上のマウント先を指定します。
ここでは ecs-test-volume-task を /tmp/ecs-test-volume-task に、
ecs-test-volume-shared を /tmp/ecs-test-volume-shared にマウントするよう設定します。
サービスの作成
クラスターに新規サービスを作成するか、既存のサービスを更新して先ほど作成した
最新のタスク定義をデプロイします。
ここでは ecs-test-volume-cluster というクラスターに ecs-test-volume-service
というサービスを作成しています。
動作確認用なのでタスクの数は1です。
ネットワーク構成では、今回はネットワークモードを awsvpc に設定しているので、
VPCやセキュリティグループの情報を設定します。ELBは設定せず進みます。
ネットワークモードの awsvpc については以前投稿した記事も参照いただければと思います。
Amazon ECSの ネットワークモードに追加された awsvpcを試す
https://qiita.com/hayao_k/items/ca5d326482278e325bfc
Service Auto Scaling の設定も今回は行いません。
サービスの作成が完了したら、
Service : ecs-test-volume-service で作成したタスク定義が RUNNING になっていることを確認します。
動作確認(ボリュームの確認)
ECSインスタンスにログインして、ボリュームが作成されていることを確認します。
$ docker volume ls
DRIVER VOLUME NAME
local ecs-console-sample-app-static-6-ecs-test-volume-task-86e4a5c4adddc180db01
local ecs-test-volume-shared
スコープが task の場合は VOLUME NAME は自動的に設定されるようです。
inspect で確認すると、ボリュームが /var/lib/docker/volumes 配下に作成されているのがわかります。
$ docker volume inspect ecs-console-sample-app-static-6-ecs-test-volume-task-86e4a5c4adddc180db01
[
{
"CreatedAt": "2018-08-13T09:37:54Z",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/ecs-console-sample-app-static-6-ecs-test-volume-task-86e4a5c4adddc180db01/_data",
"Name": "ecs-console-sample-app-static-6-ecs-test-volume-task-86e4a5c4adddc180db01",
"Options": null,
"Scope": "local"
}
]
$ docker volume inspect ecs-test-volume-shared
[
{
"CreatedAt": "2018-08-13T09:37:54Z",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/ecs-test-volume-shared/_data",
"Name": "ecs-test-volume-shared",
"Options": null,
"Scope": "local"
}
]
次にコンテナに接続して確認します。
設定したパスにボリュームがマウントされていることが確認できます。
$ docker exec -it <CONTAINER ID> /bin/bash
root@ip-10-0-1-238:/# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/docker-202:~ 9.8G 250M 9.0G 3% /
tmpfs 64M 0 64M 0% /dev
tmpfs 493M 0 493M 0% /sys/fs/cgroup
/dev/xvda1 7.8G 781M 6.9G 10% /tmp/ecs-test-volume-task
/dev/xvda1 7.8G 781M 6.9G 10% /tmp/ecs-test-volume-shared
/dev/xvda1 7.8G 781M 6.9G 10% /etc/resolv.conf
/dev/xvda1 7.8G 781M 6.9G 10% /etc/hostname
/dev/xvda1 7.8G 781M 6.9G 10% /etc/hosts
shm 64M 0 64M 0% /dev/shm
tmpfs 64M 0 64M 0% /proc/kcore
tmpfs 64M 0 64M 0% /proc/keys
tmpfs 64M 0 64M 0% /proc/latency_stats
tmpfs 64M 0 64M 0% /proc/timer_list
tmpfs 64M 0 64M 0% /proc/sched_debug
tmpfs 493M 0 493M 0% /proc/scsi
tmpfs 493M 0 493M 0% /sys/firmware
最後にタスクを終了させて task と shared のスコープによる動作の違いを確認します。
しかし直接サービスを削除したところ、スコープが task のボリュームが残った状態になってしまいました。
$ docker volume ls
DRIVER VOLUME NAME
local ecs-console-sample-app-static-6-ecs-test-volume-task-86e4a5c4adddc180db01
local ecs-test-volume-shared
もう一度サービスを作成し、サービスの更新でタスクの数を1→0に設定しても同様の挙動で
task の ボリュームが残ったままになってします。。。
$ docker volume ls
DRIVER VOLUME NAME
local ecs-console-sample-app-static-6-ecs-test-volume-task-86e4a5c4adddc180db01
local ecs-console-sample-app-static-6-ecs-test-volume-task-e4dcf8d8b9ffaced2000
local ecs-test-volume-shared
サービスからタスクを起動するのではなく、タスクから 新しいタスクの実行 で試してみます。
タスクから 起動したタスクを停止します。
やはりボリュームが残ったままになってしまいました。
$ docker volume ls
DRIVER VOLUME NAME
local ecs-console-sample-app-static-6-ecs-test-volume-task-86e4a5c4adddc180db01
local ecs-console-sample-app-static-6-ecs-test-volume-task-8ccc95efa8cdccc24200
local ecs-console-sample-app-static-6-ecs-test-volume-task-e4dcf8d8b9ffaced2000
local ecs-test-volume-shared
そもそもタスクの停止時に task のボリュームが消えるという認識自体が違うのかもしれません。
このあたりの挙動については引き続き調査したいと思います。
以下追記を参照
2018/8/15 追記
scope を task に設定したボリュームは、ECS Agentの設定により、デフォルトで3時間後に削除されます。
Amazon ECS コンテナエージェントの設定
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/ecs-agent-config.html
ECS_ENGINE_TASK_CLEANUP_WAIT_DURATION
値の例: 1h (有効な時間単位は「ns」、「us」 (または「µs」)、「ms」、「s」、「m」、および「h」です。)
Linux のデフォルト値: 3h
Windows のデフォルト値: 3h
タスクが停止してから Docker コンテナが削除されるまでの待機時間。これは Docker コンテナのデータを削除するため、この値の設定が小さすぎると、削除される前に停止したコンテナを調べたりログを確認したりできない場合があることに注意してください。最小の期間は 1m です。1 分より短い値は無視されます。
ECS_ENGINE_TASK_CLEANUP_WAIT_DURATION に設定した値が経過後にコンテナが削除されますが、
その際に一緒に scope が task であるボリュームも削除されるようです。
デフォルト値を変更したい場合は設定ファイルに以下の行を追記し、変更を反映させます。
ただしドキュメントに記載にある通り、この間隔で停止したコンテナの削除も行われますのでご注意ください。
ECS_ENGINE_TASK_CLEANUP_WAIT_DURATION=1m ★1分で削除に変更
この設定で改めて確認したところ、タスク停止の1分後にコンテナおよび scope をタスクに設定した
ボリュームが削除され、sharedのボリュームは残ったままであることを確認できました。
もちろんデフォルトの設定であれば3時間後に削除されます。
$ docker volume ls
DRIVER VOLUME NAME
local ecs-console-sample-app-static-6-ecs-test-volume-task-8cdcfbddf8839bfe4e00
local ecs-test-volume-shared
# タスク停止1分後、コンテナが削除されAgentのみが起動されている状態
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
412d92017deb amazon/amazon-ecs-agent:latest "/agent" 7 minutes ago Up 7 minutes ecs-agent
# scope:task のボリュームも削除されている
$ docker volume ls
DRIVER VOLUME NAME
local ecs-test-volume-shared
以上です。
参考になれば幸いです。