■ はじめに
Dockerコンテナの破棄・再作成が簡単にできるが、 そのままだとデータも消えてしまう。 そこで、Docker に関する データの永続性を保つ仕組み (データの永続化) について、纏める
目次
【1】Docker のデータ永続化 1)Docker の データ永続化に関する考え方 2)データ永続化する目的 3)データ永続化についての考慮点 【2】記憶領域のマウント種類 1)ボリュームマウント 2)バインドマウント 3)ボリュームマウントとバインドマウントの違い 4)どっちがいいの? 【3】データ永続化する方法 1)Data Volume 2)Data Volumeコンテナ 【4】補足:用語整理 1)ボリューム 2)マウント
【1】Docker のデータ永続化
1)Docker の データ永続化に関する考え方
* コンテナは使い捨て => 使用後は、破棄 => 再スタート時は、新しく作り直す
2)データ永続化する目的
* 一方、ログやデータベースなど保持しておきたい時もある => データ永続化する必要がある
3)データ永続化についての考慮点
[1] 大事なデータの管理はコンテナを使わない
* DBなどの保存される大事なデータの管理はコンテナを使わず AWSのRDSや普通のVMを使う
[2] 外部ストレージ上に直接置く
* コンテナとして動くOSが、 NFSやSambaなどの外部ストレージ上にデータを直接置く
[3] Dockerの永続化手法を使う
* 今回のテーマ => 「【2】記憶領域のマウント種類」以降を参照。
【2】記憶領域のマウント種類
* Dockerに記憶領域をマウントする種類は以下の通り。 ~~~~~~~~~~ 1)ボリュームマウント 2)バインドマウント ~~~~~~~~~~
1)ボリュームマウント
* Docker Engineが管理している領域内にボリュームを作成し ディスクとしてコンテナにマウントする
コマンド例 : ボリュームマウント
# Step1: マウントするボリュームを作成 # => docker volume create <Volume Name> docker volume create apache-demo-volume # Step2: runコマンド(-vオプション)で Apacheコンテナを起動 # -v <ボリューム名>:<コンテナ領域パス>(2行目) docker container run --name apache-demo-v -d -p 8081:80 \ -v apache-demo-volume:/usr/local/apache2/htdocs \ httpd # Step3: ボリュームの詳細表示 # => docker volume inspect <Volume Name> docker volume inspect apache-demo-volume ~~~~ [ { "CreatedAt": "2022-05-17T16:48:20+09:00", "Driver": "local", "Labels": {}, "Mountpoint": "/var/lib/docker/volumes/apache-demo-volume/_data", "Name": "apache-demo-volume", "Options": {}, "Scope": "local" } ] ~~~~ # docker container inspect <Container Name> docker container inspect apache-demo-v ~~~~ ・・・めちゃくちゃ長い・・・ "Mounts": [ { "Type": "volume", "Name": "apache-demo-volume", "Source": "/var/lib/docker/volumes/apache-demo-volume/_data", "Destination": "/usr/local/apache2/htdocs", "Driver": "local", "Mode": "z", "RW": true, "Propagation": "" } ], ~~~~ # 後片付け docker container stop apache-demo-v docker container rm apache-demo-v docker volume rm apache-demo-volume
2)バインドマウント
* ホストOSに予めディレクトリを作成し、それをマウントする
コマンド例1
# Step1: フォルダを作る mkdir -p /home/user/for_apache # Step2: runコマンド(-vオプション)で Apacheコンテナを起動 # -v <ホスト側の記録領域パス>:<コンテナ領域パス>(2行目) docker container run --name apache-demo -d -p 8081:80 \ -v /home/user/for_apache:/usr/local/apache2/htdocs \ httpd # Step3: ブラウザでindex.html を確認 (「Index of /」の表示を確認) # => http://localhost:8081/ # Step4: マウントしたフォルダにindex.htmlを置いて、置き換える cd /home/user/for_apache echo '<html><body>Hello, Docker!!</body><html>' > index.html # Step5: ブラウザで再度 index.html を確認 (「Hello, Docker!!」の表示を確認) # => http://localhost:8081/ # 後片付け docker container stop apache-demo docker container rm apache-demo
コマンド例2
docker run --rm --network=host \ --mount type=bind,source=./dbt_hello_world,target=/usr/app \ --mount type=bind,source=./dbt_hello_world/profiles.yml,target=/root/.dbt/ \ ghcr.io/dbt-labs/dbt-postgres:1.8.2 \ debug --profiles-dir="/usr/app/"
3)ボリュームマウントとバインドマウントの違い
https://docs.docker.jp/storage/bind-mounts.html#id3
https://matsuand.github.io/docs.docker.jp.onthefly/storage/bind-mounts/#differences-between--v-and---mount-behavior
ボリュームマウント (-v, --volume)
* マウントするファイルやディレクトリが ホスト上に存在していない場合、 そのマウントエンドポイントを生成する。 その場合には常にディレクトリとして生成される
バインドマウント (--mount)
* マウントするファイルやディレクトリが ホスト上に存在していない場合、 そのファイルやディレクトリを自動的に生成されず、エラーになる
4)どっちがいいの?
* バインドマウント(ホストOSに永続データを保存すること)は非推奨
理由
[1] Dockerコンテナ側とホスト側ディレクトリでの権限の違いにより 意図しない動作をする可能性がある点 [2] ホスト側ディレクトリと繋ぐことにより、 ホストOS側の環境に依存する部分ができる(できる可能性がある) => コンテナをそのまま他のDockerにもって動かす際に足枷になる
【3】データ永続化する方法
* Dockerにデータの永続化する方法は、以下の通り。 ~~~~~ 1)Data Volume 2)Data Volume Container ~~~~~
1)Data Volume
* データを保存するボリューム(データ領域)のこと
コマンド例
# a) 新しいボリュームを作成 # docker volume create --name=<Volume Name> docker volume create --name=hello_data_volume # b) コンテナの作成 # a)で作成したボリュームを指定 # docker container run -v <Volume Name>:<Path> docker container run -it -v hello_data_volume:tmp ubuntu /bin/bash
利点
* データ保存場所の物理的な位置を意識する必要がなくなる => ボリュームの管理場所を、Docker engine で管理しているため => 一方、ディレクトリ構造は、Dockerホストの構成によって 異なる可能性がある(/home配下だったり、/var配下だったり)
2)Data Volume Container
* データ専用のコンテナのこと
コマンド例
## a) 新しいボリュームを作成 # docker volume create --name=<Volume Name> docker volume create --name=hello2_data_volume # b) データボリュームコンテナの作成 # a)で作成したボリュームを指定 # docker container run --name=<Container Name> -v <Volume Name>:<Path> docker container run --name=data_container -v hello_data_volume:tmp ubuntu # c) コンテナ作成 # docker container run --volume-from <Data Volume Container Name> docker container run --volume-from data_container -it ubuntu /bin/bash
【4】補足:用語整理
1)ボリューム
* 記憶媒体であるストレージの1領域を区切ったもの
2)マウント(mount)
* 対象に接続して、OSやソフトウェアの支配下に置くこと cf. mount = 取り付ける
参考文献
https://christina04.hatenablog.com/entry/2016/05/04/134323
https://qiita.com/lciel/items/e21a4ede3bac7fb3ec5a
関連記事
Docker ~ 基礎知識編 ~
https://dk521123.hatenablog.com/entry/2020/04/24/160044
Docker ~ Windows / 環境構築編 ~
https://dk521123.hatenablog.com/entry/2017/09/23/235818
Docker ~ Linux / 環境構築編 ~
https://dk521123.hatenablog.com/entry/2018/04/10/234030
Docker ~ ファイルをコンテナにコピー ~
https://dk521123.hatenablog.com/entry/2022/04/27/000000
Docker によるトラブルシューティング
https://dk521123.hatenablog.com/entry/2017/09/24/162257