今日は、DockerでDirect LVMを利用してみます。
通常は、ループバックデバイスによるLVMになっています。
DockerのデフォルトLVMとは
Dockerのデフォルトは、ループバックデバイスによるLVMです。
使用しているのは、/var/lib/docker/devicemapper/devicemapper/dataと/var/lib/docker/devicemapper/devicemapper/metadataのRAWファイル(スパース)が作成され、ループデバイスとしてLVMが構成されています。
# 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
# qemu-img info /var/lib/docker/devicemapper/devicemapper/data
image: /var/lib/docker/devicemapper/devicemapper/data
file format: raw
virtual size: 100G (107374182400 bytes)
disk size: 292M
# qemu-img info /var/lib/docker/devicemapper/devicemapper/metadata
image: /var/lib/docker/devicemapper/devicemapper/metadata
file format: raw
virtual size: 2.0G (2147483648 bytes)
disk size: 744K
# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 50G 0 disk
├─sda1 8:1 0 500M 0 part /boot
└─sda2 8:2 0 49.5G 0 part
├─centos-root 253:0 0 45.6G 0 lvm /
└─centos-swap 253:1 0 3.9G 0 lvm [SWAP]
sr0 11:0 1 1024M 0 rom
loop0 7:0 0 100G 0 loop
└─docker-253:0-201702034-pool 253:2 0 100G 0 dm
└─docker-253:0-201702034-base 253:3 0 10G 0 dm
loop1 7:1 0 2G 0 loop
└─docker-253:0-201702034-pool 253:2 0 100G 0 dm
└─docker-253:0-201702034-base 253:3 0 10G 0 dm
direct LVMを利用する
利用する理由
direct LVMを利用します。ループバックデバイスは、やはり遅いです。RAWのスパースファイルですので、拡張時に領域を確保するための時間がかかります。RAWのノンスパースファイルであればもう少し早いのかもしれません。Dockerコンテナ起動時には、ループバックデバイスの使用に関する警告が出ます。
# docker run -it --name homma01 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@959b838de28a /]#
また、コンテナを大量に起動するときには、起動速度の差が顕著に表れます。
中井さんの解説ページにも書かれています。詳細は、「第68回 Dockerストレージドライバーの性能比較 (中井悦司)」を見てください。大元の記事は、「Comprehensive Overview of Storage Scalability in Docker」でしょうか。
overlayFSが一番ベストですが、direct LVMもループバックデバイスに比べて2倍以上高速です。
direct LVMの設定をします
ディスクを追加するとき
docker用のディスクを追加した場合の方法です。今回は、/dev/sdbを追加した場合です。
# ls -al /dev/sd*
brw-rw----. 1 root disk 8, 0 8月 7 21:55 /dev/sda
brw-rw----. 1 root disk 8, 1 8月 7 21:55 /dev/sda1
brw-rw----. 1 root disk 8, 2 8月 7 21:55 /dev/sda2
brw-rw----. 1 root disk 8, 16 8月 7 21:55 /dev/sdb
/etc/sysconfig/docker-storage-setupに追加した/dev/sdbを設定して、再起動します。
/dev/sdb上にLVMを作成し利用するようになります。自動的に設定(/etc/sysconfig/docker-storage)が追加されます。
# systemctl stop docker
# rm -rf /var/lib/docker
# echo DEVS=/dev/sdb >> /etc/sysconfig/docker-storage-setup
# systemctl start docker
# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 50G 0 disk
├─sda1 8:1 0 500M 0 part /boot
└─sda2 8:2 0 49.5G 0 part
├─centos-root 253:0 0 45.6G 0 lvm /
└─centos-swap 253:1 0 3.9G 0 lvm [SWAP]
sdb 8:16 0 50G 0 disk
└─sdb1 8:17 0 50G 0 part
├─centos-docker--pool_tmeta 253:2 0 104M 0 lvm
│ └─centos-docker--pool 253:4 0 30G 0 lvm
│ └─docker-253:0-67161589-base 253:5 0 10G 0 dm
└─centos-docker--pool_tdata 253:3 0 30G 0 lvm
└─centos-docker--pool 253:4 0 30G 0 lvm
└─docker-253:0-67161589-base 253:5 0 10G 0 dm
sr0 11:0 1 636M 0 rom
# cat /etc/sysconfig/docker-storage
DOCKER_STORAGE_OPTIONS=-s devicemapper --storage-opt dm.fs=xfs --storage-opt dm.thinpooldev=/dev/mapper/centos-docker--pool
何が起こったか説明します。実は、systemdの設定で、docker.serviceが起動する前にdocker-storage-setup.serviceが呼ばれるようになっています。docker-storage-setup.serviceは、/etc/sysconfig/docker-storage-setupを設定ファイルとして、/usr/bin/docker-storage-setupを起動するようになっているため、Dockerを起動したときに自動的にLVMの設定が開始されたわけです。
# cat /usr/lib/systemd/system/docker.service
[Unit]
Description=Docker Application Container Engine
Documentation=http://docs.docker.com
After=network.target
Wants=docker-storage-setup.service
... 略
# cat /usr/lib/systemd/system/docker-storage-setup.service
...略
[Service]
Type=oneshot
ExecStart=/usr/bin/docker-storage-setup
EnvironmentFile=-/etc/sysconfig/docker-storage-setup
... 略
残りのディスクを使用する
/dev/sdaのディスクのあまりを利用する場合です。
# parted -l /dev/sda
モデル: VMware, VMware Virtual S (scsi)
ディスク /dev/sda: 107GB
セクタサイズ (論理/物理): 512B/512B
パーティションテーブル: msdos
ディスクフラグ:
番号 開始 終了 サイズ タイプ ファイルシステム フラグ
1 1049kB 525MB 524MB primary xfs boot
2 525MB 58.4GB 57.9GB primary lvm
領域がないので、まず領域を作る必要があります。上で実行したコマンドの結果が重要になります。上から2行目のディスクサイズ:107GB、下から1番目の2のディスクの終了位置:58.4GBが重要です。入力する必要があります。
では、partedコマンドを利用して作成していきましょう。mkpartを入力し、質問に回答していきます。入力する値は参考にしてください。
# parted /dev/sda
(parted) mkpart
パーティションの種類? primary/プライマリ/extended/拡張? p
ファイルシステムの種類? [ext2]?
開始? 57.9GB
終了? 107GB
(parted) p
モデル: VMware, VMware Virtual S (scsi)
ディスク /dev/sda: 107GB
セクタサイズ (論理/物理): 512B/512B
パーティションテーブル: msdos
ディスクフラグ:
番号 開始 終了 サイズ タイプ ファイルシステム フラグ
1 1049kB 525MB 524MB primary xfs boot
2 525MB 58.4GB 57.9GB primary lvm
3 58.4GB 107GB 49.0GB primary
これを実行すると、/dev/sda3が出来上がります。
# ls -al /dev/sda*
brw-rw----. 1 root disk 8, 0 8月 7 22:37 /dev/sda
brw-rw----. 1 root disk 8, 1 8月 7 22:27 /dev/sda1
brw-rw----. 1 root disk 8, 2 8月 7 22:27 /dev/sda2
brw-rw----. 1 root disk 8, 3 8月 7 22:37 /dev/sda3
さっきと同様に、「echo DEVS=/dev/sda3 >> /etc/sysconfig/docker-storage-setup」としたいですが、「Partition specification unsupported at this time.」と怒られてしまいます。
手動で作成する必要があります。次の手順に従って作成します。
手動でDirectLVMを作成
DirectLVMで検索すると、ambakshi/docker-direct-lvm.shが出てきます。これでもよいですが、これは、 シンプロビジョニングされた論理ボリュームを作成していないので、もうひと手順追加して、以下のような手順がよいです。
/usr/bin/docker-storage-setupでも同様の処理を行っています。
# export DEVS=/dev/sda3
# pvcreate $DEVS
Physical volume "/dev/sda3" successfully created
# vgcreate direct-lvm $DEVS
Volume group "direct-lvm" successfully created
# lvcreate -n data direct-lvm -l 50%VG
Logical volume "data" created.
# lvcreate -n metadata direct-lvm -l 5%VG
Logical volume "metadata" created.
# lvconvert -y --zero n --thinpool direct-lvm/data --poolmetadata direct-lvm/metadata
# lvdisplay -C
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
root centos -wi-ao---- 50.00g
swap centos -wi-ao---- 3.88g
data direct-lvm -wi-a----- 43.34g
metadata direct-lvm -wi-a----- 2.28g
# ls /dev/direct-lvm
data
# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 100G 0 disk
├─sda1 8:1 0 500M 0 part /boot
├─sda2 8:2 0 53.9G 0 part
│ ├─centos-root 253:0 0 50G 0 lvm /
│ └─centos-swap 253:1 0 3.9G 0 lvm [SWAP]
└─sda3 8:3 0 45.6G 0 part
├─direct--lvm-data_tmeta 253:2 0 2.3G 0 lvm
│ └─direct--lvm-data 253:4 0 22.8G 0 lvm
└─direct--lvm-data_tdata 253:3 0 22.8G 0 lvm
└─direct--lvm-data 253:4 0 22.8G 0 lvm
sr0 11:0 1 1024M 0 rom
#
LVMが出来上がったので、設定します。
# cat /etc/sysconfig/docker-storage
DOCKER_STORAGE_OPTIONS=-s devicemapper --storage-opt dm.thinpooldev=/dev/mapper/direct--lvm-data
# systemctl stop docker
# rm -rf /var/lib/docker/
# systemctl start docker
以上です。