バインドマウント - Amazon Elastic Container Service

バインドマウント

バインドマウントでは、ホスト (Amazon EC2 インスタンスや AWS Fargate など) 上のファイルまたはディレクトリがコンテナにマウントされますバインドマウントは、Fargate インスタンスと Amazon EC2 インスタンスの両方でホストされているタスクでサポートされています。デフォルトではバインドマウントは、それらを使用してコンテナのライフサイクルに関連付けられます。タスクが停止するなど、バインドマウントを使用するすべてのコンテナが停止すると、データが削除されます。Amazon EC2 インスタンスでホストされているタスクの場合、タスク定義で host 値とオプションの sourcePath 値を指定することにより、データをホスト Amazon EC2 インスタンスのライフサイクルに関連付けることができます。詳細については、Docker ドキュメントの 「バインドマウントの使用」を参照してください。

バインドマウントの一般的なユースケースは以下のとおりです。

  • 1 つ以上のコンテナにマウントするための空のデータボリュームを提供する。

  • 1 つ以上のコンテナにホストデータボリュームをマウントする。

  • ソースコンテナのデータボリュームを、同じタスク内の他のコンテナと共有する。

  • Dockerfile から 1 つ以上のコンテナにパスとその内容を公開する。

バインドマウントを使用するときの考慮事項

バインドマウントを使用する際には、以下の点を考慮する必要があります。

  • プラットフォームバージョン 1.4.0 以降を使用する AWS Fargate でホストされているタスクの場合、デフォルトではバインドマウント用に最低 20 GiB のエフェメラルストレージを受け取ります。エフェメラルストレージの総量は、最大 200 GiB まで増やすことができます。ephemeralStorageオブジェクトを、タスク定義に追加します。

  • タスクの実行時に Dockerfile のファイルをデータボリュームに公開するために、Amazon ECS データプレーンが VOLUME ディレクティブを探します。VOLUME ディレクティブで指定された絶対パスがタスク定義で指定された containerPath と同じである場合、VOLUME ディレクティブパスのデータがデータボリュームにコピーされます。次の Dockerfile の例では、examplefile ディレクトリにある /var/log/exported という名前のファイルがホストに書き込まれ、コンテナ内にマウントされます。

    FROM public.ecr.aws/amazonlinux/amazonlinux:latest RUN mkdir -p /var/log/exported RUN touch /var/log/exported/examplefile VOLUME ["/var/log/exported"]

    デフォルトでは、ボリュームのアクセス許可は 0755 に設定され、所有者は root に設定されます。これらのアクセス許可は Dockerfile でカスタマイズできます。次の例では、ディレクトリの所有者を node として定義しています。

    FROM public.ecr.aws/amazonlinux/amazonlinux:latest RUN yum install -y shadow-utils && yum clean all RUN useradd node RUN mkdir -p /var/log/exported && chown node:node /var/log/exported RUN touch /var/log/exported/examplefile USER node VOLUME ["/var/log/exported"]
  • Amazon EC2 インスタンスでホストされているタスクで、host 値と sourcePath 値が指定されていない場合、Docker デーモンがバインドマウントを管理します。このバインドマウントを参照しているコンテナがないと、そのボリュームは Amazon ECS コンテナエージェントのタスククリーンアップサービスによって、最終的に削除されます (デフォルトでは、コンテナが終了してから 3 時間後に削除されますが、この期間はエージェント変数 ECS_ENGINE_TASK_CLEANUP_WAIT_DURATION で設定できます)。詳細については、「Amazon ECS コンテナエージェントの設定」を参照してください。コンテナのライフサイクルを通じてこのデータを永続化する必要がある場合は、バインドマウントの sourcePath 値を指定します。

タスク定義でバインドマウントを指定する

Fargate またはAmazon EC2 インスタンスのいずれかでホストされている Amazon ECS タスクの場合、次のタスク定義の JSON スニペットは、タスク定義の volumesmountPoints、および ephemeralStorage のオブジェクトの構文を示します。

{ "family": "", ... "containerDefinitions" : [ { "mountPoints" : [ { "containerPath" : "/path/to/mount_volume", "sourceVolume" : "string" } ], "name" : "string" } ], ... "volumes" : [ { "name" : "string" } ], "ephemeralStorage": { "sizeInGiB": integer } }

Amazon EC2 インスタンスでホストされる Amazon ECS タスクの場合、タスクボリュームの詳細を指定するときに、オプションの host パラメータと sourcePath を使用できます。これを指定すると、バインドマウントがコンテナではなくタスクのライフサイクルに関連付けられます。

"volumes" : [ { "host" : { "sourcePath" : "string" }, "name" : "string" } ]

以下では、各タスク定義パラメータについて詳しく説明します。

