Docker を LVM シンプールで使う

# [Docker][CentOS]Docker を LVM シンプールで使う

## はじめに

- CentOS 7.1.1503
- docker 1.6.2

## ループバックデバイスの警告抑止

いつからか `docker run` で次のような警告が表示されるようになっていました。

```console
$ docker run centos /bin/echo hoge
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.
hoge
```

> ループバックデバイスは本番環境ではとても奨励されないので `--storage-opt dm.thinpooldev` を使うか `--storage-opt dm.no_warn_on_loop_devices=true` でこの警告を抑止してね！

ってことだと思います。

試しに `--storage-opt dm.no_warn_on_loop_devices=true` を付けてみると。

```console
$ docker --storage-opt dm.no_warn_on_loop_devices=true run centos /bin/echo hoge
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.
hoge
```

なにも変わらない・・・こういう使い方ではないようです。

`/etc/sysconfig/docker-storage` を編集する必要がありました。

```console
$ vim /etc/sysconfig/docker-storage
```

次のように `DOCKER_STORAGE_OPTIONS` に追記します。

```sh
DOCKER_STORAGE_OPTIONS="--storage-opt dm.no_warn_on_loop_devices=true"
```

docker サービスを再起動します。

```console
$ systemctl restart docker.service
```

もう一度 `docker run` してみると・・警告が表示されなくなりました。

```console
$ docker run centos /bin/echo hoge
hoge
```

## LVM シンプールを使う

そもそも、シンプールをループバックデバイスに作ると性能が良くないのでやめてってことだと思うので `--storage-opt dm.thinpooldev` を使って普通の LVM シンプールを使ってみます。

Docker を止めます。

```console
$ systemctl stop docker.service
```

Docker の既存データをすべて削除します。

```console
$ rm -fr /var/lib/docker/*
```

LVM のシンプロビジョニングなら前にやったので、以下を参考にシンプールを作ります。

