web-dev-qa-db-ja.com

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

あなたのDockerコンテナのために、人々はどのようにして永続的なストレージを取り扱っていますか?

私は現在この方法を使用しています。 PostgreSQLの場合は、次にコンテナを起動します。

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

私見、それは私が今まで(偶然に)コンテナ "c0dbc34fd631"を削除してはいけないという欠点を持っています。

別の考えはホストボリューム "-v"をコンテナにマウントすることですが、コンテナ内の userid は必ずしもホストからの userid と一致するとは限らず、パーミッションが乱れる可能性があります。

注:--volumes-from 'cryptic_id'の代わりに--volumes-from my-data-containerを使用することもできます。ここでmy-data-containerはデータ専用コンテナに割り当てた名前です。 docker run --name my-data-container ...(受け入れられた答えを見てください)

928
juwalter

Docker 1.9.0以上

volume 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/pathでコンテナーを作成すると、Dockerは自動的に名前付きボリュームを作成します。

  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がコメントで強調しているように、Nice one-linerで、ぶら下がっているすべてのボリュームを取り除くことができます。

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

Docker 1.8.x以下

プロダクションに最適な方法は、data onlyコンテナを使用することです。

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

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

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

このブログ記事 には、dataのみのコンテナを持つことの主なポイントを明確にする、ボリュームパターンとしてのいわゆるcontainerの説明があります

Dockerのドキュメントでは、コンテナの明確な説明がvolume/sパターンになっています。

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

BACKUP:

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:bind現在のディレクトリをコンテナにマウントします。 tarファイルの書き込み先
  • busybox:小さいシンプルな画像 - 迅速なメンテナンスに適しています
  • tar cvf /backup/backup.tar/data:/ dataディレクトリにあるすべてのファイルの非圧縮tarファイルを作成します。

RESTORE:

# 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

これは、コンテナとデータコンテナに同じ画像を使用するのが良い理由を説明する、Nice 優秀なBrian Goffによる記事 です。

947
tommasop

Dockerリリースv1.0 では、ホストマシン上のファイルまたはディレクトリのマウントをバインドするには、次のコマンドを実行します。

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

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

69
amitmula

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の統合を改善するにつれて(そしておそらくFockerをDockerエコシステムに統合し始めると(DockerがFlockerを買ったという噂を聞いたことがあるように))、このアプローチはますます強力になるはずです。

免責事項: このアプローチは有望であり、私は開発環境でうまく使っています。私はまだ本番環境でこれを使うことを心配しているでしょう!

30
toast38coza

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

を参照してください。データ専用コンテナはdocker 1.9.0で廃止されましたか。 #17798

Dockerのメンテナは、データのみのコンテナパターンはちょっとしたデザインの匂いであることに気付き、ボリュームを関連するコンテナなしでも存在できる独立したエンティティにすることにしたと思います。

17
ben_frankly

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

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

13
Tim Dorr

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:
11
Czar Pino

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

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

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

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

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

9
Raman

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

READMEから:

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

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

8
Johann Romefort

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

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

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

MySQL Dockerコンテナを作成する

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

5
ben schwartz

私は最近、可能性のあるソリューションとそのテクニックを実証するアプリケーションについて書きました。私はそれが開発の間そして生産の中でかなり効率的であると思います。それが助けになるか、いくつかのアイデアを刺激することを願っています。

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

3
slth

PostgreSQL用のデータを永続化するために、ホスト上の事前定義されたディレクトリを使用しています。また、この方法で既存のPostgreSQLインストールをDockerコンテナに簡単に移行することが可能です: https://crondev.com/persistent-postgresql-inside-docker/

1
Alen Komljen

私の解決策は、新しいdocker cpを利用することです。これは、実行中であろうとなかろうと関係なく、コンテナからデータをコピーすることができ、データベースアプリケーションがデータベースファイルを作成する場所とまったく同じ場所にHostボリュームを共有します容器。この二重の解決策は、元のデータベースコンテナから直接、データ専用コンテナなしで動作します。

それで私の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

しかし、私はあなたの人生が実際にそれに依存するときそれが「防弾」解決策であるかどうかわからないだけです(例えば、可能な限りミリ秒のトランザクションでウェブショップ)。

この公式Docker基調講演ビデオから20分20秒後に、プレゼンターはデータベースに対して同じことを行います。

Docker入門

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

0
Lanti

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

固定ボリューム

この目的のためにKubernetesを使用する利点は以下のとおりです。

  • NFSや他のストレージなどの任意のストレージを使用できます。ノードが停止している場合でも、ストレージは使用する必要はありません。
  • さらに、そのようなボリューム内のデータは、コンテナー自体が破壊された後でも保持されるように構成できるため、必要に応じて別のコンテナーによって再利用することができます。
0
Santanu Dey