name

型: 文字列

必須: いいえ

ボリュームの名前。最大 255 文字の英字 (大文字と小文字)、数字、ハイフン、アンダースコアを使用できます。この名前は、コンテナ定義 sourceVolumemountPoints パラメータで参照されます。

host

必須: いいえ

バインドマウントを使用する場合、このパラメータが指定されます。Docker ボリュームを使用するには、代わりに dockerVolumeConfiguration を指定します。host パラメータの内容により、バインドマウントのデータボリュームがホストコンテナインスタンスで保持されるかどうかと、その保存場所が決まります。host パラメーターが空の場合、Docker デーモンはデータボリュームのホストパスを割り当てますが、関連付けられたコンテナの実行が停止した後にデータが保持されるとは限りません。

バインドマウントのホストボリュームは、EC2 または Fargate 起動タイプを使用する場合にサポートされます。

Windows コンテナは $env:ProgramData と同じドライブに全部のディレクトリをマウントできます。

sourcePath

型: 文字列

必須: いいえ

host パラメータを使用する場合は、sourcePath を指定して、コンテナに表示されるホストコンテナインスタンスのパスを宣言します。このパラメータが空の場合は、Docker デーモンによってホストパスが割り当てられています。host パラメータに sourcePath の場所が含まれている場合、データボリュームは手動で削除するまでホストコンテナインスタンスの指定された場所に保持されます。sourcePath の場所がホストコンテナインスタンスに存在しない場は、Docker デーモンによって作成されます。その場所が存在する場合は、ソースパスフォルダの内容がエクスポートされます。

mountPoints

タイプ: オブジェクト配列

必須: いいえ

コンテナでのデータボリュームのマウントポイント。

このパラメータは、Docker Remote APICreate a container (コンテナを作成する) セクションの Volumes にマップされ、--volume オプションは docker run にマップされます。

Windows コンテナは $env:ProgramData と同じドライブに全部のディレクトリをマウントできます。Windows コンテナは、別のドライブにディレクトリをマウントできません。また、マウントポイントは複数のドライブにまたがることはできません。

sourceVolume

型: 文字列

必須: はい (mountPoints を使用する場合)

マウントするボリュームの名前。

containerPath

型: 文字列

必須: はい (mountPoints を使用する場合)

ボリュームをマウントするコンテナ上のパス。

readOnly

タイプ: ブール値

必須: いいえ

この値が true の場合、コンテナはボリュームへの読み取り専用アクセスを許可されます。この値が false の場合、コンテナはボリュームに書き込むことができます。デフォルト値は false です。

ephemeralStorage

タイプ: オブジェクト

必須: いいえ

タスクに割り当てるエフェメラルストレージの量。このパラメーターを使用して、利用可能な一時ストレージの総量をデフォルト容量を超えて拡張します。AWS Fargate使用, プラットフォームのバージョンを1.4.0以降.

コパイロットCLI、CloudFormation、AWSSDK または CLI を使用して、バインドマウントのエフェメラルストレージを指定します。

バインドマウントの例

以下の例では、コンテナにバインドマウントを使用する場合の最も一般的なユースケースについて説明します。

Fargate タスク用の一時ストレージ容量の増加を割り当てるには

プラットフォームバージョン 1.4.0 以降を使用して Fargate でホストされる Amazon ECS タスクの場合、使用するタスク内のコンテナに対して、デフォルト容量を超えるエフェメラルストレージを割り当てることができます。この例は、他の例に組み込むことで、Fargate タスクに一時ストレージを割り当てることができます。

  • タスク定義で、ephemeralStorageオブジェクトを定義します。sizeInGiB21および200 の値の間にある整数である必要があり、GiB に表されます。

    "ephemeralStorage": { "sizeInGiB": integer }

1 つまたは複数のコンテナに空のデータボリュームを提供する

場合によっては、タスク内のコンテナにスクラッチスペースを提供することがあります。たとえば、タスクの実行中に同じスクラッチファイルの保存場所にアクセスする必要のある 2 つのデータベースコンテナがあるとします。これは、バインドマウントを使用して実現できます。

  1. タスク定義の volumes セクションで、名前を database_scratch としてバインドマウントを定義します。

    "volumes": [ { "name": "database_scratch", } ]
  2. containerDefinitions セクションで、ボリュームをマウントするようにデータベースのコンテナの定義を作成します。

    "containerDefinitions": [ { "name": "database1", "image": "my-repo/database", "cpu": 100, "memory": 100, "essential": true, "mountPoints": [ { "sourceVolume": "database_scratch", "containerPath": "/var/scratch" } ] }, { "name": "database2", "image": "my-repo/database", "cpu": 100, "memory": 100, "essential": true, "mountPoints": [ { "sourceVolume": "database_scratch", "containerPath": "/var/scratch" } ] } ]

