今日は、Dockerのディスク管理について調べてみようと思います。
参考ページ
中井さんのこのページが参考になります。
* RHEL7におけるDockerのディスクイメージ管理方式
* 第68回 Dockerストレージドライバーの性能比較 (中井悦司)
* Fedora22のDockerでoverlayfsドライバーを利用する手順
このあたりの情報をもとにDockerについて整理していきたいと思います。
Dockerのディスク管理
中井さんのページに記載されている通り、DockerではDevice MapperによるThin-Provisioning機能を使っています。
Device MapperによるThin-Provisioning機能は、RedHatがDockerをubuntu以外のLinuxでも利用できるように、Linuxカーネルで動作できるように追加した機能です。たいへんありがたいですね。
■Dockerのインストール時のディスクイメージ
Dockerをインストールしていないときはこのような状態です。
# df -h
ファイルシス サイズ 使用 残り 使用% マウント位置
/dev/mapper/centos-root 18G 1001M 17G 6% /
devtmpfs 905M 0 905M 0% /dev
tmpfs 914M 0 914M 0% /dev/shm
tmpfs 914M 8.5M 905M 1% /run
tmpfs 914M 0 914M 0% /sys/fs/cgroup
/dev/sda1 497M 162M 336M 33% /boot
# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 20G 0 disk
├─sda1 8:1 0 500M 0 part /boot
└─sda2 8:2 0 19.5G 0 part
├─centos-root 253:0 0 17.5G 0 lvm /
└─centos-swap 253:1 0 2G 0 lvm [SWAP]
sr0 11:0 1 1024M 0 rom
Dockerを起動すると、このようなプロセスが起動していますね。フォーマット処理が行われています。
root 19324 19297 0 09:21 ? 00:00:00 mkfs.ext4 -E nodiscard,lazy_itable_init=0,lazy_journal_init=0 /dev/mapper/docker-253:0-20253-base
ディスクはこのように変わり、ループバックデバイスが出ていることがわかります。
# df -h
ファイルシス サイズ 使用 残り 使用% マウント位置
/dev/mapper/centos-root 18G 1.3G 17G 8% /
devtmpfs 905M 0 905M 0% /dev
tmpfs 914M 0 914M 0% /dev/shm
tmpfs 914M 8.6M 905M 1% /run
tmpfs 914M 0 914M 0% /sys/fs/cgroup
/dev/sda1 497M 162M 336M 33% /boot
[root@DockerDirect ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 20G 0 disk
├─sda1 8:1 0 500M 0 part /boot
└─sda2 8:2 0 19.5G 0 part
├─centos-root 253:0 0 17.5G 0 lvm /
└─centos-swap 253:1 0 2G 0 lvm [SWAP]
sr0 11:0 1 1024M 0 rom
loop0 7:0 0 100G 0 loop
└─docker-253:0-20253-pool 253:2 0 100G 0 dm
└─docker-253:0-20253-base 253:3 0 10G 0 dm
loop1 7:1 0 2G 0 loop
└─docker-253:0-20253-pool 253:2 0 100G 0 dm
└─docker-253:0-20253-base 253:3 0 10G 0 dm
loop0とloop1が追加されているのがわかります。
losetコマンドさらに確認すると、
# losetup
NAME SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE
/dev/loop0 0 0 1 0 /var/lib/docker/devicemapper/devicemapper/data
/dev/loop1 0 0 1 0 /var/lib/docker/devicemapper/devicemapper/metadata
つまり作成されたループバックデバイス/dev/loop0や/dev/loop1は、/var/lib/docker/devicemapper/devicemapperに紐づいていることがわかります。このディレクトリの中身はこのようなファイルです。
# ls -lh /var/lib/docker/devicemapper/devicemapper/
合計 293M
-rw-------. 1 root root 100G 7月 25 08:52 data
-rw-------. 1 root root 2.0G 7月 25 08:54 metadata
# qemu-img info data
image: data
file format: raw
virtual size: 100G (107374182400 bytes)
disk size: 292M
# qemu-img info metadata
image: metadata
file format: raw
virtual size: 2.0G (2147483648 bytes)
disk size: 740K
dataファイルもmetadataファイルもraw(スパース)ファイルになっていますね。
■イメージを取得すると?
まずは、イメージを取得してみましょう
# docker pull centos
latest: Pulling from docker.io/centos
f1b10cd84249: Pull complete
c852f6d61e65: Pull complete
7322fbe74aa5: Already exists
docker.io/centos:latest: The image you are pulling has been verified. Important: image verification is a tech preview feature and should not be relied on to provide security.
Digest: sha256:57554136c655abb33ecb7bb790b1db0279668d3763c3b81f31bc6c4e60e4a1f3
Status: Downloaded newer image for docker.io/centos:latest
# docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
docker.io/centos latest 7322fbe74aa5 5 weeks ago 172.2 MB
Centos:latestをダウンロードしましたが、さぁどうなったでしょうか。
# qemu-img info data
image: data
file format: raw
virtual size: 100G (107374182400 bytes)
disk size: 484M
# qemu-img info metadata
image: metadata
file format: raw
virtual size: 2.0G (2147483648 bytes)
disk size: 904K
292Mから484Mに増えていることが確認できます。
192M増えていますから、ほぼイメージ分(172.2MB)くらいが増えたことになりますね。
取得したイメージも/var/lib/docker/devicemapper/devicemapper/dataファイル内に保存されています。
■コンテナを起動すると?
では、Dockerコンテナを1個起動してみましょう
# docker run -it --name test00 centos /bin/bash
Usage of loopback devices is strongly discouraged for production use. Either use `--storage-opt dm.thinpooldev` or use `--storage-opt dm.no_warn_on_loop_devices=true` to suppress this warning.
[root@46bed6620c0b /]#
# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
46bed6620c0b centos:latest "/bin/bash" About a minute ago Up About a minute test00
Ctrl+PQで抜けれます。exitはしないように。。。
# qemu-img info data
image: data
file format: raw
virtual size: 100G (107374182400 bytes)
disk size: 485M
# qemu-img info metadata
image: metadata
file format: raw
virtual size: 2.0G (2147483648 bytes)
disk size: 956K
dataのディスクサイズは、484Mから485Mとほとんど増えていないことがわかります。
コンテナとして、/bin/bashを動かすのに追加のディスクは必要ないということで、
かなりディスクスペースが節約されているようです。
では、このとき、loopデバイスはどうなっているのでしょうか。
# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
...
loop0 7:0 0 100G 0 loop
└─docker-253:0-20253-pool 253:2 0 100G 0 dm
├─docker-253:0-20253-base 253:3 0 10G 0 dm
└─docker-253:0-20253-46bed6620c0b12328d9cd95110dab4a360c5a31875837184e36ef585b750d8e9 253:4 0 10G 0 dm
loop1 7:1 0 2G 0 loop
└─docker-253:0-20253-pool 253:2 0 100G 0 dm
├─docker-253:0-20253-base 253:3 0 10G 0 dm
└─docker-253:0-20253-46bed6620c0b12328d9cd95110dab4a360c5a31875837184e36ef585b750d8e9 253:4 0 10G 0 dm
docker-253:0-20253-46bed6620c0b12328d9cd95110dab4a360c5a31875837184e36ef585b750d8e9が作成されていますね。
コンテナ内部を見てみるとわかりますが、作成されたディスクがマウントされていることがわかります。
# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/docker-253:0-20253-46bed6620c0b12328d9cd95110dab4a360c5a31875837184e36ef585b750d8e9 9.8G 219M 9.0G 3% /
tmpfs 914M 0 914M 0% /dev
shm 64M 0 64M 0% /dev/shm
tmpfs 914M 0 914M 0% /run/secrets
/dev/mapper/centos-root 18G 1.5G 16G 9% /etc/hosts
tmpfs 914M 0 914M 0% /proc/kcore
tmpfs 914M 0 914M 0% /proc/timer_stats
では、コンテナを終了してみます。
# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
...
loop0 7:0 0 100G 0 loop
└─docker-253:0-20253-pool 253:2 0 100G 0 dm
└─docker-253:0-20253-base 253:3 0 10G 0 dm
loop1 7:1 0 2G 0 loop
└─docker-253:0-20253-pool 253:2 0 100G 0 dm
└─docker-253:0-20253-base 253:3 0 10G 0 dm
ループバックデバイスがなくなりました。
docker rm test00を実行してコンテナを削除しておきます。
ディスクの使用量
ディスクの使用量の調査をするために、もう少しわかりやすい試験をします。
Dockerコンテナを起動し、100M程度のデータを書き込みます。
# docker run -it --name test01 centos /bin/dd if=/dev/zero of=zero.file count=102400 bs=1024
Usage of loopback devices is strongly discouraged for production use. Either use `--storage-opt dm.thinpooldev` or use `--storage-opt dm.no_warn_on_loop_devices=true` to suppress this warning.
102400+0 records in
102400+0 records out
104857600 bytes (105 MB) copied, 0.214952 s, 488 MB/s
そうするとディスクはこのようになります。
# losetup
NAME SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE
/dev/loop0 0 0 1 0 /var/lib/docker/devicemapper/devicemapper/data
/dev/loop1 0 0 1 0 /var/lib/docker/devicemapper/devicemapper/metadata
# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
...
loop0 7:0 0 100G 0 loop
└─docker-253:0-20253-pool 253:2 0 100G 0 dm
└─docker-253:0-20253-base 253:3 0 10G 0 dm
loop1 7:1 0 2G 0 loop
└─docker-253:0-20253-pool 253:2 0 100G 0 dm
└─docker-253:0-20253-base 253:3 0 10G 0 dm
# qemu-img info data
image: data
file format: raw
virtual size: 100G (107374182400 bytes)
disk size: 585M
# qemu-img info metadata
image: metadata
file format: raw
virtual size: 2.0G (2147483648 bytes)
disk size: 1.1M
# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
75347df847b3 centos:latest "/bin/dd if=/dev/zer 3 minutes ago Exited (0) 3 minutes ago test01
Dockerではイメージを起動すると、ディスクが増えています。
dataは484Mから585Mに100Mくらい増えています。書き込んだ分だけ増える。
当然の結果です。
ディスクのメタ情報
このとき、ディスクに書き込んだ情報は、/var/lib/docker/devicemapper/metadata以下に保存されているようです。
# find ./ -type f -print -exec /bin/bash -c 'cat {} | python -mjson.tool' \;
./transaction-metadata
{
"device_hash": "75347df847b334b01ee5d01dd7b5a1a0ad5a0127738df9de28325fd6a1ce05c6",
"device_id": 8,
"open_transaction_id": 10
}
./base
{
"device_id": 1,
"initialized": true,
"size": 10737418240,
"transaction_id": 1
}
./f1b10cd842498c23d206ee0cbeaa9de8d2ae09ff3c7af2723a9e337a6965d639
{
"device_id": 2,
"initialized": false,
"size": 10737418240,
"transaction_id": 2
}
...(略)
./7322fbe74aa5632b33a400959867c8ac4290e9c5112877a7754be70cfe5d66e9
{
"device_id": 4,
"initialized": false,
"size": 10737418240,
"transaction_id": 4
}
./75347df847b334b01ee5d01dd7b5a1a0ad5a0127738df9de28325fd6a1ce05c6-init
{
"device_id": 7,
"initialized": false,
"size": 10737418240,
"transaction_id": 9
}
...(略)
削除後のディスク使用量は?
■コンテナのディスク削除
コンテナを削除してみます。きれいに作成する前のサイズに戻っていることがわかります。
# qemu-img info data
image: data
file format: raw
virtual size: 100G (107374182400 bytes)
disk size: 585M
# docker rm test01
test01
# qemu-img info data
image: data
file format: raw
virtual size: 100G (107374182400 bytes)
disk size: 484M
■イメージの削除
イメージを削除してみます。きれいにダウンロードする前のサイズに戻っていることがわかります。
# docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
docker.io/centos latest 7322fbe74aa5 5 weeks ago 172.2 MB
# docker rm 7322fbe74aa5
Error response from daemon: no such id: 7322fbe74aa5
FATA[0000] Error: failed to remove one or more containers
# docker rmi 7322fbe74aa5
Untagged: docker.io/centos:latest
Deleted: 7322fbe74aa5632b33a400959867c8ac4290e9c5112877a7754be70cfe5d66e9
Deleted: c852f6d61e65cddf1e8af1f6cd7db78543bfb83cdcd36845541cf6d9dfef20a0
Deleted: f1b10cd842498c23d206ee0cbeaa9de8d2ae09ff3c7af2723a9e337a6965d639
# qemu-img info data
image: data
file format: raw
virtual size: 100G (107374182400 bytes)
disk size: 292M