LXCで学ぶコンテナ入門 -軽量仮想化環境を実現する技術

第21回 LXCの構築・活用 [7] ─ いろいろなストレージバックエンドの利用(3:LVM)

この記事を読むのに必要な時間:およそ 9 分

Thin Provisioning 機能の利用

Linux kernel 3.2でDevice MapperにThin Provisioning機能が入りました。この機能をLVMから使用することで,実際のディスク容量以上の論理ボリュームを作成したり,スナップショット機能を使って既存の論理ボリュームのコピーを作成できます。

DockerをRHELやCentOS上で使う際には,このThin Provisioningの機能を使っていますのでご存じの方も多いのではないでしょうか。

LXCのLVMストレージバックエンドもこの機能をサポートしています。また,lxc-cloneを使ってクローンできます。

ここでは簡単にThin Provisioning機能を使ったコンテナの操作を紹介しておきます。Thin Provisioning機能そのものの詳細や,細かな操作についてはここでは述べません。

Thin Provisioning 機能を使う場合の準備

ボリュームグループは先の例で使ったlxcをそのまま使います。

$ sudo vgs
  VG        #PV #LV #SN Attr   VSize  VFree 
  lxc         1   0   0 wz--n-  8.00g  8.00g

Thin Provisioning用のプールをlxcという名前で作成します。データを保存する領域の他にメタデータを保存する領域が必要です。このためボリュームグループlxcの全部をプールとして確保するわけにはいきませんので,とりあえず90%程度を確保します。

$ sudo lvcreate -l 90%VG --type thin-pool --thinpool lxc lxc
  Rounding up size to full physical extent 8.00 MiB
  Logical volume "lxc" created
$ sudo lvs
  LV     VG        Attr      LSize    Pool Origin Data%  Move Log Copy%  Convert
  lxc    lxc       twi-a-tz-    7.20g               0.00                        

Thin Provisioning 機能を使ったコンテナの作成

ではコンテナを作成してみましょう。ここでは--thinpool lxcと指定して明示的にThin Provisioning用のプールを指定しています。

LXCはデフォルトではlxc.bdev.lvm.thin_poolで設定した名前のThin Provisioning用のプールがある場合は,自動的にそのプールを使ってコンテナ用の論理ボリュームを作成しますので,ここの例では--thinpool lxcは指定しなくても同じ結果となります。

逆にlxc.bdev.lvm.thin_poolで指定したプールがない場合に--thinpoolでプール名を指定せずに実行すると,Thin Provisioning機能は使わずに直接論理ボリュームを作成しようとします。少しややこしいですが,実際に使う場合はThin Provisioning機能を使ったり使わなかったりという状況は考えにくいので,あまり問題にならないかも知れませんね。

$ sudo lxc-create -n thin01 -B lvm --thinpool lxc \
> --fstype ext4 --fssize 8G -t download \
> -- -d ubuntu -r trusty -a amd64
     :(略)
  Logical volume "thin01" created
     :(略)
You just created an Ubuntu container (release=trusty, arch=amd64, variant=default)
     :(略)
$ sudo lxc-ls
thin01

作成できました。論理ボリュームの状態を見てみましょう。

$ sudo lvs
  LV     VG        Attr      LSize    Pool Origin Data%  Move Log Copy%  Convert
  lxc    lxc       twi-a-tz-    7.20g               7.13                        
  thin01 lxc       Vwi-a-tz-    8.00g lxc           6.41                        

7.2GBの領域に8GBのコンテナ用の論理ボリュームが作成されています。物理的に存在している容量以上のコンテナを作ったところでも,さらにコンテナを作れます。

$ sudo lxc-create -n thin02 -B lvm --thinpool lxc \
> --fstype ext4 --fssize 8G -t download \
> -- -d ubuntu -r trusty -a amd64
     :(略)
$ sudo lxc-ls
thin01  thin02  
$ sudo lvs
  LV     VG        Attr      LSize    Pool Origin Data%  Move Log Copy%  Convert
  lxc    lxc       twi-a-tz-    7.20g              14.14                        
  thin01 lxc       Vwi-a-tz-    8.00g lxc           6.41                        
  thin02 lxc       Vwi-a-tz-    8.00g lxc           6.31                        

7.2GBの領域に8GBのコンテナが2つ存在しています。これは極端な例ですが,常にコンテナに割り当てた容量を使わない場合もあるでしょうから,ある程度の領域を準備しておいて足りなくなりそうな場合に追加するという運用ができるようになりますね。

Thin Provisioning 機能を使ったコンテナのクローン

lxc-clone-sオプションを指定しないコピーによるクローンの場合は,コンテナを新たに作成する場合と変わりませんのでここでは述べません。では-sを指定してクローンしてみましょう。

$ sudo lxc-clone -o thin02 -n thin03 -s 
  Logical volume "thin03" created
Created container thin03 as snapshot of thin02
$ sudo lvs
  LV     VG        Attr      LSize    Pool Origin Data%  Move Log Copy%  Convert
  lxc    lxc       twi-a-tz-    7.20g              14.15                        
  thin01 lxc       Vwi-a-tz-    8.00g lxc           6.41                        
  thin02 lxc       Vwi-a-tz-    8.00g lxc           6.31                        
  thin03 lxc       Vwi-a-tz-    8.00g lxc  thin02   6.31                        