Dockerfile 内のパスとその内容をコンテナに公開する

この例には、コンテナ内にマウントするデータを書き込む Dockerfile があります。この例は、Fargate または Amazon EC2 インスタンスでホストされているタスクで機能します。

  1. Dockerfile を作成します。次の例では、パブリック Amazon Linux 2 コンテナイメージを使用して、コンテナ内にマウントする /var/log/exported ディレクトリに examplefile という名前のファイルを作成します。VOLUME ディレクティブは絶対パスを指定する必要があります。

    FROM public.ecr.aws/amazonlinux/amazonlinux:latest RUN mkdir -p /var/log/exported RUN touch /var/log/exported/examplefile VOLUME ["/var/log/exported"]

    デフォルトでは、ボリュームのアクセス許可は 0755 に設定され、所有者は root に設定されます。これらのアクセス許可は Dockerfile で変更できます。以下の例では、/var/log/exported ディレクトリの所有者が node に設定されています。

    FROM public.ecr.aws/amazonlinux/amazonlinux:latest RUN yum install -y shadow-utils && yum clean all RUN useradd node RUN mkdir -p /var/log/exported && chown node:node /var/log/exported RUN touch /var/log/exported/examplefile USER node VOLUME ["/var/log/exported"]
  2. タスク定義の volumes セクションで、名前を application_logs としてボリュームを定義します。

    "volumes": [ { "name": "application_logs", } ]
  3. containerDefinitions セクションで、ストレージをマウントするようにアプリケーションのコンテナの定義を作成します。containerPath 値は、Dockerfile の VOLUME ディレクティブで指定された絶対パスと一致する必要があります。

    "containerDefinitions": [ { "name": "application1", "image": "my-repo/application", "cpu": 100, "memory": 100, "essential": true, "mountPoints": [ { "sourceVolume": "application_logs", "containerPath": "/var/log/exported" } ] }, { "name": "application2", "image": "my-repo/application", "cpu": 100, "memory": 100, "essential": true, "mountPoints": [ { "sourceVolume": "application_logs", "containerPath": "/var/log/exported" } ] } ]

ホスト Amazon EC2 インスタンスのライフサイクルに関連付けられているコンテナに空のデータボリュームを提供する

Amazon EC2 インスタンスでホストされているタスクの場合、バインドマウントを使用して、ボリュームを参照するコンテナではなく、ホスト Amazon EC2 インスタンスのライフサイクルにデータを関連付けることができます。これは、host パラメータを使用して sourcePath 値を指定することによって行われます。sourcePath に存在するファイルは、containerPath 値のコンテナに渡され、containerPath 値に書き込まれたファイルは、ホスト Amazon EC2 インスタンスの sourcePath 値に書き込まれます。

重要

Amazon ECS は、Amazon EC2 インスタンス間でストレージを同期しません。永続的ストレージを使用するタスクは、使用可能なキャパシティーのあるクラスター内の Amazon EC2 インスタンスに配置できます。タスクを停止して再び開始した後に永続的ストレージが必要な場合は、タスクの開始時に毎回、AWS CLI の start-task コマンドを使用して同じ Amazon EC2 インスタンスを指定する必要があります。永続ストレージに Amazon EFS ボリュームを使用することもできます。詳細については、「Amazon EFS ボリューム」を参照してください。

  1. タスク定義の volumes セクションで、name および sourcePath 値を使用して、バインドマウントを定義します。次の例では、ホスト Amazon EC2 インスタンスはコンテナ内にマウントしたい /ecs/webdata のデータを含めます。

    "volumes": [ { "name": "webdata", "host": { "sourcePath": "/ecs/webdata" } } ]
  2. containerDefinitions セクションで、定義したバインドマウントの名前を参照する mountPoints 値と、コンテナにバインドマウントをマウントするための containerPath 値を使用して、コンテナを定義します。

    "containerDefinitions": [ { "name": "web", "image": "nginx", "cpu": 99, "memory": 100, "portMappings": [ { "containerPort": 80, "hostPort": 80 } ], "essential": true, "mountPoints": [ { "sourceVolume": "webdata", "containerPath": "/usr/share/nginx/html" } ] } ]

定義したボリュームを異なる場所にある複数のコンテナにマウントする

