Zenn
🐳

Docker のデータ管理

に公開
1

Docker のデータ管理

Docker のデータ管理について、主に公式ドキュメントから引用して日本語化し、
やりたいことから逆引きできるようにしてまとめました

この記事の前提知識 (解説しないこと)

  • コンテナ
  • Docker Compose

データ管理のデフォルト

デフォルトでは、コンテナ内で作成されたファイルは
「書き込み可能なコンテナ レイヤー」に保存されます

「書き込み可能なコンテナ レイヤー」の特徴と気をつけること

  • 書き込まれたデータは、コンテナが破棄されると保持されません
    • つまり、別のプロセスでデータが必要な場合、コンテナからデータを取得するのが困難になる可能性があります。
  • コンテナごとに一意
  • ホストまたは別のコンテナにデータを簡単に抽出することはできません

書き込み可能なコンテナ レイヤーの問題を解決するには

「ストレージをマウント」します

Docker のストレージマウントは 3 種類

次の URL より図を引用しています:
tmpfs マウントの使用 — Docker-docs-ja 20.10 ドキュメント

ストレージマウントは 3 種類

やりたいこと データ管理の種類
・複数の実行中のコンテナー間でデータを共有したいとき
・Dockerホストが
 特定のディレクトリまたはファイル構造を持つことが
 保証されていないとき
・コンテナのデータをローカルではなく、
 リモートホストまたはクラウドプロバイダーに保存したいとき
・あるDockerホストから別のDockerホストに
 データをバックアップ、復元、または移行する必要があるとき
・パフォーマンスが重要なデータ処理
・長期保存のニーズ
Volume mounts
・ホストマシンからコンテナへ構成ファイルを共有したいとき
・Dockerホスト上の開発環境とコンテナー間で
 ソースコードまたはビルド成果物を共有したいとき
・Dockerホストのファイルまたはディレクトリ構造が、
 コンテナーが必要とするバインドマウントと
 一致することが保証されているとき
Bind mounts
次のような理由で
ホストマシン上、またはコンテナ内のいずれかで
データを永続化させたくないとき:
・セキュリティ上の理由
・アプリケーションが
 大量の非永続状態データを書き込む必要がある場合に
 コンテナーのパフォーマンスを保護するため
tmpfs mounts

docker compose down && docker compose up の際の振る舞い

データ管理の種類 docker compose down && docker compose up の際の振る舞い
tmpfs mounts 新しく作成し直されます
Volume mounts Bind mounts docker compose down 前の内容が再度読み込まれます

公式ドキュメントでも次のように言及されています:
docker compose down

Anonymous volumes are not removed by default.
However, as they don’t have a stable name,
they are not automatically mounted by a subsequent up.
For data that needs to persist between updates,
use explicit paths as bind mounts or named volumes.

和訳:

デフォルトでは、匿名ボリュームは削除されません。
ただし、安定した名前がないため、
後続のアップによって自動的にマウントされることはありません。
更新間で保持する必要があるデータについては、
明示的なパスをバインド マウントまたは名前付きボリュームとして使用します。

Compose YAML の記法は 2 種類

次の 2 種類の記法は同様の内容です:

services:
  web:
    image: httpd:latest
    volumes:
      - type: bind
        source: ./location
        target: /container/location
      - type: volume
        source: mydata
        target: /container/location
volumes:
  mydata:
services:
  web:
    image: httpd:latest
    volumes:
      - ./location:/container/location
      - mydata:/container/location
volumes:
  mydata:

Answer: docker-compose: define mount for bind mount and managed mount - Stack Overflow

ただし、ホスト側にディレクトリーやファイルが存在しなかった場合の動作に違いがあるようです:
docker-compose の bind mount を1行で書くな

Volume mounts

概要

  • Docker でデータを永続化するための最良の方法
  • ホストファイルシステム上の、Dockerによって管理される場所にデータボリュームを保持
  • コンテナーが破棄されてもデータにアクセス可能
  • プラグインを使うことでクラウドのストレージを Volumes として読み書きすることも可能
  • Docker Compose で利用する場合、所有者やグループは
    Volumes を関連付けたサービスのイメージのディレクトリーに従うようです:
    Docker Compose mounts named volumes as 'root' exclusively · Issue #3270 · docker/compose · GitHub

