Dockerで永続ストレージ(データベースなど)を処理する方法


993

Dockerコンテナーの永続ストレージはどのように扱われますか?

私は現在このアプローチを使用しています:PostgreSQL用などにイメージをビルドし、次にコンテナーを

docker run --volumes-from c0dbc34fd631 -d app_name/postgres

私見、これには欠点があります。コンテナ「c0dbc34fd631」を(偶然に)削除してはいけません。

別のアイデアは、ホストボリューム「-v」をコンテナーにマウントすることですが、コンテナー内のユーザーIDは必ずしもホストからのユーザーIDと一致せず、権限がめちゃくちゃになる可能性があります。

注:代わりに--volumes-from 'cryptic_id'を使用することもできます--volumes-from my-data-containermy-data-containerは、データのみのコンテナーに割り当てた名前ですdocker run --name my-data-container ...(たとえば、承認された回答を参照してください)。


申し訳ありませんが、私はそれを間違って言いました、私は言うつもりでした:そのイメージからのすべての私の将来のインスタンスはそのコンテナに依存しています。そのコンテナを誤って削除してしまうと困ります。
juwalter 2013

@AntonStrogonoffは-うん、エラーをフレージング-私が言うことを意味:その後、参照、「永続的な」ストレージもなくなってしまうので、私は今まで、その(おそらく)古いコンテナを削除しません、私は確認する必要があります
juwalter

それはあるはずです--name。あなたが持っています-name
シャンメル・リー

回答:


986

Docker 1.9.0以降

ボリュームAPIを使用する

docker volume create --name hello
docker run -d -v hello:/container/path/for/volume container_image my_command

つまり、データのみのコンテナーパターンは、新しいボリュームのために破棄する必要があります。

実際、ボリュームAPIは、データコンテナーのパターンを実現するためのより良い方法にすぎません。

-v volume_name:/container/fs/pathDockerでコンテナを作成すると、次のことができる名前付きボリュームが自動的に作成されます。

  1. を通じてリストされる docker volume ls
  2. を通じて識別される docker volume inspect volume_name
  3. 通常のディレクトリとしてバックアップ
  4. --volumes-from接続を介して以前と同様にバックアップ

新しいボリュームAPIには、ダングリングボリュームを特定できる便利なコマンドが追加されています。

docker volume ls -f dangling=true

そして、その名前で削除します。

docker volume rm <volume name>

コメントで@mpugachが下線を引いているように、素敵なワンライナーでぶら下がりボリュームをすべて取り除くことができます。

docker volume rm $(docker volume ls -f dangling=true -q)
# Or using 1.13.x
docker volume prune

Docker 1.8.x以下

本番環境に最適と思われるアプローチは、データのみのコンテナを使用することです。

データのみのコンテナーはベアボーンイメージで実行され、実際にはデータボリュームを公開する以外は何もしません。

次に、他のコンテナーを実行して、データコンテナーボリュームにアクセスできます。

docker run --volumes-from data-container some-other-container command-to-execute
  • ここでは、さまざまなコンテナを配置する方法の良い写真を得ることができます。
  • ここでは、ボリュームがどのように機能するかについての良い洞察があります。

、このブログの記事は、いわゆるの良好な説明がありボリュームパターンとして容器を有するの主点明確データのみコンテナは

Dockerドキュメントに、ボリュームのパターンとしてコンテナの明確な説明が追加されました

以下は、Docker 1.8.x以下のバックアップ/復元手順です。

バックアップ:

sudo docker run --rm --volumes-from DATA -v $(pwd):/backup busybox tar cvf /backup/backup.tar /data
  • --rm:コンテナが存在するときに削除します
  • --volumes-from DATA:DATAコンテナが共有するボリュームに接続します
  • -v $(pwd):/ backup:コンテナーに現在のディレクトリをバインドマウントします。tarファイルを書き込む
  • busybox:小さくシンプルな画像-迅速なメンテナンスに適しています
  • tar cvf /backup/backup.tar / data:/ dataディレクトリ内のすべてのファイルの非圧縮tarファイルを作成します

戻す:

# Create a new data container
$ sudo docker run -v /data -name DATA2 busybox true
# untar the backup files into the new container᾿s data volume
$ sudo docker run --rm --volumes-from DATA2 -v $(pwd):/backup busybox tar xvf /backup/backup.tar
data/
data/sven.txt
# Compare to the original container
$ sudo docker run --rm --volumes-from DATA -v `pwd`:/backup busybox ls /data
sven.txt

コンテナとデータコンテナに同じ画像を使用するのが良い理由を説明する、優れたブライアンゴフのすばらしい記事を次に示します。


