前書き

Dockerは、実行に必要なすべてを含むファイルシステムをソフトウェアアプリケーションに提供するために使用される一般的なコンテナ化ツールです。 Dockerコンテナーを使用すると、実行時環境が一貫しているため、ソフトウェアが展開先に関係なく同じように動作します。

一般に、Dockerコンテナーは一時的なものであり、コンテナーで発行されたコマンドが完了するのに必要な時間だけ実行されます。 ただし、コンテナが削除された後、アプリケーションがデータへのアクセスを共有したり、データを保持したりする必要がある場合があります。 データベース、Webサイトのユーザー生成コンテンツ、およびログファイルは、Dockerイメージに含めることは非現実的または不可能であるが、アプリケーションがアクセスする必要があるデータのほんの一例です。 データへの永続的なアクセスはhttps://docs.docker.com/storage/volumes/[Docker Volumes]で提供されます。

Dockerボリュームは、コンテナを作成するのと同じコマンドで作成およびアタッチできます。または、コンテナとは独立して作成し、後でアタッチできます。 この記事では、コンテナ間でデータを共有する4つの異なる方法について説明します。

前提条件

この記事を読むには、次のものを備えたUbuntu 18.04サーバーが必要です。

ステップ1-独立ボリュームの作成

Docker 1.9リリースで導入された `+ docker volume create `コマンドを使用すると、特定のコンテナに関連付けずにボリュームを作成できます。 このコマンドを使用して、 ` DataVolume1 +`という名前のボリュームを追加します。

docker volume create --name DataVolume1

コマンドが成功したことを示す名前が表示されます。

OutputDataVolume1

ボリュームを利用するには、Ubuntuイメージから新しいコンテナを作成し、終了時に `-rm +`フラグを使用して自動的に削除します。 また、「-v 」を使用して新しいボリュームをマウントします。 ` -v +`には、ボリュームの名前、コロン、そしてボリュームがコンテナ内で表示される場所への絶対パスが必要です。 パス内のディレクトリが画像の一部として存在しない場合、コマンドの実行時に作成されます。 _do_が存在する場合、マウントされたボリュームは既存のコンテンツを隠します:

docker run -ti --rm -v DataVolume1:/datavolume1 ubuntu

コンテナにいる間に、いくつかのデータをボリュームに書き込みましょう。

echo "Example1" > /datavolume1/Example1.txt

`+-rm +`フラグを使用したため、終了時にコンテナは自動的に削除されます。 ただし、ボリュームは引き続きアクセス可能です。

exit

`+ docker volume inspect +`を使用して、システムにボリュームが存在することを確認できます。

docker volume inspect DataVolume1
Output[
   {
       "CreatedAt": "2018-07-11T16:57:54Z",
       "Driver": "local",
       "Labels": {},
       "Mountpoint": "/var/lib/docker/volumes/DataVolume1/_data",
       "Name": "DataVolume1",
       "Options": {},
       "Scope": "local"
   }
]

次に、新しいコンテナを開始して、 `+ DataVolume1 +`をアタッチします。

docker run --rm -ti -v DataVolume1:/datavolume1 ubuntu

内容を確認します。

cat /datavolume1/Example1.txt
OutputExample1

コンテナを終了します。

exit

この例では、ボリュームを作成し、コンテナに接続して、その永続性を検証しました。

手順2-コンテナが削除されても持続するボリュームの作成

次の例では、コンテナと同時にボリュームを作成し、コンテナを削除してから、ボリュームを新しいコンテナにアタッチします。

`+ docker run `コマンドを使用して、基本Ubuntuイメージを使用して新しいコンテナーを作成します。 「 -t 」は端末を提供し、「-i 」は端末と対話できるようにします。 明確にするため、 `-name`を使用してコンテナを識別します。

「+ -v 」フラグを使用すると、「 DataVolume2 」と呼ばれる新しいボリュームを作成できます。 コロンを使用して、ボリュームをコンテナにマウントするパスからこの名前を分離します。 最後に、ベースUbuntuイメージを指定し、https://github.com/dockerfile/ubuntu/blob/master/Dockerfile#L32 [UbuntuベースイメージのDockerファイル]のデフォルトのコマンド、 ` bash +`に依存します。シェルにドロップします。

docker run -ti --name=Container2 -v DataVolume2:/datavolume2 ubuntu

コンテナにいる間に、ボリュームにいくつかのデータを書き込みます。

echo "Example2" > /datavolume2/Example2.txt
cat /datavolume2/Example2.txt
OutputExample2

コンテナを終了しましょう:

exit

コンテナを再起動すると、ボリュームが自動的にマウントされます。

docker start -ai Container2

ボリュームが実際にマウントされ、データがまだ存在していることを確認しましょう。

cat /datavolume2/Example2.txt
OutputExample2

最後に、終了してクリーンアップしましょう。

exit

Dockerは、コンテナによって参照されているボリュームを削除させません。 試してみるとどうなるか見てみましょう:

docker volume rm DataVolume2

このメッセージは、ボリュームがまだ使用中であり、コンテナIDの長いバージョンを提供していることを示しています。

OutputError response from daemon: unable to remove volume: remove DataVolume2: volume is in use - []

このIDを使用して、コンテナを削除できます。

docker rm
Outputd0d2233b668eddad4986313c7a4a1bc0d2edaf0c7e1c02a6a6256de27db17a63

コンテナを取り外してもボリュームには影響しません。 `+ docker volume ls +`でボリュームをリストすることで、システムにまだ存在していることがわかります。

docker volume ls
OutputDRIVER              VOLUME NAME
local               DataVolume2

そして、 `+ docker volume rm +`を使用して削除できます。

docker volume rm DataVolume2

