あなたの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 ...
(受け入れられた答えを見てください)
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は自動的に名前付きボリュームを作成します。
docker volume ls
を通してリストされるdocker volume inspect volume_name
を通して識別される--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
プロダクションに最適な方法は、data onlyコンテナを使用することです。
データ専用コンテナはベアボーンイメージで実行され、実際にはデータボリュームを公開すること以外何もしません。
その後、他のコンテナを実行してデータコンテナボリュームにアクセスできます。
docker run --volumes-from data-container some-other-container command-to-execute
このブログ記事 には、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
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による記事 です。
Dockerリリースv1.0 では、ホストマシン上のファイルまたはディレクトリのマウントをバインドするには、次のコマンドを実行します。
$ docker run -v /Host:/container ...
上記のボリュームは、Dockerを実行しているホスト上の永続ストレージとして使用できます。
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 1.9の時点で、選択した回答の更新5から明らかでない場合は、特定のコンテナーに関連付けられていなくても存在できるボリュームを作成できるため、「データ専用コンテナー」パターンは時代遅れになります。
を参照してください。データ専用コンテナはdocker 1.9.0で廃止されましたか。 #17798。
Dockerのメンテナは、データのみのコンテナパターンはちょっとしたデザインの匂いであることに気付き、ボリュームを関連するコンテナなしでも存在できる独立したエンティティにすることにしたと思います。
これはまだDocker これには何らかの作業が必要です の一部ですが、 VOLUME命令 を使用してDockerfileにボリュームを配置すると、他のコンテナーからボリュームをコピーする必要がなくなります。 。
これにより、コンテナの相互依存性が少なくなり、あるコンテナの削除が他のコンテナに影響を与えることを心配する必要がなくなります。
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:
@tommasopの答えは適切であり、データのみのコンテナーを使用するメカニズムのいくつかを説明しています。しかし、最初にデータコンテナはホストにボリュームをバインドするだけで馬鹿げていると思っていた人(他のいくつかの回答で示唆されているように)が、実際にはデータのみのコンテナはかなりきちんとしたものだと気づいた人は、このトピックに関するブログ投稿:なぜDockerデータコンテナー(ボリューム!)が優れているのか
参照: my answer 質問への「 Docker共有ボリュームのアクセス許可を管理する(最良の)方法は何ですか? を回避するためのデータコンテナーの使用例許可やホストとのuid/gidマッピングなどの問題。
OPの元々の懸念の1つに対処するには、データコンテナを削除してはいけないということです。データコンテナが削除された場合でも、コンテナがそのボリューム、つまり--volumes-from
を介してボリュームをマウントしたコンテナへの参照を持っている限り、データ自体は失われません。したがって、関連するすべてのコンテナが停止および削除されない限り(これは偶発的なrm -fr /
と同等と見なすことができます)、データは安全です。そのボリュームへの参照を持つコンテナを--volumes-from
することで、いつでもデータコンテナを再作成できます。
いつものように、バックアップを作成してください!
更新:Dockerには、コンテナーとは無関係に管理できるボリュームが追加され、管理がさらに容易になりました。
ボリュームを移動したい場合は、Flockerも確認してください。
READMEから:
FlockerはデータボリュームマネージャとマルチホストDockerクラスタ管理ツールです。これを使用すると、Linux上のZFSの機能を活用することで、ステートレスアプリケーションに使用するのと同じツールを使用してデータを制御できます。
つまり、データベース、キュー、Key-ValueストアをDockerで実行して、他のアプリケーションと同じくらい簡単に移動できるということです。
ニーズに応じて、永続データの管理にはいくつかのレベルがあります。
-v Host-path:container-path
を使用します。--volumes-from
を使用してそのデータをアプリケーションコンテナにマウントします。シナリオによって異なります(これは実稼働環境にはあまり適していません)が、ここに1つの方法があります。
この要点は、データの永続化のためにホスト上のディレクトリを使用することです。
私は最近、可能性のあるソリューションとそのテクニックを実証するアプリケーションについて書きました。私はそれが開発の間そして生産の中でかなり効率的であると思います。それが助けになるか、いくつかのアイデアを刺激することを願っています。
レポ: https://github.com/LevInteractive/docker-nodejs-example
記事: http://lev-interactive.com/2015/03/30/docker-load-balanced-mongodb-persistence/
PostgreSQL用のデータを永続化するために、ホスト上の事前定義されたディレクトリを使用しています。また、この方法で既存のPostgreSQLインストールをDockerコンテナに簡単に移行することが可能です: https://crondev.com/persistent-postgresql-inside-docker/
私の解決策は、新しい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コンテナー管理およびスケジューリングツールであるKubernetesのPersistent Volume Claim(PVC)を使用します。
この目的のためにKubernetesを使用する利点は以下のとおりです。