タスク定義でデータボリュームを定義し、そのボリュームをさまざまなコンテナのさまざまな場所にマウントできます。たとえば、ホストコンテナにウェブサイトのデータフォルダ /data/webroot があり、さまざまなドキュメントルートのある 2 つの異なるウェブサーバーに、そのデータボリュームを読み取り専用としてマウントするとします。

  1. タスク定義の volumes セクションで、名前を webroot、ソースパスを /data/webroot としてデータボリュームを定義します。

    "volumes": [ { "name": "webroot", "host": { "sourcePath": "/data/webroot" } } ]
  2. containerDefinitions セクションで、各ウェブサーバーのコンテナを定義しています。各コンテナの mountPoints で、webroot ボリュームを、そのコンテナのドキュメントルートを参照する containerPath 値に関連付けます。

    "containerDefinitions": [ { "name": "web-server-1", "image": "my-repo/ubuntu-apache", "cpu": 100, "memory": 100, "portMappings": [ { "containerPort": 80, "hostPort": 80 } ], "essential": true, "mountPoints": [ { "sourceVolume": "webroot", "containerPath": "/var/www/html", "readOnly": true } ] }, { "name": "web-server-2", "image": "my-repo/sles11-apache", "cpu": 100, "memory": 100, "portMappings": [ { "containerPort": 8080, "hostPort": 8080 } ], "essential": true, "mountPoints": [ { "sourceVolume": "webroot", "containerPath": "/srv/www/htdocs", "readOnly": true } ] } ]

volumesFrom を使用して別のコンテナからボリュームをマウントするには

あるコンテナに 1 つ以上のボリュームを定義し、同じタスクの異なるコンテナ定義で volumesFrom パラメータを使用して、sourceContainer のすべてのボリュームを、最初に定義されていたマウントポイントにマウントできます。volumesFrom パラメータは、タスク定義で定義されたボリューム、および Dockerfile でイメージに組み込まれたボリュームに適用されます。

  1. (オプション) イメージに組み込まれたボリュームを共有するには、そのボリュームを VOLUME 命令で宣言してイメージを構築する必要があります。次の例では、Dockerfile は httpd イメージを使用し、ボリュームを追加して、Apache ドキュメントルート (dockerfile_volume ウェブサーバーで使用されるフォルダ) の httpd にマウントします。

    FROM httpd VOLUME ["/usr/local/apache2/htdocs/dockerfile_volume"]

    この Dockerfile を使用してイメージを構築し、Docker ハブなどのレポジトリにプッシュして、タスク定義で使用できます。以下の手順で例として使用する my-repo/httpd_dockerfile_volume イメージは上記の Dockerfile から構築しました。

  2. コンテナの他のボリュームとマウントポイントを定義するタスク定義を作成します。この例の volumes セクションでは、Docker デーモンによって管理される空のボリューム empty を作成します。また、ホストコンテナインスタンスに host_etc をエクスポートするホストボリューム /etc も定義しています。

    { "family": "test-volumes-from", "volumes": [ { "name": "empty", "host": {} }, { "name": "host_etc", "host": { "sourcePath": "/etc" } } ],

    コンテナ定義セクションで、先ほど定義したボリュームをマウントするコンテナを作成します。この例の web コンテナ (Dockerfile で指定されたボリュームで構築されたイメージを使用) は empty ボリュームと host_etc ボリュームをマウントします。

    "containerDefinitions": [ { "name": "web", "image": "my-repo/httpd_dockerfile_volume", "cpu": 100, "memory": 500, "portMappings": [ { "containerPort": 80, "hostPort": 80 } ], "mountPoints": [ { "sourceVolume": "empty", "containerPath": "/usr/local/apache2/htdocs/empty_volume" }, { "sourceVolume": "host_etc", "containerPath": "/usr/local/apache2/htdocs/host_etc" } ], "essential": true },

    volumesFrom を使用して、web コンテナに関連付けられているすべてのボリュームをマウントする、別のコンテナを作成します。web コンテナのすべてのボリュームは busybox コンテナ (my-repo/httpd_dockerfile_volume イメージの構築に使用された Dockerfile で指定されたボリュームを含む) にも同様にマウントされます。

    { "name": "busybox", "image": "busybox", "volumesFrom": [ { "sourceContainer": "web" } ], "cpu": 100, "memory": 500, "entryPoint": [ "sh", "-c" ], "command": [ "echo $(date) > /usr/local/apache2/htdocs/empty_volume/date && echo $(date) > /usr/local/apache2/htdocs/host_etc/date && echo $(date) > /usr/local/apache2/htdocs/dockerfile_volume/date" ], "essential": false } ] }

    このタスクが実行されると、2 つのコンテナでボリュームがマウントされ、command コンテナで busybox が各ボリュームフォルダの date という名前のファイルに日付と時刻を書き込みます。その後、フォルダは web コンテナによって表示されるウェブサイトで見ることができます。

    注記

    busybox コンテナはクイックコマンドを実行して終了するため、コンテナ定義で "essential": false として設定する必要があります。そうしなければ、終了時にタスク全体が停止します。