8
それは、異なるニーズのための異なるツールです。--volumes-fromディスク領域--linkを共有させて、サービスを共有させます。
tommasop 2014年

3
この種のもののために特別に意図された作品に別のプロジェクトがあります。多分、それをこのリファレンスに追加して、視聴の参考にしますか?github.com/ClusterHQ/flocker
Andre

9
データコンテナーには意味がなく、非常に悪い考えです!コンテナーは、プロセスがその中で実行されている場合にのみ意味を持ち、それ以外の場合は、ホストファイルシステムの一部にすぎません。-vを使用してボリュームをマウントするだけで、これが唯一の最良のオプションです。使用するファイルシステムと物理ディスクを制御できます。
Boynux

11
はい、Docker 1.9の時点で、ボリュームAPI(docker volume create --name mydata)を使用して名前付きボリュームを作成することは、データボリュームコンテナーよりも優先されます。Dockerの人々は、データボリュームコンテナは「推奨パターンとは見なされなくなった」、「名前付きボリュームはほとんどの(すべてではないにしても)データのみのボリュームを置き換えることができるはずである」、「使用する理由がわからない」と示唆していますデータのみのコンテナ。」
Quinn Comendant 2016

8
@コーディング、私はあなたが悲しいのは悲しいです。回答を3年の遅れで判断しているためと、回答がすべての歴史において実質的に正しいためです。アドバイスがありましたら、私が答えを統合して人々が悲しくないようにできるようにコメントしてください
tommasop

75

ドッカーリリースv1.0を、指定されたコマンドによって行うことができ、ホストマシン上のファイルまたはディレクトリのマウント結合:

$ docker run -v /host:/container ...

上記のボリュームは、Dockerを実行しているホストの永続ストレージとして使用できます。


3
これは、現時点で投票数が多いボリュームコンテナアプローチよりもはるかに複雑ではないため、推奨される回答になるはずです
insitusec

2
このボリュームマウントコマンドを使用するときにhost-uid:container-uidおよびhost-gid:container-gidマッピングを指定するフラグがあればいいのにと思います。
ラピオン2017年

35

Docker Compose 1.6以降、Docker Composeのデータボリュームのサポートが改善されました。次の構成ファイルは、親コンテナーの再起動(または削除)の間も存続するデータイメージを作成します。

これがブログ発表です:Compose 1.6:ネットワークとボリュームを定義するための新しいComposeファイル

次に、作成ファイルの例を示します。

version: "2"

services:
  db:
    restart: on-failure:10
    image: postgres:9.4
    volumes:
      - "db-data:/var/lib/postgresql/data"
  web:
    restart: on-failure:10
    build: .
    command: gunicorn mypythonapp.wsgi:application -b :8000 --reload
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    links:
      - db

volumes:
  db-data:

私が理解できる限り:これにより、db_data再起動間で持続するデータボリュームコンテナー()が作成されます。

実行した場合:docker volume lsボリュームがリストされているはずです。

local               mypthonapp_db-data
...

データボリュームに関する詳細を取得できます。

docker volume inspect mypthonapp_db-data
[
  {
    "Name": "mypthonapp_db-data",
    "Driver": "local",
    "Mountpoint": "/mnt/sda1/var/lib/docker/volumes/mypthonapp_db-data/_data"
  }
]

いくつかのテスト:

# Start the containers
docker-compose up -d

# .. input some data into the database
docker-compose run --rm web python manage.py migrate
docker-compose run --rm web python manage.py createsuperuser
...

# Stop and remove the containers:
docker-compose stop
docker-compose rm -f

# Start it back up again
docker-compose up -d

# Verify the data is still there
...
(it is)

# Stop and remove with the -v (volumes) tag:

docker-compose stop
docker=compose rm -f -v

# Up again ..
docker-compose up -d

# Check the data is still there:
...
(it is).