- [LVM シンプロビジョニングボリューム](http://qiita.com/ngyuki/items/84c471862cb29f6dfc71 "LVM シンプロビジョニングボリューム")

```console
$ parted -s /dev/sdb -- mklabel gpt mkpart primary 1 -1 set 1 lvm on
$ pvcreate /dev/sdb1
  Physical volume "/dev/sdb1" successfully created
$ vgcreate -s 32MB vg0 /dev/sdb1
  Volume group "vg0" successfully created
$ lvcreate --thin -L 16GB vg0/docker
  Logical volume "docker" created.
```

シンプールが作成されています。

```console
$ lvs
  LV     VG   Attr       LSize  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  docker vg0  twi-a-tz-- 16.00g             0.00   0.31
```

`/etc/sysconfig/docker-storage` を編集します。

```console
$ vim /etc/sysconfig/docker-storage
```

次のようにシンプールを指定します。

```sh
DOCKER_STORAGE_OPTIONS="--storage-opt dm.thinpooldev=/dev/mapper/vg0-docker"
```

docker サービスを開始します。

```console
$ systemctl start docker.service
```

docker info でそれっぽく表示されていることを確認します。

```console
$ docker info
Containers: 0
Images: 0
Storage Driver: devicemapper
 Pool Name: vg0-docker
 Pool Blocksize: 65.54 kB
 Backing Filesystem: xfs
 Data file: 
 Metadata file: 
 Data Space Used: 307.2 MB
 Data Space Total: 17.18 GB
 Data Space Available: 16.87 GB
 Metadata Space Used: 245.8 kB
 Metadata Space Total: 33.55 MB
 Metadata Space Available: 33.31 MB
 Udev Sync Supported: true
 Library Version: 1.02.93-RHEL7 (2015-01-28)
  :
```

`docker run` してみます。

```console
$ docker run centos /bin/echo hoge
Unable to find image 'centos:latest' locally
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
hoge
```

`lsblk` すると次のようになりました。

```console
$ lsblk /dev/sdb1
NAME                          MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sdb1                            8:17   0  20G  0 part 
├─vg0-docker_tmeta            253:0    0  32M  0 lvm  
│ └─vg0-docker                253:2    0  16G  0 lvm  
│   └─docker-8:1-9643532-base 253:3    0  10G  0 dm   
└─vg0-docker_tdata            253:1    0  16G  0 lvm  
  └─vg0-docker                253:2    0  16G  0 lvm  
    └─docker-8:1-9643532-base 253:3    0  10G  0 dm   
```

## docker-storage-setup でシンプールをセットアップ

↑では自分でシンプールを作成して /etc/sysconfig/docker-storage を編集しましたが、`docker-storage-setup` を使えばそのあたりを自動で作成してくれるようです。

Docker を止めてすべてのデータを削除します。

```console
$ systemctl stop docker.service
$ rm -fr /var/lib/docker/*
```

↑で作っていたシンプールも削除します。

```console
$ lvremove /dev/vg0/docker
Do you really want to remove active logical volume docker? [y/n]: y
  Logical volume "docker" successfully removed
```

`/etc/sysconfig/docker-storage-setup` で、シンプールに使うボリュームグループを指定します。

```console
$ cat <<EOS> /etc/sysconfig/docker-storage-setup
VG=vg0
EOS
```

`docker-storage-setup` を実行します。

```console
$ docker-storage-setup
  Volume group "sda1" not found
  Cannot process volume group sda1
  Rounding up size to full physical extent 32.00 MiB
  Logical volume "docker-poolmeta" created.
WARNING: ext4 signature detected on /dev/vg0/docker-pool at offset 1080. Wipe it? [y/n]: y
  Wiping ext4 signature on /dev/vg0/docker-pool.
  Logical volume "docker-pool" created.
  WARNING: Converting logical volume vg0/docker-pool and vg0/docker-poolmeta to pool's data and metadata volumes.
  THIS WILL DESTROY CONTENT OF LOGICAL VOLUME (filesystem etc.)
  Converted vg0/docker-pool to thin pool.
  Logical volume "docker-pool" changed.
```

シンプールが作成されています。

```console
$ lvs
  LV          VG   Attr       LSize  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  docker-pool vg0  twi-a-t--- 11.94g             0.00   0.12
```

`/etc/sysconfig/docker-storage` も作成されています。

```console
$ cat /etc/sysconfig/docker-storage
DOCKER_STORAGE_OPTIONS=-s devicemapper --storage-opt dm.fs=xfs --storage-opt dm.thinpooldev=/dev/mapper/vg0-docker--pool
```

docker サービスを開始します。

```console
$ systemctl start docker.service
```

`docker run` してみます。

```console
$ docker run centos /bin/echo hoge
Unable to find image 'centos:latest' locally
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
hoge
```

ちなみに、この docker-storage-setup ですが、多分 [これ](https://github.com/projectatomic/docker-storage-setup) だと思うんですけど、`systemctl show docker-storage-setup.service` してみた感じ、ブート時に自動で実行されるようになっているようです。

## docker-storage-setup でシンプールをセットアップ：改

Docker のストレージ用のディスクを別に設けるなら、パーティションの作成やボリュームグループの作成も `docker-storage-setup` にやらせることができました。

Docker を止めてすべてのデータを削除します。

```console
$ systemctl stop docker.service
$ rm -fr /var/lib/docker/*
```

↑で作っていたシンプールとかボリュームグループとかパーティションとかを削除します。

```console
$ lvremove /dev/vg0/docker-pool
Do you really want to remove active logical volume docker-pool? [y/n]: y
  Logical volume "docker-pool" successfully removed

$ vgremove /dev/vg0
  Volume group "vg0" successfully removed

$ parted -s /dev/sdb rm 1
```

`/etc/sysconfig/docker-storage-setup` でディスクのデバイスと、作成するボリュームグループの名前を指定します。

```console
$ cat <<EOS> /etc/sysconfig/docker-storage-setup
DEVS=/dev/sdb
VG=vg-docker
EOS
```

`docker-storage-setup` を実行します。

```console
$ docker-storage-setup
  Volume group "sda1" not found
  Cannot process volume group sda1

  ...snip...

If you created or changed a DOS partition, /dev/foo7, say, then use dd(1)
to zero the first 512 bytes:  dd if=/dev/zero of=/dev/foo7 bs=512 count=1
(See fdisk(8).)
  Physical volume "/dev/sdb1" successfully created
  Volume group "vg-docker" successfully created
  Rounding up size to full physical extent 24.00 MiB
  Logical volume "docker-poolmeta" created.
  Logical volume "docker-pool" created.
  WARNING: Converting logical volume vg-docker/docker-pool and vg-docker/docker-poolmeta to pool's data and metadata volumes.
  THIS WILL DESTROY CONTENT OF LOGICAL VOLUME (filesystem etc.)
  Converted vg-docker/docker-pool to thin pool.
  Logical volume "docker-pool" changed.
```

シンプールが作成されています。

```console
$ lvs
  LV          VG        Attr       LSize  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  docker-pool vg-docker twi-a-t--- 11.98g             0.00   0.16
```

`/etc/sysconfig/docker-storage` も作成されています。

```console
$ cat /etc/sysconfig/docker-storage
DOCKER_STORAGE_OPTIONS=-s devicemapper --storage-opt dm.fs=xfs --storage-opt dm.thinpooldev=/dev/mapper/vg--docker-docker--pool
```

docker サービスを開始します。

```console
$ systemctl start docker.service
```

`docker run` してみます。

```console
$ docker run centos /bin/echo hoge
Unable to find image 'centos:latest' locally
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
hoge
```

## さいごに

うーん？
ループバックデバイスのほうがコンテナの作成が明らかに早いのだけれども・・・なにか根本的に間違っているのかもしれません。