コンテンツを含む、Dockerコンテナと関連データコンテナをデプロイするにはどうすればよいですか?


18

Dockerを初めて使用することを認めることから始めます。間違った一連の仮定からこの問題に近づいているのかもしれません。その場合はお知らせください。Dockerが展開にどのように役立つかについて多くの議論を見てきましたが、実際にどのように行われるかについての例はありません。

これがうまくいくと思った方法は次のとおりです。

  1. マシンAに永続データを保持するデータコンテナを作成します
  2. データコンテナのボリュームを使用するアプリケーションコンテナを作成します
  3. データコンテナ内のデータを変更する可能性のある作業を行います
  4. アプリケーションコンテナを停止します
  5. データコンテナのコミットとタグ付け
  6. データコンテナを(プライベート)リポジトリにプッシュします
  7. マシンBでステップ6のイメージをプルして実行します
  8. マシンBで中断したところから再開する

ここで重要なステップはステップ5です。これは、現在の状態(ファイルシステムの内容を含む)を保存すると思ったものです。その後、その状態をリポジトリにプッシュし、他の場所からプルすることで、元のコンテナと基本的に同じ新しいコンテナを作成できます。

しかし、そのようには機能しないようです。私が見つけたのは、ステップ5が思ったとおりに動作しないか、ステップ7(イメージのプルと実行)がコンテナを初期状態に「リセット」することです。

これをテストするために、3つのDockerイメージとコンテナーのセットをまとめました。データコンテナー、30秒ごとにデータコンテナー内のファイルにランダムな文字列を書き込むライター、およびechoデータの値を単純に読み取るリーダーコンテナファイルと終了します。

データコンテナ

で作成

docker run \
    --name datatest_data \
    -v /datafolder \
    myrepository:5000/datatest-data:latest

Dockerfile:

FROM ubuntu:trusty

# make the data folder
#
RUN mkdir /datafolder

# write something to the data file
#
RUN echo "no data here!" > /datafolder/data.txt

# expose the data folder
#
VOLUME /datafolder

作家

で作成

docker run \
    --rm \
    --name datatest_write \
    --volumes-from datatest_data \
    myrepository:5000/datatest-write:latest

Dockerfile:

FROM ubuntu:trusty

