ECS で Docker volume plugin を使って EFS 連携してみた

2018.08.16

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

オペレーション部の下田です。つい先日、ECS で Docker Volume と Volume Plugin がサポートされました。公式のアナウンスについては、以下のリンク先を参照してください。

これまで ECS で EFS を利用する場合、予め ECS インスタンス起動時に ECS 環境で利用する EFS を特定のマウントポイントに対して NFS マウントしておく必要がありました。公式の手順としては、下記のチュートリアルが公開されております。

今回 ECS で Docker Volume と Volume Plugin がサポートされたことにより、気軽に EFS を利用することが出来そうだなと感じたので、EFS に対応している Docker volume plugin を試してみました。 なお、今回の検証で利用した plugin は Netshare plugin です。Netshare plugin に関する詳細については、下記の公式サイトをご確認ください。

また、その他の(Docker 公式ドキュメントに記載されている)利用可能な plugin については、下記のドキュメントをご参照ください。

事前準備

ECS インスタンスの起動 AMI として ECS Optimized AMI 2018.03.d を利用しました。

  • amzn-ami-2018.03.d-amazon-ecs-optimized - ami-256c15c8

また、公式のチュートリアルを参考に作業を進めます。(予め EFS を ECS で利用するために必要な作業などを実施済みであることが前提)

チュートリアルに記載されている「ユーザーデータにより Amazon EFS を使用するようにインスタンスをブートストラップする」手順 2 のユーザーデータを、以下に置き換えることにより Netshare plugin が組み込まれた ECS インスタンスが起動します。

Content-Type: multipart/mixed; boundary="//"
MIME-Version: 1.0

--//
Content-Type: text/cloud-boothook; charset="us-ascii"

# Install nfs-utils wget docker-volume-netshare
cloud-init-per once yum_update yum update -y
cloud-init-per once install_nfs_utils_and_wget yum install -y nfs-utils wget
cloud-init-per once wget_docker-volume-netshare wget https://github.com/ContainX/docker-volume-netshare/releases/download/v0.35/docker-volume-netshare_0.35_linux_amd64-bin -O /usr/bin/docker-volume-netshare
cloud-init-per once chmod_docker-volume-netshare chmod 755 /usr/bin/docker-volume-netshare
cloud-init-per once start_docker-volume-netshare_daemon /usr/bin/docker-volume-netshare efs >> /var/log/docker-volume-netshare.log 2>&1 &
--//
Content-Type: text/x-shellscript; charset="us-ascii"

#!/bin/bash
echo ECS_CLUSTER=development >> /etc/ecs/ecs.config
--//

注意事項は、以下のとおりです。

  • ECS_CLUSTER の設定は、利用環境に合わせて適宜修正してください。
  • 検証用途での利用を想定しているため、本番環境に設定しないでください。

やってみた

公式チュートリアルのステップ 5(Amazon EFS ファイルシステムを使用するためのタスク定義を作成する)以降を、マネジメントコンソールからやってみます。

2018/8/16 現在 Fargate の EFS サポートは提供されていないため、EC2 起動タイプを選択します。

efs-plugin-test タスク定義を作成します。

コンテナは、チュートリアル同様に nginx を利用します。 「ボリュームの追加」をクリックします。

「ボリュームドライバーを選択してください」と記載されたチェックボックスを選択します。

下記の設定を行います。

  • ボリュームの名前として EFS のファイルシステム ID を入力
  • ドライバーに "efs" を入力
  • スコープに shared を選択
  • 自動プロビジョニングを有効にするのチェックボックスにチェックを入れる

画面をスクロールすると、Volume labels を設定することが可能なため適宜設定してください。 全ての項目を入力後、追加ボタンをクリックすればボリュームの追加作業は完了です。

次にコンテナ設定側で EFS を利用する設定を行います。 項目:ストレージとログにあるマウントポイントのソースボリュームとして、先程追加した EFS のボリュームを指定します。また、コンテナパスはチュートリアルの記載に従い /usr/share/nginx/html としました。

設定が完了すれば、タスク定義を作成しましょう。

また、続けてアクションから作成したタスク定義をもとにタスクを実行します。

タスクが作成されたタイミングで、ECS インスタンス側を確認すると EFS Backed な Docker volume が作成されていました。

$ docker volume ls # タスク作成前
DRIVER VOLUME NAME
↓
$ docker volume ls # タスク作成後
DRIVER VOLUME NAME
efs fs-deadbeef
$ docker volume inspect fs-deadbeef
[
{
"CreatedAt": "0001-01-01T00:00:00Z",
"Driver": "efs",
"Labels": {
"Name": "ECS-EFS"
},
"Mountpoint": "/var/lib/docker-volumes/netshare/efs/fs-deadbeef",
"Name": "fs-deadbeef",
"Options": null,
"Scope": "local"
}
]
$ df -h /var/lib/docker-volumes/netshare/efs/fs-deadbeef
Filesystem Size Used Avail Use% Mounted on
10.0.1.126:/ 8.0E 0 8.0E 0% /var/lib/docker-volumes/netshare/efs/fs-deadbeef
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a98df2ba715b nginx:latest "nginx -g 'daemon of…" 58 seconds ago Up 57 seconds 0.0.0.0:80->80/tcp ecs-efs-plugin-test-2-nginx-f885ddc8baece4f8bd01

合わせて nginx コンテナも起動済みであるため、index.html を変更しブラウザから確認してみます。

$ ls -l /var/lib/docker-volumes/netshare/efs/fs-deadbeef
total 8
-rw-r--r-- 1 root root 537 Jul 24 13:02 50x.html
-rw-r--r-- 1 root root 612 Jul 24 13:02 index.html
$ sudo bash -c "cat >/var/lib/docker-volumes/netshare/efs/fs-deadbeef/index.html" <<'EOF' >>
>
<h1>It Works!</h1>
>

You are using an Amazon EFS file system for persistent container storage.

>
>
> EOF
$ ls -l /var/lib/docker-volumes/netshare/efs/fs-deadbeef
total 8
-rw-r--r-- 1 root root 537 Jul 24 13:02 50x.html
-rw-r--r-- 1 root root 154 Aug 16 01:32 index.html

先程、更新した内容のコンテンツがブラウザから確認できました。

さいごに

ECS で Docker Volume と Volume Plugin がサポートされたことにより、EFS に対応する plugin を利用すればタスク定義で設定された EFS を ECS インスタンス側で動的にマウントし利用できることが確認できました。 そのため、今後 EFS に対応する Volume Plugin の RPM パッケージが提供されれば ECS と EFS サービスの連携はより強化(柔軟性が高まる)されるものと期待しております。

推測とはなりますが、この仕組みが Fargate で利用されている(AWS マネージドな)ECS インスタンス側に導入されることによって、Fargate 環境での EFS サポートが提供されるのではないかと期待しています。

ではでは