この例では、コンテナを作成すると同時に空のデータボリュームを作成しました。 次の例では、既にデータが含まれているコンテナディレクトリでボリュームを作成するとどうなるかを見ていきます。

手順3-データを含む既存のディレクトリからボリュームを作成する

一般に、「+ docker volume create +」を使用してボリュームを個別に作成し、コンテナを作成しながらボリュームを作成することは同等ですが、1つの例外があります。 コンテナを作成すると同時にボリュームを作成する場合は、ベースイメージのデータを含むディレクトリへのパスを指定すると、そのデータがボリュームにコピーされます。

例として、コンテナを作成し、ベースイメージにデータを含むディレクトリ「+ / var +」にデータボリュームを追加します。

docker run -ti --rm -v DataVolume3:/var ubuntu

ベースイメージの `+ / var +`ディレクトリのすべてのコンテンツがボリュームにコピーされ、そのボリュームを新しいコンテナにマウントできます。

現在のコンテナを終了します。

exit

今回は、ベースイメージのデフォルトの `+ bash `コマンドに依存するのではなく、シェルを入力せずにボリュームの内容を表示する独自の ` ls +`コマンドを発行します。

docker run --rm -v DataVolume3:/datavolume3 ubuntu ls datavolume3

ディレクトリ `+ datavolume3 `には、ベースイメージの ` / var +`ディレクトリの内容のコピーがあります。

Outputbackups
cache
lib
local
lock
log
mail
opt
run
spool
tmp

この方法で `+ / var / +`をマウントすることはまずありませんが、独自のイメージを作成し、データを保存する簡単な方法が必要な場合に役立ちます。 次の例では、複数のコンテナ間でボリュームを共有する方法を示します。

ステップ4-複数のDockerコンテナー間でデータを共有する

ここまでで、一度に1つのコンテナにボリュームをアタッチしました。 多くの場合、同じデータボリュームに複数のコンテナを接続する必要があります。 これを達成するのは比較的簡単ですが、1つの重要な注意事項があります。現時点では、Dockerはファイルのロックを処理しません。 ボリュームに複数のコンテナを書き込む必要がある場合、それらのコンテナで実行されるアプリケーションは、データ破損を防ぐために共有データストアに書き込むように設計する必要があります。

Container4およびDataVolume4を作成する

`+ docker run `を使用して、データボリュームが添付された ` Container4 +`という名前の新しいコンテナーを作成します。

docker run -ti --name=Container4 -v DataVolume4:/datavolume4 ubuntu

次に、ファイルを作成してテキストを追加します。

echo "This file is shared between containers" > /datavolume4/Example4.txt

次に、コンテナを終了します。

exit

これにより、ホストコマンドプロンプトに戻り、 `+ Container4 +`からデータボリュームをマウントする新しいコンテナーを作成します。

Container5を作成し、Container4からボリュームをマウントする

`+ Container5 `を作成し、 ` Container4 +`からボリュームをマウントします。

docker run -ti --name=Container5 --volumes-from Container4 ubuntu

データの永続性を確認しましょう。

cat /datavolume4/Example4.txt
OutputThis file is shared between containers

次に、 `+ Container5 +`からテキストを追加します。

echo "Both containers can write to DataVolume4" >> /datavolume4/Example4.txt

最後に、コンテナを終了します。

exit

次に、データがまだ「+ Container 4」に存在することを確認します。

Container5で行われた変更を表示する

`+ Container4 `を再起動して、 ` Container5 +`によってデータボリュームに書き込まれた変更を確認します。

docker start -ai Container4

変更を確認します。

cat /datavolume4/Example4.txt
OutputThis file is shared between containers
Both containers can write to DataVolume4

両方のコンテナがデータボリュームから読み書きできることを確認したので、コンテナを終了します。

exit

繰り返しますが、Dockerはファイルのロックを処理しないため、アプリケーションはファイルをロックする必要があります。 `+:ro +`を追加することにより、コンテナーが読み取り専用アクセスを必要とする場合にデータ破損が偶発的に発生しないように、Dockerボリュームを読み取り専用としてマウントすることができます。 これがどのように機能するか見てみましょう。

Container 6を起動し、ボリュームを読み取り専用でマウントします

ボリュームをコンテナーにマウントしたら、通常のLinuxファイルシステムのようにボリュームをアンマウントするのではなく、必要に応じてマウントした新しいコンテナーを作成し、必要に応じて以前のコンテナーを削除できます。 ボリュームを読み取り専用にするには、コンテナ名の最後に「+:ro +」を追加します。

docker run -ti --name=Container6 --volumes-from Container4:ro ubuntu

サンプルファイルを削除して、読み取り専用ステータスを確認します。

rm /datavolume4/Example4.txt
Outputrm: cannot remove '/datavolume4/Example4.txt': Read-only file system

最後に、コンテナを終了し、テストコンテナとボリュームをクリーンアップします。

exit

以上で、コンテナとボリュームをクリーンアップしましょう。

docker rm Container4 Container5 Container6
docker volume rm DataVolume4

この例では、データボリュームを使用して2つのコンテナ間でデータを共有する方法と、データボリュームを読み取り専用としてマウントする方法を示しました。

結論

このチュートリアルでは、コンテナを削除してもデータを保持できるデータボリュームを作成しました。 コンテナ間でデータボリュームを共有しましたが、データの破損を防ぐためにファイルロックを処理するようにアプリケーションを設計する必要があることに注意してください。 最後に、共有ボリュームを読み取り専用モードでマウントする方法を示しました。 コンテナとホストシステム間でデータを共有する方法について知りたい場合は、https://www.digitalocean.com/community/tutorials/how-to-share-data-between-the-docker-container-and-をご覧ください。 the-host [Dockerコンテナとホスト間でデータを共有する方法]。