ノート:

  • volumesブロックでさまざまなドライバーを指定することもできます。たとえば、db_dataにFlockerドライバーを指定できます。

    volumes:
      db-data:
        driver: flocker
    
  • Docker SwarmとDocker Composeの統合が改善されると(そしてFlockerをDockerエコシステムに統合し始める可能性があります(DockerがFlockerを購入したという噂を聞きました)、このアプローチはますます強力になるはずです。

免責事項:このアプローチは有望であり、私は開発環境でうまく使用しています。これをまだプロダクションで使用するのは不安です。



17

Docker 1.9以降、選択した回答の更新5から明確でない場合は、特定のコンテナーに関連付けられていなくても存在できるボリュームを作成できるため、「データのみのコンテナー」パターンは廃止されます。

docker 1.9.0で廃止されたデータのみのコンテナーを参照してください#17798

Dockerのメンテナーは、データのみのコンテナーパターンが少しデザインの匂いだと気づき、ボリュームを、コンテナーがなくても存在できる別個のエンティティーにすることを決めたと思います。


13

これはまだいくつかの作業を必要とするDockerの一部ですが、VOLUME命令を使用してDockerfileにボリュームを配置する必要がありますですが、別のコンテナーからボリュームをコピーする必要がないように使用必要があります。

これにより、コンテナーの相互依存性が低くなり、コンテナーの削除が別のコンテナーに影響を与えることを心配する必要がなくなります。


裏側の議論は、「データのみ」のコンテナーは最終的にデータボリュームへの最後のリゾート参照になるということです(Dockerは、そのボリュームを参照する最後のコンテナーがで削除されると、データボリュームを破棄しますdocker rm
WineSoaked

2
Dockerからのこの公式ガイドは、そうではないことを示唆しています:docs.docker.com/userguide/dockervolumes/… "データボリュームは、コンテナのライフサイクルとは関係なく、データを永続化するように設計されています。コンテナから参照されなくなった「ガベージコレクション」ボリューム。」
Alex

12

Docker Composeを使用する場合は、名前付きボリュームを接続するだけです。次に例を示します。

version: '2'
services:
  db:
    image: mysql:5.6
    volumes:
      - db_data:/var/lib/mysql:rw
    environment:
      MYSQL_ROOT_PASSWORD: root
volumes:
  db_data:

9

@tommasopの答えは適切で、データのみのコンテナーを使用するメカニズムの一部を説明しています。しかし、他のいくつかの回答で示唆されているように、ボリュームをホストにバインドマウントするだけでデータコンテナーはばかげていると当初は思っていたが、実際はデータのみのコンテナーはかなりきちんとしていることに気付いたので、自分のコンテナーを提案することができます。このトピックに関するブログ投稿:Dockerデータコンテナー(ボリューム!)が優れている理由

参照:質問に対する私の回答 " Docker共有ボリュームの権限を管理する(最良の)方法は何ですか?アクセス許可やホストとのuid / gidマッピングなどの問題を回避するためにデータコンテナーを使用する方法の例については、「

OPの元の懸念の1つに対処するには、データコンテナーを削除してはならないということです。データコンテナーが削除された場合でも、コンテナーがそのボリュームへの参照を持っている限り、データ自体は失われません--volumes-from。したがって、関連するすべてのコンテナが停止されて削除されない限り(これは偶発的なものと見なすことができrm -fr /ます)、データは安全です。--volumes-fromそのボリュームへの参照を持つ任意のコンテナーを実行することにより、いつでもデータコンテナーを再作成できます。

いつものように、しかしバックアップをしてください!

更新:Dockerに、コンテナーとは独立して管理できるボリュームが追加されました。これにより、管理がさらに容易になります。


9

ニーズに応じて、永続データの管理にはいくつかのレベルがあります。

  • ホストに保存する
    • 旗を使う -v host-path:container-pathをコンテナディレクトリデータをホストディレクトリに永続化します。
    • バックアップ/復元は、同じディレクトリにマウントされたバックアップ/復元コンテナー(tutumcloud / dockupなど)を実行することで行われます。
  • データコンテナーを作成し、そのボリュームをアプリケーションコンテナーにマウントする
    • データボリュームをエクスポートするコンテナーを作成します。 --volumes-fromそのデータをアプリケーションコンテナーにマウントためします。
    • 上記のソリューションと同じバックアップ/復元。
  • 外部/サードパーティサービスをサポートするDockerボリュームプラグインを使用する
    • Dockerボリュームプラグインにより、データソースをどこからでも取得できます-NFS、AWS(S3、EFS、およびEBS)
    • プラグイン/サービスに応じて、単一または複数のコンテナーを単一のボリュームに接続できます。
    • サービスによっては、バックアップ/復元が自動化されている場合があります。
    • これを手動で行うのは面倒ですが、一部のオーケストレーションソリューション(Rancherなど)では、簡単に使用できます。
    • コンボイは、これを手動で行うための最も簡単なソリューションです。

8

ボリュームを移動したい場合は、Flockerも確認してください。

READMEから:

Flockerは、データボリュームマネージャーおよびマルチホストDockerクラスター管理ツールです。LinuxでZFSの機能を利用することにより、ステートレスアプリケーションに使用するのと同じツールを使用してデータを制御できます。

つまり、Dockerでデータベース、キュー、Key-Valueストアを実行し、他のアプリケーションと同じように簡単に移動できます。


1
ヨハンありがとう。私はClusterHQで働いており、ZFSベースのストレージだけを超えて移動したことに注意したいと思います。Amazon EBSやGoogle Persistent DiskなどのストレージでFlockerを使用できるようになりました。ストレージオプションの完全なリストは次のとおり
en


5

これはシナリオによって異なりますが(これは実稼働環境にはあまり適していません)、次の1つの方法があります。

MySQL Dockerコンテナの作成

この要点は、データの永続化のためにホスト上のディレクトリを使用することです。


6
ベンに感謝します-このアプローチで私が見ることができる問題の1つ:ファイルシステムリソース(ディレクトリ、ファイル)は、docker / lxcコンテナー(ゲスト)内のuidによって所有されます-おそらくuidと衝突する可能性がありますホスト上で...
juwalter

1
rootで実行されているので、あなたはかなり安全だと思いますが、それはハックであることに同意します-せいぜいローカル開発/一時的な統合テストに適しています。これは間違いなく、私がもっと多くのパターン/思考を生み出してほしい領域です。この質問をチェックアウトするか、docker-dev googleグループに投稿してください
ben schwartz '18

ベン、このソリューションをありがとう!私はそれをハックとは呼びませんが、ボリュームとしてのコンテナよりもはるかに信頼できるようです。データがコンテナーからのみ使用される場合の欠点はありますか?(この場合、UIDは重要ではありません)
johndodo 2014

3

私は最近、可能性のある解決策とその技術を実証するアプリケーションについて書きました。開発中および本番環境ではかなり効率的であることがわかりました。それがいくつかのアイデアに役立つか、またはスパークすることを願っています。

リポジトリ: https : //github.com/LevInteractive/docker-nodejs-example
記事: http : //lev-interactive.com/2015/03/30/docker-load-balanced-mongodb-persistence/



0

私の解決策は、新しい docker cp実行中かどうかに関係なく、コンテナーからデータをコピーして、データベースアプリケーションがコンテナー内でデータベースファイルを作成している場所とまったく同じ場所にホストボリュームを共有できることです。この二重のソリューションは、元のデータベースコンテナーから直接、データのみのコンテナーなしで機能します。

そのため、私のsystemd initスクリプトは、データベースをホスト上のアーカイブにバックアップする仕事をしています。ファイルを書き換えないように、ファイル名にタイムスタンプを付けました。

ExecStartPreで実行しています。

ExecStartPre=-/usr/bin/docker cp lanti-debian-mariadb:/var/lib/mysql /home/core/sql
ExecStartPre=-/bin/bash -c '/usr/bin/tar -zcvf /home/core/sql/sqlbackup_$$(date +%%Y-%%m-%%d_%%H-%%M-%%S)_ExecStartPre.tar.gz /home/core/sql/mysql --remove-files'

そして、ExecStopPostでも同じことをしています。

ExecStopPost=-/usr/bin/docker cp lanti-debian-mariadb:/var/lib/mysql /home/core/sql
ExecStopPost=-/bin/bash -c 'tar -zcvf /home/core/sql/sqlbackup_$$(date +%%Y-%%m-%%d_%%H-%%M-%%S)_ExecStopPost.tar.gz /home/core/sql/mysql --remove-files'

さらに、ホストからフォルダをボリュームとして、データベースが格納されている場所とまったく同じ場所に公開しました。

mariadb:
  build: ./mariadb
  volumes:
    - $HOME/server/mysql/:/var/lib/mysql/:rw

それは私のVMでうまく機能します(私は自分用にLEMPスタックを構築しています):https : //github.com/DJviolin/LEMP

しかし、あなたの人生が実際にそれに依存している場合、それが「防弾」ソリューションであるかどうかはわかりません(たとえば、ミリ秒単位でトランザクションが発生するWebショップ)。

この公式のDockerキーノートビデオから20分20秒で、プレゼンターはデータベースで同じことを行います。

Docker入門

「データベースにはボリュームがあるので、データベースコンテナーが停止しても、データベースが上下してもデータが失われないことを確認できます。」


「...を使う」とはどういう意味ですか?そして「...ミリ秒単位でのトランザクション」
Peter Mortensen、2018

0

Dockerコンテナー管理およびスケジューリングツールであるKubernetesのPersistent Volume Claim(PVC)を使用します。

永続ボリューム

この目的でKubernetesを使用する利点は次のとおりです。

  • NFSやその他のストレージなどの任意のストレージを使用できます。ノードが停止している場合でも、ストレージを使用する必要はありません。
  • さらに、このようなボリュームのデータは、コンテナー自体が破棄された後も保持されるように構成できます。これにより、必要に応じて、別のコンテナーでデータを再利用できます。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.