Docker では、ボリュームという機能を使うことで、ホストや外部のストレージをコンテナにマウントできる。
今回は、それらについてざっと使い方を見ていく。
紹介するボリュームの種類は次のとおり。
- bind mount
- volume mount
- tempfs mount
使った環境は以下のとおり。
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 18.04.5 LTS
Release: 18.04
Codename: bionic
$ uname -r
4.15.0-124-generic
$ docker version
Client: Docker Engine - Community
Version: 20.10.1
API version: 1.41
Go version: go1.13.15
Git commit: 831ebea
Built: Tue Dec 15 04:34:59 2020
OS/Arch: linux/amd64
Context: default
Experimental: true
Server: Docker Engine - Community
Engine:
Version: 20.10.1
API version: 1.41 (minimum version 1.12)
Go version: go1.13.15
Git commit: f001486
Built: Tue Dec 15 04:32:40 2020
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.4.3
GitCommit: 269548fa27e0089a8b8278fc4fc781d7f65a939b
runc:
Version: 1.0.0-rc92
GitCommit: ff819c7e9184c13b7c2607fe6c30ae19403a7aff
docker-init:
Version: 0.19.0
GitCommit: de40ad0
もくじ
bind mount
はじめに、従来からある bind mount について。
このやり方では、コンテナの起動時に Docker ホストのディレクトリパスを指定すると、そのディレクトリをコンテナにマウントできる。
たとえば、カレントディレクトリに確認用のテキストファイルを書き込んでおこう。
$ echo "Hello, World" > greet.txt
bind mount するときは、一般的には -v
または --volume
オプションを使うことが多い。
このオプションでは、左辺にマウントしたい Docker ホストのディレクトリを絶対パスで指定する。
そして、コロンを挟んだ右辺にコンテナでマウント先のディレクトリを指定する。
以下では、カレントディレクトリをコンテナの /mnt
にマウントしている。
$ docker container run \
--rm \
-v $(pwd):/mnt \
-it ubuntu:18.04 \
bash
起動したコンテナの中で /mnt
以下を確認すると、先ほど作ったテキストファイルが確認できる。
root@4829d9a83fe9:/
Hello, World
ただし、最近では --mount
というオプションも使える。
このオプションでは、マウントの種類とマウント元、マウント先を指定することで、より明示的な指示になっている。
$ docker container run \
--rm \
--mount type=bind,source=$(pwd),destination=/mnt \
-it ubuntu:18.04 \
bash
結果は先ほどと変わらないので割愛する。
volume mount
続いては volume mount というやり方を扱う。
bind mount ではマウント元のディレクトリを指定していた。
これは直感的な反面、マウントするディレクトリの管理が煩雑になるデメリットがある。
一方、volume mount では、Docker が管理している領域にマウント用のディレクトリが作られて、それを名前で指定できる。
たとえば、以下のようにしてボリュームを作成しておく。
ここでは example-volume
という名前でボリュームを作った。
$ docker volume create example-volume
ボリュームの一覧を見ると、ちゃんとボリュームが作成されている。
ここで着目すべき点として DRIVER
というカラムがある。
先ほど作ったボリュームでは、値が local
になっている。
これは、ドライバを変更することで Docker ホスト以外の場所もボリュームとして管理できることを表している。
公式のドキュメントでも SSHFS や NFS を使ってコンテナ間でストレージを共有する方法が示されている。
$ docker volume ls
DRIVER VOLUME NAME
local example-volume
volume mount するときは、bind mount と同じように -v
オプションが使える。
先ほどは左辺に Docker ホストのディレクトリを指定したのに対し、今回はボリュームの名前を指定する。
$ docker container run \
--rm \
-v example-volume:/mnt \
-it ubuntu:18.04 \
bash
あるいは、--mount
オプションを使っても良い。
こちらの場合は type
に bind
ではなく volume
を指定した上で、source
にボリュームの名前を指定する。
$ docker container run \
--rm \
--mount type=volume,source=example-volume,destination=/mnt \
-it ubuntu:18.04 \
bash
初期状態では、マウントされたディレクトリにファイルが何もない。
そこで、一旦は確認用のファイルを書き込んでコンテナを終了しておこう。
root@10cc21f927a7:/
root@10cc21f927a7:/
root@10cc21f927a7:/
exit
そして、改めて同じボリュームをマウントするコンテナを起動する。
$ docker container run \
--rm \
--mount type=volume,source=example-volume,destination=/mnt \
-it ubuntu:18.04 \
bash
すると、次のように先ほど作成したファイルが存在することが確認できる。
root@324a3d594723:/
greet.txt
root@324a3d594723:/
Hello, World
ちなみに、ボリュームの場所は次のようにして調べることができる。
まずはコンテナの識別子か名前を確認しておく。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
324a3d594723 ubuntu:18.04 "bash" 59 seconds ago Up 58 seconds reverent_golick
そして、docker inspect
を使えばボリュームの情報が確認できる。
これで、"/var/lib/docker/volumes/example-volume/_data"
にマウント元のディレクトリがあることがわかった。
$ docker inspect 324a3d594723 | grep example-volume
"example-volume:/mnt"
"Name": "example-volume",
"Source": "/var/lib/docker/volumes/example-volume/_data",
Docker ホスト側でディレクトリの内容を確認しておこう。
ちゃんとファイルが存在することがわかる。
$ sudo ls /var/lib/docker/volumes/example-volume/_data
greet.txt
$ sudo cat /var/lib/docker/volumes/example-volume/_data/greet.txt
Hello, World
tmpfs mount
続いては、これまでとちょっと毛色が異なる tmpfs mount を紹介する。
tmpfs は Linux のファイルシステムの一種で、主記憶装置を使った (つまりオンメモリの) ファイルシステムになっている。
もちろん、オンメモリということはデータは永続化されず揮発する。
tmpfs mount をするときは、専用のオプションとして --tmpfs
が使える。
指定するのはコンテナのマウント先だけ。
$ docker container run \
--rm \
--tmpfs /mnt \
-it ubuntu:18.04 \
bash
あるいは、--mount
オプションで type
に tmpfs
を指定しても良い。
$ docker container run \
--rm \
--mount type=tmpfs,destination=/mnt \
-it ubuntu:18.04 \
bash
起動したコンテナを確認すると、/mnt
ディレクトリに tmpfs
でマウントされている。
root@71b7c20cbcb8:/
tmpfs 7.9G 0 7.9G 0% /mnt
dd(1) を使ってちょっと大きめのファイルを書くこんでみると、別の場所に比べてスループットが高いことが確認できる。
root@71b7c20cbcb8:/
2000+0 records in
2000+0 records out
2000000000 bytes (2.0 GB, 1.9 GiB) copied, 0.651633 s, 3.1 GB/s
root@71b7c20cbcb8:/
2000+0 records in
2000+0 records out
2000000000 bytes (2.0 GB, 1.9 GiB) copied, 1.93574 s, 1.0 GB/s
いじょう。
参考
docs.docker.com