ECSでコンテナインスタンス間でデータボリュームを同期したい時

ECSの話

ECS以前にDockerを使っているとデータを永続化したかったりコンテナ間でデータを共有したいってことがあると思う

hatappi.hateblo.jp 今回は前の記事でDigdagのセッション情報をデータボリュームに退避させコンテナを立て直しても続きからをECS上で行いたかった

ECSをブラウザ上から設定している時はタスク定義画面の下の方にボリュームを追加するボタンがあるので追加して

f:id:hatappi1225:20170512175509p:plain

コンテナを追加する際にさきほど追加したボリュームをマウントしてあげるだけで使用できる
f:id:hatappi1225:20170512175527p:plain

これらはAWSのECSのドキュメントにも書いてある
画面からポチポチやるだけなので楽ちんですね

ただこのドキュメントを読むと分かるが下記のように書かれている

Amazon ECS は、コンテナインスタンス間でデータボリュームを同期しません。永続データボリュームを使用するタスクは、使用可能なキャパシティーのあるクラスター内のコンテナインスタンスに配置できます。タスクを停止して再び開始した後に永続データボリュームが必要な場合は、タスクの開始時に毎回、AWS CLI の start-task コマンドを使用して同じコンテナインスタンスを指定する必要があります。

つまり最初はクラスタ内のEC2_1でDigdagが処理されて何らかの要因で落ちた後に再度EC2_1に割り当てられればデータボリュームからセッション情報をとれるがEC2_2に割り当てられてしまった場合はセッション情報がないので最初からになってしまう

でもしたい!!

そんな時はサードパーティ製にはなるがs3fs-fuse/s3fs-fuseを使用する
これはS3をEC2にマウントするものでこれを使って任意のバケットを例えば /s3としてEC2にマウントして後はタスク定義のボリューム追加の際に/s3をソースパスとして追加してあげればコンテナからも見ることができ、共有データはS3に保存されるので他のインスタンスからも参照が出来るようになる

f:id:hatappi1225:20170512175835p:plain

ハマりポイント

S3をマウントしてボリュームとして追加したのにコンテナ上から見えない

Dockerデーモンはプロセスの起動時にマウントされていたデバイスしか認識しないためDocker デーモンが起動した後にS3のマウント処理した時におきる

これを解決するものしては下記のようにrestartしてあげればコンテナ上でも認識できるようになった

$  sudo service docker restart && sudo start ecs

最後に

今回はサードパーティのツールを使用したのでAWSのサポート外でかつレイテンシも発生する
ただこれはEFSが東京リージョンにくれば複数のコンテナインスタンスにマウントできるようになるので今回の件はすっきりする
https://aws.amazon.com/jp/blogs/compute/using-amazon-efs-to-persist-data-from-amazon-ecs-containers/