Dockerにおけるデータ管理の概要
コンテナで扱う動的なデータは、起動中のコンテナの読み書き可能なレイヤー内に置くこともできるが、いくつかのデメリットがある。例えばコンテナが削除された時点で、コンテナ内のデータも消える。コンテナ間で共有することもできない。書き込みのパフォーマンスもホスト上のデータに書き込むのに比べて、書き込みのパフォーマンスが良くない。
volumeを使用したデータ管理
Linuxの場合
/var/lib/docker/volumes配下に作成される。これが自動的にコンテナにマウントされる。作成されたvolumeは名前を付けて管理することができ、複数のコンテナにマウントすることができる。また、複数のコンテナで共通のファイルを読み書きすることができる。volumeはコンテナが削除されても消えず、明示的に削除されるまで消えない。ファイルの移動は推奨されていないため、コンテナ上でファイルを管理するために用意されている機能。
基本的なvolumeの管理コマンド
-# 環境の差異を避けるためdocker-machineコマンドで仮想マシンを起動してその中で作業をする。
% docker-machine create vol-test
-# 作成したホストにssh接続
% docker-machine ssh vol-test
-# docker volume create 新しいvolume名
$ docker volume create my-vol
-# 存在するvolumeの確認
$ docker volume ls
-# Dockerで管理されるホストマシン上の領域に「my-vol」と言うvolumeが作成される。
DRIVER VOLUME NAME
local my-vol
volumeの詳細確認
-# docker valume inspect volume名
$ docker valume inspect my-vol
volumeの削除
-# docker valume rm volume名
$ docker valume rm my-vol
コンテナにvolumeをマウントする。
-vによるマウント
-# docker run -itd --name コンテナ名 -v volume名:マウントポイント コンテナ元
$ docker run -itd —-name mount-c1 -v vol1:/app nginx:latest
-vの引数にコロン区切りでvolume名とコンテナ上にマウントするパスを指定する。今回は「vol1」 というvolume名で、存在しないので新規のvolumeとして作成される。コンテナ内のマウントポイントは「/app」になる。docker volume lsコマンドで「vol1」が作成されているのがわかる。docker inspectコマンドでコンテナの詳細を確認することで、マウントされているvolumeを確認することができる。
コンテナに接続してvolumeの情報を確認する。
$ docker exec -it mount-c1 /bin/bash
# df
Filesystem 1K-blocks Used Available Use% Mounted on
overlay 18714000 189496 17535376 2% /
tmpfs 65536 0 65536 0% /dev
tmpfs 504516 0 504516 0% /sys/fs/cgroup
shm 65536 0 65536 0% /dev/shm
/dev/sda1 18714000 189496 17535376 2% /app
tmpfs 504516 0 504516 0% /proc/asound
tmpfs 504516 0 504516 0% /proc/acpi
tmpfs 504516 0 504516 0% /proc/scsi
tmpfs 504516 0 504516 0% /sys/firmware
「/app」がマウントされているのがわかる。
/appにファイルをupしてみる
-# appに移動
# cd app
-# 「hogehoge」ファイルの作成
# touch hogehoge
# ls
hogehoge
別のコンテナに「mount-c1」をマウントし同じファイルがあるか確認する。
--mountでマウントする。
-# docker run -itd --name コンテナ名 --mount source=volume名,target=マウントポイント コンテナ元
$ docker run -itd —-name mount-c2 —-mount source=vol1,target=/app nginx:latest
--mountでマウントする場合、マウント元のvolumeをsourceの引数に指定し、マウント先をtargetの引数に指定する。動作は-vと同様。
$ docker exec -it mount-c2 /bin/bash
# ls -l /app
Hogehogeファイルが確認できる。このように同じvolumeを複数のコンテナにマウントすることで、ファイルを共有することができる。ただし、この方法で共有できるのは、同じホスト内で実行しているコンテナのみで、異なるホスト間で共有することができない。
コンテナ起動時のvolumeのマウント
-# docker run -itd --name コンテナ名 --mount source=valume名,destination=マウントポイント コンテナ元
$ docker run -itd —-name mount-c3 —-mount source=copy-vol,destination=/etc/nginx nginx
「copy-vol」というvolumeが作成され、「/etc/nginx」にマウントされた。volume内に「etc/nginx」の設定ファイルやディレクトリがcopyされている。
$ docker volume inspect copy-vol
Volumeの詳細を見るとマウントポイントが確認できる。新規にvolumeが作成されマウントされた場合は、既に存在していたファイル類がコピーされ、volume上に存在するようになる。マウントのもう一つのパターンとして、既に存在するvolumeをマウントする場合がある。コンテナ上のファイルがコピーされることはない。あくまで既存のvolumeが指定したマウントポイントにマウントされ、コンテナ上に存在していた既存のファイル類はマウントvolumeによって隠れて見えない状態になる。
読み取り専用でvolumeをマウントする方法
コンテナごとに読み書き可能にするか、読み取り専用にするかを設定することができる。マウントフラグを使用して読み取り専用としてマウントする方法。
-# docker run -itd --name コンテナ名 --mount source=volume名,destination=マウントポイント,readonly コンテナ元
$ docker run -itd —-name mount-c4 -—mount source=copy-vol,destination=/etc/nginx,readonly nginx
「,」カンマ区切りで「readonly」と指定する。
$ docker inspect mount-c4
"Mounts”の"RW": falseになっていることが確認できる。
-vでの読み取り専用でvolumeをマウントする方法
-# docker run -itd --name コンテナ名 -v volume名:マウントポイント:ro コンテナ元
$ docker run -itd —-name mount-c5 -v copy-vol:/etc/nginx:ro nginx
volume名:マウントポイント:roとすることで、読み取り専用に設定することができる。