# Add script
#
ADD run.sh /usr/local/sbin/run.sh
RUN chmod 755 /usr/local/sbin/*.sh

CMD ["/usr/local/sbin/run.sh"]

run.sh

#!/bin/bash

while :
do
    sleep 30s

    NEW_STRING=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)

    echo "$NEW_STRING" >> /datafolder/data.txt

    date >> /datafolder/data.txt

    echo "wrote '$NEW_STRING' to file"
done

このスクリプトは、ランダムな文字列と日付/時刻を/datafolder/data.txtデータコンテナーに書き込みます。

読者

で作成

docker run \
    --rm \
    --name datatest_read \
    --volumes-from datatest_data \
    myrepository:5000/datatest-read:latest

Dockerfile:

FROM ubuntu:trusty

# Add scripts
ADD run.sh /run.sh
RUN chmod 0777 /run.sh

CMD ["/run.sh"]

run.sh:

#!/bin/bash

echo "reading..."

echo "-----"

cat /datafolder/data.txt

echo "-----"

これらのコンテナをビルドして実行すると、それらは正常に実行され、期待どおりに動作します。

開発マシンで停止して開始:

  1. データコンテナを作成する
  2. ライターを実行する
  3. すぐにリーダーを実行してください。「データがありません!」を参照してください。メッセージ
  4. しばらく待ってください
  5. リーダーを実行し、ランダムな文字列を参照してください
  6. 作家を止める
  7. ライターを再起動します
  8. リーダーを実行し、同じランダムな文字列を見る

しかし、コミットとプッシュは私が期待することをしません:

  1. データコンテナを作成する
  2. ライターを実行する
  3. すぐにリーダーを実行してください。「データがありません!」を参照してください。メッセージ
  4. しばらく待ってください
  5. リーダーを実行し、ランダムな文字列を参照してください
  6. 作家を止める
  7. データコンテナにコミットしてタグを付けます docker commit datatest_data myrepository:5000/datatest-data:latest
  8. リポジトリにプッシュする
  9. すべてのコンテナを削除して再作成します

この時点で、データコンテナがコミットされ、リポジトリにプッシュされ、リポジトリ内の同じイメージから再作成されているため、リーダーを実行し、同じランダムな文字列を確認します。ただし、実際に表示されるのは「データがありません!」です。メッセージ。

私がここで間違っている場所を誰かが説明できますか?または、代わりに、Dockerを使用した展開方法の例を教えてください。

回答:


22

Dockerでボリュームがどのように機能するかについての仮定が間違っています。ボリュームがDockerコンテナとDockerイメージにどのように関係するかを説明しようと思います。データボリュームデータボリュームコンテナの違いが明らかになれば幸いです。

まず、いくつかの定義を思い出しましょう

Dockerイメージ

Dockerイメージは、基本的にユニオンファイルシステムとメタデータです。docker exportコマンドを使用してdocker image unionファイルシステムのコンテンツを検査し、コマンドを使用してdocker imageメタデータを検査できますdocker inspect

データ量

ドッカーユーザーガイド

データボリュームは、Union File Systemをバイパスして永続データまたは共有データにいくつかの便利な機能を提供する、1つ以上のコンテナ内の特別に指定されたディレクトリです。

ここで、特定のボリューム(データを含むディレクトリまたはファイルとして)は、それを使用する少なくとも1つのdockerコンテナーが存在する場合にのみ再利用可能であることに注意することが重要です。Dockerイメージにはボリュームがなく、最終的にユニオンファイルシステムのどこにボリュームがマウントされるかを示すメタデータのみがあります。データボリュームはdocker container unionファイルシステムの一部ではありませんが、どこにありますか?下/var/lib/docker/volumesドッカーホスト上で(容器が下に格納されている間/var/lib/docker/containers)。

データボリュームコンテナー

その特別なタイプのコンテナには特別なものはありません。それらは、データボリュームを使用するコンテナを停止しただけで、少なくとも1つのコンテナがそのデータボリュームを使用するという唯一かつ独自の目標を持っています。特定のデータボリュームを使用している最後のコンテナ(実行中または停止中)が削除されるとすぐに、そのボリュームはdocker run --volumes-fromオプションを介して到達不能になることに注意してください

データボリュームコンテナーの操作

データボリュームコンテナーを作成する方法

データボリュームコンテナを作成するために使用されるイメージは、そのようなコンテナが停止したままでも目的を果たすことができるため、重要ではありません。したがってdatatest_data、ボリュームの名前が付けられたデータコンテナを作成するには、/datafolder次のコマンドを実行するだけです。

docker run --name datatest_data --volume /datafolder busybox true

これbaseはイメージ名(便利な短い名前)でありtrue、dockerデーモンがコマンドの欠落について不平を言うのを避けるために提供するコマンドです。とにかく、コマンドのオプションを使用datatest_dataしてそのボリュームに到達できるようにするという唯一の目的で名前が付けられたコンテナを停止した後。--volumes-fromdocker run

データボリュームコンテナーから読み取る方法

データボリュームの読み取りには2つの方法があります。最初の方法はコンテナを使用する方法です。そのデータボリュームにアクセスするためのシェルを既存のコンテナーに配置できない場合は、--volumes-fromそのデータを読み取ることのみを目的としたオプションを使用して、新しいコンテナーを実行できます。

例えば:

docker run --rm --volumes-from datatest_data busybox cat /datafolder/data.txt

もう1つの方法は、/var/lib/docker/volumesフォルダからボリュームをコピーすることです。ボリュームを使用してコンテナの1つのメタデータを調べることにより、そのフォルダ内のボリュームの名前を見つけることができます。詳細については、この回答を参照してください。

ボリュームの操作(Docker 1.9.0以降)

ボリュームを作成する方法(Docker 1.9.0以降)

Docker 1.9.0では、docker volumeボリュームを作成できる新しいコマンドが導入されました。

docker volume create --name hello

ボリュームから読み取る方法(Docker 1.9.0以降)

あなたが名前のボリュームを作成しましょうhelloとするdocker volume create --name helloあなたが持つコンテナにそれをマウントすることができ、-vオプション:

docker run -v hello:/data busybox ls /data

コンテナのコミットとプッシュについて

データボリュームはコンテナー(ユニオンファイルシステム)の一部ではないため、コンテナーをコミットして新しいdockerイメージを作成しても、データボリュームにあるデータは保持されないことが明らかです。

データボリュームのバックアップを作成する

Dockerユーザーガイドには、データボリュームのバックアップの作成に関する素晴らしい記事があります


ボリュームに関する良い記事:http ://container42.com/2014/11/03/docker-indepth-volumes/


「データボリュームコンテナの作成に使用されるイメージは重要ではない」と思われます。真:ちょうどあなたの「実行『与える「スクラッチ」画像をしてみてください』:実行可能ファイルが見つかりません」
tcurdt

このエラーにもかかわらず、あなたのコンテナは、ボリューム・ホルダーとしての役割果たして作成されます
Thomasleveil

1
うーん-そのための問題を開く価値があるかもしれません。
tcurdt 14年

いいえ、スクラッチイメージは/bin/trueバイナリ(またはその他)を持つことができない空のイメージであるため、この動作が予想されます
Thomasleveil 14年

1
たったひとつ。「特定のデータボリュームを使用している最後のコンテナ(実行中または停止中)が削除されるとすぐに、Dockerはそのデータボリュームを/ var / lib / docker / volumesから破棄します」と言いましたが、実際はそうではありません:docs.docker.com/userguide/dockervolumes(コンテナー自体が削除されてもデータボリュームは保持されます。docker rm -vボリュームも削除するには、最後のコンテナーに対してコマンドを指定する必要があります)
-juanra

1

ドッカーデータコンテナーを使用してコードを展開することもできます。

それが良い習慣かどうかはわかりませんが、私はそのようにします:

FROM ubuntu:trusty

# make the data folder
#
RUN mkdir /data-image

# in my case, I have a 
# ADD dest.tar /data-image/
#
# but to follow your example :
# write something to the data file
RUN echo "no data here!" > /data-image/data.txt

# expose the data folder 
#
VOLUME /datafolder

ENTRYPOINT cp -r /data-image/* /datafolder/

これで、イメージをプッシュし、volumes-fromなどを使用できます...


これは私が探しているものですが、受け入れられた答えはこれができないことを明示的に述べています。今すぐ試してみます。
アンドホ

1
一見すると、受け入れられた答えはボリューム(またはその中のデータ)はコミットされないと言いますが、DockerfileでCOPYまたはADDを使用してコンテナーにデータを追加し、使用VOLUMEしてボリュームを作成できます。
アンドホ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.