LXD 2.0: ライブマイグレーション [9/12]

## この文書について

この文書は、連載記事「[LXD 2.0: Blog post series](https://www.stgraber.org/2016/03/11/lxd-2-0-blog-post-series-012/)」（[日本語版目次](http://qiita.com/m-shibata/items/029b19d90af2a79116c2)）の一つである以下の記事を翻訳したものです。

* https://www.stgraber.org/2016/04/14/lxd-2-0-lxd-in-lxd-812/

この文書のライセンスは原文と同じく、[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)

---------

## はじめに

LXD 2.0のもっとも素晴らしい機能の一つは、実験的な機能とはいえ、コンテナのチェックポイントとリストアのサポートでしょう。

簡単に言うと、チェックポイント・リストアとは実行中のコンテナの状態をディスクに保存し、その後に復元する機能です。これは同じホスト上に復元するのであればコンテナのステートフルなスナップショットであり、異なるホストに復元するのであればライブマイグレーションとなります。


## 要件

コンテナのライブマイグレーションやステートフルスナップショットを利用するためには、以下の条件を満たす必要があります：

* 4.4以上のLinuxカーネル。
* CRIU 2.0。カーネルコンフィグによっては、いくつかのコミットをcherry-pickする必要があるかもしれません。
* LXDをホスト上で直接実行していること。ネストしたコンテナではこの機能は使えません。
* マイグレーションを行うために、ターゲットマシンには少なくともソースと同じ命令セットを実装していること、ターゲットカーネルはソースと同じシステムコールをサポートしていること、ソース上でマウントされているカーネル空間のあらゆるファイルシステムがターゲットでもマウント可能であること。

Ubuntu 16.04 LTSであれば、上記条件をすべて満たします。この場合、必要なのはCRIUをインストールするだけです：

```
apt install criu
```

## 使用方法

### ステートフルスナップショット

通常のコンテナスナップショットは、次のように取得します：

```
stgraber@dakara:~$ lxc snapshot c1 first
stgraber@dakara:~$ lxc info c1 | grep first
 first (taken at 2016/04/25 19:35 UTC) (stateless)
```

ステートフルスナップショットの場合、次のように取得します：

```
stgraber@dakara:~$ lxc snapshot c1 second --stateful
stgraber@dakara:~$ lxc info c1 | grep second
 second (taken at 2016/04/25 19:36 UTC) (stateful)
```

これはつまり、コンテナの実行時の状態が、スナップショットの一つとしてディスクに保存されるということです。そのようなスナップショットも、ステートレスなスナップショットと同様に、次のコマンドでリストアできます：

```
stgraber@dakara:~$ lxc restore c1 second
stgraber@dakara:~$
```

### ステートフルな停止と起動

カーネルの更新やそれに類するメンテナンスによって、サーバーを再起動することがあるでしょう。再起動後にすべてのコンテナを一から起動しなおすのではなく、次のようなことが行えます：

```
stgraber@dakara:~$ lxc stop c1 --stateful
```

コンテナの実行時の状態がディスクに書き込まれ、次回起動時にそれが取り出されます。

この状態は、次のように確認できます：

```
root@dakara:~# tree /var/lib/lxd/containers/c1/rootfs/state/
/var/lib/lxd/containers/c1/rootfs/state/
├── cgroup.img
├── core-101.img
├── core-102.img
├── core-107.img
├── core-108.img
├── core-109.img
├── core-113.img
├── core-114.img
├── core-122.img
├── core-125.img
├── core-126.img
├── core-127.img
├── core-183.img
├── core-1.img
├── core-245.img
├── core-246.img
├── core-50.img
├── core-52.img
├── core-95.img
├── core-96.img
├── core-97.img
├── core-98.img
├── dump.log
├── eventfd.img
├── eventpoll.img
├── fdinfo-10.img
├── fdinfo-11.img
├── fdinfo-12.img
├── fdinfo-13.img
├── fdinfo-14.img
├── fdinfo-2.img
├── fdinfo-3.img
├── fdinfo-4.img
├── fdinfo-5.img
├── fdinfo-6.img
├── fdinfo-7.img
├── fdinfo-8.img
├── fdinfo-9.img
├── fifo-data.img
├── fifo.img
├── filelocks.img
├── fs-101.img
├── fs-113.img
├── fs-122.img
├── fs-183.img
├── fs-1.img
├── fs-245.img
├── fs-246.img
├── fs-50.img
├── fs-52.img
├── fs-95.img
├── fs-96.img
├── fs-97.img
├── fs-98.img
├── ids-101.img
├── ids-113.img
├── ids-122.img
├── ids-183.img
├── ids-1.img
├── ids-245.img
├── ids-246.img
├── ids-50.img
├── ids-52.img
├── ids-95.img
├── ids-96.img
├── ids-97.img
├── ids-98.img
├── ifaddr-9.img
├── inetsk.img
├── inotify.img
├── inventory.img
├── ip6tables-9.img
├── ipcns-var-10.img
├── iptables-9.img
├── mm-101.img
├── mm-113.img
├── mm-122.img
├── mm-183.img
├── mm-1.img
├── mm-245.img
├── mm-246.img
├── mm-50.img
├── mm-52.img
├── mm-95.img
├── mm-96.img
├── mm-97.img
├── mm-98.img
├── mountpoints-12.img
├── netdev-9.img
├── netlinksk.img
├── netns-9.img
├── netns-ct-9.img
├── netns-exp-9.img
├── packetsk.img
├── pagemap-101.img
├── pagemap-113.img
├── pagemap-122.img
├── pagemap-183.img
├── pagemap-1.img
├── pagemap-245.img
├── pagemap-246.img
├── pagemap-50.img
├── pagemap-52.img
├── pagemap-95.img
├── pagemap-96.img
├── pagemap-97.img
├── pagemap-98.img
├── pages-10.img
├── pages-11.img
├── pages-12.img
├── pages-13.img
├── pages-1.img
├── pages-2.img
├── pages-3.img
├── pages-4.img
├── pages-5.img
├── pages-6.img
├── pages-7.img
├── pages-8.img
├── pages-9.img
├── pipes-data.img
├── pipes.img
├── pstree.img
├── reg-files.img
├── remap-fpath.img
├── route6-9.img
├── route-9.img
├── rule-9.img
├── seccomp.img
├── sigacts-101.img
├── sigacts-113.img
├── sigacts-122.img
├── sigacts-183.img
├── sigacts-1.img
├── sigacts-245.img
├── sigacts-246.img
├── sigacts-50.img
├── sigacts-52.img
├── sigacts-95.img
├── sigacts-96.img
├── sigacts-97.img
├── sigacts-98.img
├── signalfd.img
├── stats-dump
├── timerfd.img
├── tmpfs-dev-104.tar.gz.img
├── tmpfs-dev-109.tar.gz.img
├── tmpfs-dev-110.tar.gz.img
├── tmpfs-dev-112.tar.gz.img
├── tmpfs-dev-114.tar.gz.img
├── tty.info
├── unixsk.img
├── userns-13.img
└── utsns-11.img

0 directories, 154 files
```

この場合、コンテナのリストはとても簡単です：

```
stgraber@dakara:~$ lxc start c1
```


### ライブマイグレーション

ライブマイグレーションも基本的にステートフルな起動・停止と同じです。異なるのは、コンテナのディレクトリと設定が他のマシンに移動するということです。

```
stgraber@dakara:~$ lxc list c1
+------+---------+-----------------------+----------------------------------------------+------------+-----------+
| NAME |  STATE  |          IPV4         |                     IPV6                     |    TYPE    | SNAPSHOTS |
+------+---------+-----------------------+----------------------------------------------+------------+-----------+
| c1   | RUNNING | 10.178.150.197 (eth0) | 2001:470:b368:4242:216:3eff:fe19:27b0 (eth0) | PERSISTENT | 2         |
+------+---------+-----------------------+----------------------------------------------+------------+-----------+

stgraber@dakara:~$ lxc list s-tollana:
+------+-------+------+------+------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+------+-------+------+------+------+-----------+

stgraber@dakara:~$ lxc move c1 s-tollana:

stgraber@dakara:~$ lxc list c1
+------+-------+------+------+------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+------+-------+------+------+------+-----------+

stgraber@dakara:~$ lxc list s-tollana:
+------+---------+-----------------------+----------------------------------------------+------------+-----------+
| NAME |  STATE  |          IPV4         |                     IPV6                     |    TYPE    | SNAPSHOTS |
+------+---------+-----------------------+----------------------------------------------+------------+-----------+
| c1   | RUNNING | 10.178.150.197 (eth0) | 2001:470:b368:4242:216:3eff:fe19:27b0 (eth0) | PERSISTENT | 2         |
+------+---------+-----------------------+----------------------------------------------+------------+-----------+
```

## 制限事項

前述したように、コンテナのチェックポイント・リストア機能はまだ導入されたばかりで、現在はこの機能に間するさまざまな対応や発覚した問題の修正を行っている状態です。より多くの人にこの機能を利用してもらい、フィードバックを送ってもらう必要があります。今はまだ、プロダクションでは利用しないことをおすすめします。

現在わかっている問題点は[Launchpad](https://bugs.launchpad.net/ubuntu/+source/criu/+bugs)上にリストアップしています。

Ubuntu 16.04上でいくつかのサービスが動いている基本的なUbuntuコンテナであれば、CRIUはうまく動くものと思います。しかしながらより複雑なコンテナや、デバイスパススルーの利用、複雑なネットワークサービスや特別なストレージ設定の場合は、おそらく動かないでしょう。

可能な限り、CRIUはリストア時ではなくダンプ時に失敗するようにしています。この場合、ソースとなるコンテナは動作したままとなり、単純にスナップショットやマイグレーションが失敗し、デバッグ用にログファイルに記録されるだけです。

レアケースとして、CRIUはコンテナのリストア時に失敗することがあります。この場合、ソースコンテナはまだ存在しますが、おそらく停止状態になっているので、手動で再起動する必要があるでしょう。


## 不具合報告

チェックポイント・リストアに関連する不具合はLaunchpadのCRIUパッケージ上で管理しています。これらの不具合の対応のほとんどは、CRIU自身かLinuxカーネルの上流で対応していますが、この方法の方が問題を追跡しやすいのです。

新しい不具合は、[ここから](https://launchpad.net/ubuntu/+source/criu/+filebug?no-redirect)報告してください。

その際は、次の情報も含めるようにしてください：

* 実行しようとしたコマンドと表示されたエラーメッセージ
* 「`lxc info`」の結果（＊）
* 「`lxc info <コンテナ名>`」の結果
* 「`lxc config show --expanded <コンテナ名>`」の結果
* 「`dmesg`」の結果（＊）
* 「`/proc/self/mountinfo`」の内容（＊）
* 「`lxc exec <コンテナ名> -- cat /proc/self/mountinfo`」の結果
* 「`uname -a`」の結果（＊）
* `/var/log/lxd.log`ファイル（＊）
* `/etc/default/lxd-bridge`ファイル（＊）
* `/var/log/lxd/<コンテナ名>/`のアーカイブ（＊）

もしステートフルスナップショットやステートフルストップの不具合ではなくマイグレーションの不具合を報告するのであれば、上記のリストで「（＊）」とマークがついているものについては、ソースとターゲット両方のデータを送るようにしてください。


## その他の情報

* CRIUのウェブサイト：[https://criu.org/](https://criu.org/)

* LXDのウェブサイト：[https://linuxcontainers.org/ja/lxd/](https://linuxcontainers.org/ja/lxd/)
* 開発はGitHub上で行なっています：[https://github.com/lxc/lxd](https://github.com/lxc/lxd)
* メーリングリスト：[https://lists.linuxcontainers.org](https://lists.linuxcontainers.org)
* IRCチャンネル：#lxcontainers on irc.freenode.net
* LXDをオンラインで試したい場合：[https://linuxcontainers.org/ja/lxd/try-it/](https://linuxcontainers.org/ja/lxd/try-it/)