web-dev-qa-db-ja.com

Dockerコンテナーでボリュームまたはマウントを作成することの違いは何ですか?

Dockerは、ローカルマシン上のコンテナーデータをバックアップおよび同期する2つの方法を提供します(つまり、volumeおよびmount)。私が気付いたいくつかのことを除いて、どちらも同じように動作します:

  1. ボリュームは常に/ var/lib/docker/volumesにデータを保持しますが、マウントポイントはどこにでも作成できます。
  2. マウントポイントが割り当てられているコンテナーにボリュームも割り当てられている場合、マウントポイントからのすべてのデータが自動的にボリュームにコピーされますが、その逆は当てはまりません。
  3. Dockerfileでマウントポイントを記述することはできませんが、Dockerfileでボリュームを指定できます。

では、方法論にはいくつかの長所と短所がありますが、最適化に関してはまだ分類や違いがあります。

説明された回答を提供してください。

5
YATIN GUPTA

ボリュームには実際には3つのタイプがあります。

  • ホストボリューム:コンテナーのマウントと呼ばれるもので、より一般的な用語はバインドマウントです。
  • 名前付きボリューム:名前を付ける、Dockerが管理するボリューム。
  • 匿名ボリューム:ソースのないボリューム、Dockerはこれを長い一意のIDを持つローカルボリュームとして作成し、名前付きボリュームとして動作します。

ボリュームにはソースとターゲットがあります。ソースはボリュームのタイプを識別するため、ファイル/ディレクトリへのパス(先頭のスラッシュを含む)はホストボリュームになります。ソースを提供しない場合は、匿名ボリュームを取得します。 Dockerfile内でボリュームを定義する場合、そこでソースを指定することはできません。そのため、デフォルトでdockerは、実行時に別の方法で指示しない限り、匿名ボリュームを作成します。

タイプごとに、長所と短所を次に示します。

  • ホスト:
    • Pro:ホストから基になるファイルに簡単にアクセス
    • 欠点:コンテナーユーザーのuidがホストのgidと一致しない場合、uid/gidのアクセス許可の問題が発生する
    • 欠点:データが初期化されていません
  • 名前:
    • 長所:異なるコンテナー/イメージ間の再利用を簡単に作成できます。他の設定なしで名前のみを指定すると、ローカルドライバーはデフォルトで/ var/lib/docker/volumesにデータを格納します。これは、Dockerの外部からrootのみがアクセスできるようにする必要があります。
    • Pro:空/新規でコンテナが作成されると、コンテンツを画像コンテンツに初期化します。この初期化には、ファイルの所有者とイメージからのアクセス許可が含まれます。これにより、ほとんどのuid/gid問題を解決できます。
    • プロ:バインドマウントやNFSマウントなど、マウントドライバーがローカルドライバーを使用して接続できるすべてのものに接続できます。その他のドライバーを使用すると、さらに多くの場所(クラウドプロバイダーなど)のデータを参照できます。
    • 欠点:コンテンツの管理はコンテナを介して行う必要があります。
  • 匿名:
    • プロ:使用する計画は必要ありません
    • 欠点:ボリュームからそれを作成したコンテナー/イメージへのマッピングがないため、データは通常ここに失われます。これは私の意見ではボリュームを格納するための最悪の方法であり、誰もDockerfile内でボリュームを定義するべきではない理由です。

可能な場合は、名前付きボリュームを使用します。データの初期化とuid/gidの問題のより適切な処理は、ホストボリュームの利便性よりも優先されます。 Dockerの外部でデータに直接アクセスする必要がある場合は、デフォルトのローカルドライバー設定の代わりに、バインドマウントを指す名前付きボリュームを使用してみます。この簡単な例は次のとおりです。

$ docker volume create --driver local \
  --opt type=none \
  --opt device=/home/user/test \
  --opt o=bind \
  test_vol

私のボリュームを定義するために、Dockerfileでこれを実行したくないので、私はdocker-compose.ymlを使用してそこでボリュームを定義します。 swarmモードでデプロイされている場合は、名前付きボリュームを持つNFSサーバーをポイントして、コンテナーが別のホストに移行するときにデータにアクセスできるようにします。それ以外の場合は、docker-composeで簡単に使用できるローカルの名前付きボリュームです。

4
BMitch

Dockerfileのボリュームでは、常にボリュームとして作成する必要のあるパスをイメージで指定できます。これは本質的に、Dockerが使用するユニオンファイルシステムをバイパスします。

このようなイメージのユーザーは、実行時に常にその場所にボリュームを取得します

docker run <imagename>

つまり、-v /my/mount/point:/mount/hereを追加する理由はないので、ユーザーはそれを気にする必要はありません。

バインドマウント(上記の-vの例のように)が必要な場合は、常に存在する必要があります。画像間での移植性はありません。

最適化の効果的な違いは次のとおりです。

  • ボリュームは、多くのr/w操作が必要であり、ユニオンファイルシステム(データベースを考える)にビジネス書き込みがある場合に使用できます。
  • ボリュームは、データボリュームのようなものをマウントするのには無意味です。あなたはそれを行うことができますが、これがユニオンファイルシステムにある理由がないので、あなたは莫大なr/wヒットをとります。
  • ただし、mountsは、既存のディレクトリをコンテナ内の場所にマウントし、そのディレクトリのユニオンファイルシステムをすべて無視するため、これ(上記)を非常に適切に格納します。

これは意味がありますか?

1
Nalaurien