【Docker】 Docker ~ 基本編 / Data Volume ~

■ はじめに

 Dockerコンテナの破棄・再作成が簡単にできるが、
そのままだとデータも消えてしまう。

 そこで、Docker に関する
データの永続性を保つ仕組み (データの永続化)
について、纏める

目次

【1】Docker のデータ永続化
 1)Docker の データ永続化に関する考え方
 2)データ永続化する目的
 3)データ永続化についての考慮点
【2】記憶領域のマウント種類
 1)ボリュームマウント
 2)バインドマウント
 3)どっちがいいの?
【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)バインドマウント
~~~~~~~~~~

差異

* docker container run での -vオプションの指定の違い

ボリュームマウント

docker container run -v [ボリューム名]:[コンテナの記憶領域パス] ...

バインドマウント

docker container run -v [ホスト側の記憶領域パス]:[コンテナの記憶領域パス] ...

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に予めディレクトリを作成し、
 それをマウントする

コマンド例 : バインドマウント

# 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

3)どっちがいいの?

* バインドマウント(ホスト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