良い利用例

  • 複数の実行中のコンテナー間でデータを共有します。
    • 明示的に作成しない場合、
      ボリュームはコンテナに初めてマウントされたときに作成されます。
    • そのコンテナが停止または削除されても、
      ボリュームはまだ存在しています。
    • 複数のコンテナは、読み取り/書き込みまたは読み取り専用のいずれかで、
      同じボリュームを同時にマウントできます。
    • ボリュームは、明示的に削除した場合にのみ削除されます。
  • Dockerホストが
    特定のディレクトリまたはファイル構造を持つことが保証されていない場合。
    • ボリュームは、Dockerホストの構成を
      コンテナーランタイムから切り離すのに役立ちます。
  • コンテナのデータをローカルではなく、
    リモートホストまたはクラウドプロバイダーに保存する場合。
  • あるDockerホストから別のDockerホストにデータを
    バックアップ、復元、または移行する必要がある場合は、
    ボリュームの方が適しています。
    • ボリュームを使用してコンテナを停止してから、
      ボリュームのディレクトリ
      (/ var / lib / docker / volumes / <volume-name>など)を
      バックアップできます。

Compose YAML の例

次の例は、データベースのデータ ディレクトリが
db-data という名前のボリュームとして別のサービスと共有され、
定期的にバックアップできる 2 つのサービスの設定を示しています:
Volumes top-level element | Docker Docs

services:
  backend:
    image: example/database
    volumes:
      - db-data:/etc/data
  backup:
    image: backup-service
    volumes:
      - db-data:/var/lib/backup/data
volumes:
  db-data:

Bind mounts

概要

  • ホストのデータを直接マウントし、コンテナーがリアルタイムに読み書きする方式

  • ホストにない場合は、実行時に作成されます

  • マウントしたディレクトリーやファイルの所有者とグループは
    ホストの ID となっており、権限などで色々面倒になります

    but they rely on the host machine’s filesystem
    having a specific directory structure available.
    If you are developing new Docker applications, consider using named volumes instead.

    In general, you should use volumes where possible.

良い利用例

  • ホストマシンからコンテナへの構成ファイルの共有。
    • これは、Dockerがホストマシンから各コンテナーに
      /etc/resolv.confをマウントすることにより、
      デフォルトでコンテナーにDNS解決を提供する方法です。
  • Dockerホスト上の開発環境とコンテナー間で
    ソースコードまたはビルド成果物を共有する。
    • たとえば、Mavenターゲット/ディレクトリをコンテナにマウントし、
      DockerホストでMavenプロジェクトをビルドするたびに、
      コンテナは再構築されたアーティファクトにアクセスできます。
      • この方法で開発にDockerを使用する場合、
        本番Dockerfileは、バインドマウントに依存するのではなく、
        本番用のアーティファクトをイメージに直接コピーします。
  • Dockerホストのファイルまたはディレクトリ構造が、
    コンテナーが必要とするバインドマウントと一致することが保証されている場合。

Compose YAML の例

Bind mounts | Docker Docs

次の例はホストのファイルやディレクトリーをマウントしています:

services:
  web:
    image: httpd:latest
    volumes:
    - type: bind
      source: ./location
      target: /container/location

次のようにも書けます:

services:
  web:
   image: httpd:latest
   volumes:
     - ./location:/container/location

上記の場合、次のような記法になっています:

<host-path>:<container-path>

後者の記法の場合、
ホスト上にファイルやディレクトリーが存在しないときは
ディレクトリーが作成されることに注意します:
docker-compose の bind mount を1行で書くな

tmpfs mounts

概要

  • ホストのメモリーを使う方式
  • LinuxでDockerを実行している場合のみ利用可能です
  • ホストまたはコンテナの書き込み可能レイヤーに永続化したくない機密ファイルを
    一時的に保存する場合に役立ちます
  • コンテナ間でtmpfsマウントを共有することはできません

良い利用例

  • tmpfsマウントは、ホストマシン上またはコンテナ内のいずれかで
    データを永続化させたくない場合に最適です
    • これは、次のいずれかである可能性があります:
      • セキュリティ上の理由
      • アプリケーションが
        大量の非永続状態データを書き込む必要がある場合の
        コンテナーのパフォーマンスを保護するため

Manage data in Docker

Compose YAML の例

次の例は /var/run や /var/cache をメモリー上にして処理を高速化します:
docker-compose tmpfs not working - Stack Overflow

  ubuntu:
    image: ubuntu
    command: "bash -c 'mount'"
    tmpfs:
      - /var/run
      - /var/cache

Windows では $(pwd -W)

次のようにします:

docker run -v $(pwd -W):/workspace python

参考: Mount current directory as a volume in Docker on Windows 10 - Stack Overflow

With Git Bash it can be either
winpty docker run -it -v "/$(pwd -W):/usr/src/project" gcc:4.9
or
winpty docker run -it -v "/$(cmd //c cd):/usr/src/project" gcc:4.9

Windows でネットワークドライブはマウント出来ません

Docker Windows ドライブマウント関係

名前付き pipe

  • Host と container の通信用
  • 一般的な使用例は、container 内でThird party 製 tool を実行し、名前付き pipe を使用して Docker Engine API に接続すること

Storage | Docker Docs

例: Exciting new things for Docker with Windows Server 1709 | Docker

1

Discussion

ログインするとコメントできます