(O+P)ut

アウトプット



(O+P)ut

エンジニアのアウトプット

【Docker】コンテナ上のディレクトリをホストと共有する

スポンサーリンク

はじめに

コンテナ上で作成したファイルは、コンテナを破棄すれば消えてしまいます。
ホスト上で管理しているファイルをコンテナ側で利用したいケースもあります。

そのような場合はコンテナの外に置いたデータをコンテナにマウントして見せる必要があります。

本記事では、コンテナ外とコンテナ内でディレクトリ(フォルダ)を共有する方法とに設定値であるbindとvolumeの違いについて解説していきます。
f:id:mtiit:20190504091704p:plain
( コンテナ内外でのディレクトリ共有イメージ )

コマンド実行環境
ホスト環境 Red Hat Enterprise Linux Server 7.6

マウント手順

コンテナ作成コマンドであるdocker run のオプションにてマウントを行います。

  -v, --volume list  Bind mount a volume (default [])

ちなみに言葉の整理ですが、ホスト上の任意のディレクトリをコンテナ内にマウントする場合はbind、Dockerが管理するデータ領域をコンテナ上にマウントする場合はvolumeです。

それらの違いはdocker run -v の引数で表現します。

Type:volume

以下のようにubuntuのコンテナを作成するとコンテナ上に/root/sharedockerというディレクトリが作成されています。

docker run -v /root/sharedocker  -ti ubuntu
root@5c74231ce0a2:/# ls -l /root/
total 0
drwxr-xr-x. 2 root root XXXX sharedocker

この/root/sharedockerに対応するホスト上のディレクトリは「docker inspect」にて確認できます。

docker inspect 5c74231ce0a2
...
"Mounts": [
            {
                "Type": "volume",
                "Name": "fcfd2b777eb5de2e09709fc041d55b04efa15f814e76432eb94e2451e54cba4a",
                "Source": "/var/lib/docker/volumes/fcfd2b777eb5de2e09709fc041d55b04efa15f814e76432eb94e2451e54cba4a/_data",
                "Destination": "/root/sharedocker",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
....

以下のSource部分がホスト上の該当ディレクトリとなります。

"Source": "/var/lib/docker/volumes/.../_data",

試しにホスト側にて_dataディレクトリにファイルを格納するとコンテナから確認でき、コンテナ上のsharedockerディレクトリにファイルを格納するとホスト側から確認できます。ファイルの権限を変更してもそれは同様に反映されます。

ちなみにコンテナ上では以下のようにファイルシステムとして確認できます。

root@5c74231ce0a2:/# df
Filesystem     1K-blocks    Used Available Use% Mounted on
overlay         15716368 6105764   9610604  39% /
tmpfs            1811316       0   1811316   0% /dev
tmpfs            1811316       0   1811316   0% /sys/fs/cgroup
/dev/sda1       15716368 6105764   9610604  39% /root/sharedocker
shm                65536       0     65536   0% /dev/shm
tmpfs            1811316       0   1811316   0% /proc/acpi
tmpfs            1811316       0   1811316   0% /proc/scsi
tmpfs            1811316       0   1811316   0% /sys/firmware

Type:bind

先ほどの引数に加えて「:ホスト上のディレクトリ」を追記すると任意のディレクトリをマウントすることが可能です。

# docker run -v /root/sharedocker:/root/sharedocker -it ubuntu

同じく「docker inspect」でマウント情報を確認すると以下のようになっています。
先ほどと異なりSource部分が指定した先になっており、Typeがbindとなっています。

"Mounts": [
            {
                "Type": "bind",
                "Source": "/root/sharedocker",
                "Destination": "/root/sharedocker",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],

これによりコンテナ内外からファイルを共有できるだけでなく、ホスト上のディレクトリを複数のコンテナにて共有することも可能になります。

一点注意ですが、コンテナ上で共有ディレクトリで操作を行おうとすると以下のメッセージが出てエラーになるケースがあります。

XX: cannot open directory '.': Permission denied

そのような場合はSELinuxがオンになっている事が原因の可能性があります。設定値はgetenfoceで確認できます。

# getenforce
Enforcing

「setenforce 0」にて無効化できますが、こちらはセキィリティ設定となるので要否は確認ください。

# setenforce 0
# getenforce
Permissive

終わりに

Dockerにてコンテナ内で作成したデータを永続化したいケースなどで利用する手順です。よってコンテナを削除しても該当のディレクトリは残ったままです。

このあたりはコンテナ特有の面倒な点ですが、覚えておくとより便利にコンテナを利用できると思います。

以上、ご参考になれば幸いです。