LXC 1.0: コンテナーストレージ [5/10]

## この文書について

この文書は、連載記事「[LXC 1.0: Blog post series](https://www.stgraber.org/2013/12/20/lxc-1-0-blog-post-series/)」の一つである以下の記事を翻訳したものです。連載の目次や注意点は[こちら](http://qiita.com/m-shibata/items/ee9b295a2596824da819)を参照してください。

* https://www.stgraber.org/2013/12/27/lxc-1-0-container-storage/

この文書のライセンスは原文と同じく、[Creative Commons BY-NC-SA 2.5](http://creativecommons.org/licenses/by-nc-sa/2.5/)のもとに提供されています。

![CC-BY-NC-SA 2.5](http://i.creativecommons.org/l/by-nc-sa/2.5/88x31.png)


## ストレージの「backingstore」

LXCはさまざまなストレージバックエンド（これを `backingstore` と呼びます）をサポートしています。標準のバックエンドは「 `none` 」で、これは単純にルートファイルシステムを `/var/lib/lxc/<コンテナー>/rootfs` に保存するものです。バックエンドは、 `lxc-create` や `lxc-clone` 時に、 `-B` オプションで指定できます。

現在サポートしている値は次のとおりです：

### 直接ストレージに保存（「none」や「dir」）

これは標準のbackingstoreで、コンテナーのルートファイルシステムを `/var/lib/lxc/<コンテナー>/rootfs` に保存します。

`--dir` オプション（「 `dir` 」指定時）を使えば、保存先を変更できます。

### btrfs

このbackingstoreを使うと、LXCはそのコンテナー用に新しいサブボリュームを作成します。これにより、スナップショットがより簡単に作成できます。

### lvm

これは、コンテナー用に新しい論理ボリュームを作成します。LVは `--lvname` で指定します（指定しない場合はコンテナー名になります）。VGは `--vgname` で指定します（指定しない場合は「lxc」になります）。ファイルシステムは `--fstype` で指定可能です（指定しない場合は「ext4」になります）。 `--fssize` で容量を指定できます（指定しない場合は「1G」になります）。 `--thinpool` でLVMシンプールを使用できます。

### overlayfs

あるコンテナーから別のコンテナーを作成するためにコンテナーを複製する際によく使われるオプションで、あらゆる変更をオーバーレイとして保存します。

`lxc-create` 時に使用した場合、コンテナー作成後に行われたあらゆる変更は、コンテナーのルートファイルシステムの隣にある「 `delta0` 」ディレクトリに保存されます。

### zfs

btrfsと似ていますが、私はこれまで使った事がないため、コンテナー用にサブボリュームのようなものを作ること、スナップショットや複製が高速であること、サイズ効率が良いこと以上のことはわかりません。


## 標準的なパス

LXCが参照し、ファイルを保存する一般的なパスは次のとおりです：

* /var/lib/lxc （コンテナーの標準的な保存場所です）
* /var/lib/lxcsnap （スナップショットの標準的な保存場所です）
* /var/cache/lxc （テンプレートキャッシュの標準的な保存場所です）
* $HOME/.local/share/lxc （非特権コンテナーの標準的な保存場所です）
* $HOME/.local/share/lxcsnap （非特権スナップショットの標準的な保存場所です）
* $HOME/.cache/lxc （非特権テンプレートキャッシュの標準的な保存場所です）

`lxcpath` とも呼ばれている標準的なパスは、コマンドラインで `-P` オプションを付けた場合や、 `/etc/lxc/lxc.conf` （もしくは非特権コンテナーの場合は `$HOME/.config/lxc/lxc.conf` ）において、「 `lxcpath = /新しい/パス` 」を指定した場合に変更できます。

スナップショットのディレクトリは常に、 `lxcpath` に「 `snap` 」を追加したものですので、 `lxcpath` の値に追随します。テンプレートキャッシュは残念ながらハードコードされており、bind mountやシンボリックリンクなしには簡単には移動できません。

すべてのコンテナーは、作成時に標準の設定ファイルである `/etc/lxc/default.conf` を参照します（非特権用のものはまだありません）。テンプレート自体は、 `/usr/share/lxc/templates` に保存されます。


## コンテナーの複製

これらのbackingstoreは、コンテナーの複製を始めた時のみ意味が出てきます。例えば、これまでに作った「p1」という名前のUbuntuコンテナーについて、「p4」という名前でコピーしたいとしましょう。これは次のコマンドを実行するだけで実現できます：

```
sudo lxc-clone -o p1 -n p4
```

そうすると、「p4」という実際に動作するコンテナーが得られるはずです。これは「p1」の単なるコピーですが、新しいMACアドレスやホスト名が正しく設定されています。

「p1」でちょっと試したいことがあるけれども、コンテナー自身に変更を加えたくないとしましょう。さらに、完全なコピーにかかる時間が惜しい場合は、次のコマンドを実行すると良いでしょう：

```
sudo lxc-clone -o p1 -n p1-test -B overlayfs -s
```

この場合、「p1」のルートファイルシステムをベースにした「p1-test」コンテナーが得られます。また、「p1-test」に加えた変更はすべて、「 `delta0` 」ディレクトリに保存されます。この「 `-s` 」オプションは、LVMやbtrfs（おそらくzfsも）のコンテナーでも動作します。このオプションは、 `lxc-clone` にルートファイルシステム全体のコピーではなく、スナップショット機能を使うよう通知しているのです。


## スナップショットの取得

複製機能は、コンテナーを破棄することがあるような開発環境においては、とても便利で素晴らしい機能です。ただし稼働中のような、バックアップやリスクのある変更を実行する前の状態を保存しておきたい場合においては、スナップショットの方がより便利でしょう。

LXCでは、「 `lxc-snapshot` 」ツールを使うと、コンテナーのスナップショットの作成やリストアップ、復元、破棄を行えます。実際の動作を見せる前に一つ注意点があります。「 `lxc-snapshot` 」は現在のところディレクトリベースのコンテナーでは動作しません。単純に空のスナップショットを生成するだけです。これはLXC 1.0が実際にリリースされる前に修正される予定です。

では、「p1-lvm」コンテナーに「 `apache2` 」をインストールする前に、そのコンテナーのバックアップを取ることにしましょう。次のコマンドを実行するだけです：

```
echo "before installing apache2" > snap-comment
sudo lxc-snapshot -n p1-lvm -c snap-comment
```

この時点で、次のコマンドを実行すれば、スナップショットが作成されたことがわかります：

```
sudo lxc-snapshot -n p1-lvm -L -C
```

さらに「 `apache2` 」をそのコンテナーにインストールしたとします。コンテナーを元の状態に戻すには次のコマンドを実行します：

```
sudo lxc-snapshot -n p1-lvm -r snap0
```

もしスナップショット自体を新しいコンテナーにリストアしたい場合は、次のように実行します：

```
sudo lxc-snapshot -n p1-lvm -r snap0 p1-lvm-snap0
```

これにより「 `snap0` 」時点での「p1-lvm」のコピーである、「p1-lvm-snap0」という新しいコンテナーが作成されます。