以上のようにthin02コンテナのスナップショットを使ったクローンとしてthin03コンテナが作成されました。

コンテナを2つ起動して,apt-get updateを実行してみました。

$ sudo lxc-start -n thin02 -d  (スナップショット元のコンテナの起動)
$ sudo lxc-start -n thin03 -d  (スナップショット先のコンテナの起動)
$ sudo lxc-ls -f
NAME    STATE    IPV4       IPV6  AUTOSTART  
-------------------------------------------
thin01  STOPPED  -          -     NO         
thin02  RUNNING  10.0.3.29  -     NO         
thin03  RUNNING  10.0.3.68  -     NO
$ sudo lxc-attach -n thin02 -- apt-get update  (コンテナ内でapt-get update実行)
     :(略)
$ sudo lxc-attach -n thin03 -- apt-get update  (コンテナ内でapt-get update実行)
     :(略)
$ sudo lvs  (論理ボリュームの確認)
  LV     VG        Attr      LSize    Pool Origin Data%  Move Log Copy%  Convert
  lxc    lxc       twi-a-tz-    7.20g              18.71                        
  thin01 lxc       Vwi-a-tz-    8.00g lxc           6.36                        
  thin02 lxc       Vwi-aotz-    8.00g lxc           8.43                        
  thin03 lxc       Vwi-aotz-    8.00g lxc  thin02   8.31                        

それぞれのコンテナで使用量が増えていますね。

先に紹介したThin Provisioning機能を使わないLVMでは,スナップショットのスナップショットが作成できませんでしたので,スナップショットを使ったクローンにより作成したコンテナをさらにスナップショットを使ってクローンできませんでした。

それに対してThin Provisioning機能を使うと,スナップショットのスナップショットが作成できます。試してみましょう。

$ sudo lxc-clone -o thin03 -n thin04 -s -B lvm
  Logical volume "thin04" created
Created container thin04 as snapshot of thin03
$ sudo lvs
  LV     VG        Attr      LSize    Pool Origin Data%  Move Log Copy%  Convert
  lxc    lxc       twi-a-tz-    7.20g              19.02                        
  thin01 lxc       Vwi-a-tz-    8.00g lxc           6.36                        
  thin02 lxc       Vwi-a-tz-    8.00g lxc           8.50                        
  thin03 lxc       Vwi-a-tz-    8.00g lxc  thin02   8.50                        
  thin04 lxc       Vwi-a-tz-    8.00g lxc  thin03   8.50                        

コンテナの削除を試してみましょう。クローン元のコンテナから削除してみます。

$ sudo lxc-destroy -n thin02 (クローン元のコンテナの削除)
     :(略)
  Logical volume "thin02" successfully removed
(削除したコンテナ用のボリュームのみ削除されている)
$ sudo lxc-ls
thin01  thin03  thin04  
$ sudo lvs
  LV     VG        Attr      LSize    Pool Origin Data%  Move Log Copy%  Convert
  lxc    lxc       twi-a-tz-    7.20g              16.53                        
  thin01 lxc       Vwi-a-tz-    8.00g lxc           6.36                        
  thin03 lxc       Vwi-a-tz-    8.00g lxc           8.50                        
  thin04 lxc       Vwi-a-tz-    8.00g lxc  thin03   8.50                        
(クローン先のボリュームは残っている)
$ sudo lxc-destroy -n thin03 (更にクローン元のコンテナの削除)
     :(略)
$ sudo lvs
  LV     VG        Attr      LSize    Pool Origin Data%  Move Log Copy%  Convert
  lxc    lxc       twi-a-tz-    7.20g              16.52                        
  thin01 lxc       Vwi-a-tz-    8.00g lxc           6.36                        
  thin04 lxc       Vwi-a-tz-    8.00g lxc           8.50                        
(クローン先のボリュームは残っている)

Thin Provisioning機能を使った場合,スナップショットを使っても,それぞれの論理ボリュームは独立したコピーとなります。従って,クローン元を削除しても,クローン先のスナップショットが削除されることはありませんので,先に紹介したような不具合は起こりません。

まとめ

今回はストレージバックエンドとしてLVMを使った場合のコンテナの作成,クローンを紹介しました。

Thin Provisioning機能を使わない場合に不具合がある点を除いても,Thin Provisioning機能を使った方がスナップショットを使ったクローンを含めて便利な気がします。

ストレージバックエンドとしてLVMを使う場合は,カーネルがThin Provisioning機能に対応している場合はThin Provisioning機能の使用を前提にしても良いのかな,と記事を書きながら思いました。

次回もストレージバックエンドを便利に使う方法や,その他のまだ紹介していないLXCの機能を紹介する予定です。

著者プロフィール

加藤泰文(かとうやすふみ)

2009年頃にLinuxカーネルのcgroup機能に興味を持って以来,Linuxのコンテナ関連の最新情報を追っかけたり,コンテナの勉強会を開いたりして勉強しています。英語力のない自分用にLXCのmanページを日本語訳していたところ,あっさり本家にマージされてしまい,それ以来日本語訳のパッチを送り続けています。

Plamo Linuxメンテナ

Twitter:@ten_forward
技術系のブログ:http://tenforward.hatenablog.com/