最近自分の周りでDockerの話しか聞かなくて、寂しくなってきたので書いてみました(笑)
以前LXCの非特権コンテナをマイグレーションする記事は書いたのですが、コンテナを止めてtarで固めて移行先で展開するという原始的なものでした。
LXCの非特権コンテナを別ホストに移行する - くろの雑記帳
LXDの登場により、マイグレーション自体コマンド一発でできるようになりましたし、さらに条件付きでライブマイグレーションもできるようになったのでその紹介です。
LXDって?
一言でいうと、
LXD はコンテナの『ハイパーバイザ』であり、LXC の新しいユーザ体験です。
Linux Containers - LXD - イントロダクション
ということですが、もう少し詳しく言うと、 LXDがLinuxコンテナ(LXC)を管理するシステム全体のデーモンとして動いてくれて、REST APIを提供してくれます。
また、コマンドラインインターフェイスとしてlxc
というコマンドが用意されています。
環境構築
今回はサーバを2台使います。同じ構成で、
- Ubuntu Server 15.04
- CPU 1コア
- Mem 1GB
- Disk 8GB
です。
ホスト名はそれぞれ、ip-172-31-29-89
とip-172-31-29-90
です。ユーザ名はubuntu
にしました。
インストール
2台とも同じように構築してください。
LXDのインストール
# 開発が活発なので、最新版を使います $ sudo apt-add-repository -y ppa:ubuntu-lxc/daily $ sudo apt-add-repository -y ppa:ubuntu-lxc/lxd-git-master $ sudo aptitude update # lxdをインストール $ sudo aptitude install lxd
liblxcがlxcfsを使ってのライブマイグレーションをまだサポートしていないらしいので、lxcfsをアンインストールします。
Live Migration in LXD | Ubuntu Insights
$ sudo aptitude remove lxcfs
ここまで行ったあと、一旦ログアウトしてログインしなおします。ubuntuユーザがlxdグループに追加されるはずです。
criuをインストール
動いているコンテナを状態を保存して止めるためには、checkpoint/restart機能を提供してくれるcriu
が必要です。
プロセスの状態をファイルに保存して、それを展開する事でプロセスを再開することができます。
$ sudo aptitude install criu
extraカーネルをインストール
netlink_diag
というモジュールがないとライブマイグレーションできないようなのですが、入っていなかったので、extraカーネルイメージをインストールしました。
以下のコマンドで、netlink_diag.ko
が存在していれば、この手順は必要ありません。
$ ls -l /lib/modules/{今使用しているカーネルバージョン}-generic/kernel/net/netlink
なければインストールします。バージョンは使用しているカーネルに合わせてください。
$ sudo aptitude install linux-image-extra-3.19.0-25-generic
設定
パスワード
ホスト同士がrest apiで通信するのでパスワードを設定します。それぞれ、hogehoge
とfugafuga
にしました。
以前はset password
だったような気がするのですが、set core.trust_password
になっていました。
# ip-172-31-29-89 ubuntu@ip-172-31-29-89:~$ lxc config set core.trust_password hogehoge # ip-172-31-29-90 ubuntu@ip-172-31-29-90:~$ lxc config set core.trust_password fugafuga
リモートの追加
それぞれのサーバで、自身ともう一方をリモートとして登録します。パスワードは先ほど設定したものです。
# ip-172-31-29-89 ubuntu@ip-172-31-29-89:~$ lxc remote add ip-172-31-29-90 ip-172-31-29-90 Certificate fingerprint: 06 f0 4d fe f1 60 6a 45 d9 6f bb 4a 65 c7 7f 15 6b 97 21 28 73 6d 86 b7 e2 e8 33 df 65 d1 0b c0 ok (y/n)? y Admin password for ip-172-31-29-90: fugafuga Client certificate stored at server: ip-172-31-29-90 ubuntu@ip-172-31-29-89:~$ lxc remote add ip-172-31-29-89 ip-172-31-29-89 Certificate fingerprint: 56 df 86 39 94 89 fd fe 9a b5 e3 7f 5b 94 4a cb ba 80 f0 94 f9 e9 f2 6c a7 cd 2c 78 b3 9c 35 fc ok (y/n)? y Admin password for ip-172-31-29-89: hogehoge Client certificate stored at server: ip-172-31-29-89 # ip-172-31-29-90 ubuntu@ip-172-31-29-90:~$ lxc remote add ip-172-31-29-90 ip-172-31-29-90 Admin password for ip-172-31-29-90: fugafuga Certificate fingerprint: 06 f0 4d fe f1 60 6a 45 d9 6f bb 4a 65 c7 7f 15 6b 97 21 28 73 6d 86 b7 e2 e8 33 df 65 d1 0b c0 ok (y/n)? y Client certificate stored at server: ip-172-31-29-90 ubuntu@ip-172-31-29-90:~$ lxc remote add ip-172-31-29-89 ip-172-31-29-89 Certificate fingerprint: 56 df 86 39 94 89 fd fe 9a b5 e3 7f 5b 94 4a cb ba 80 f0 94 f9 e9 f2 6c a7 cd 2c 78 b3 9c 35 fc ok (y/n)? y Admin password for ip-172-31-29-89: hogehoge Client certificate stored at server: ip-172-31-29-89
リモートが追加されたか確認してみます。
ubuntu@ip-172-31-29-90:~$ lxc remote list ip-172-31-29-89 <https://ip-172-31-29-89:8443> ip-172-31-29-90 <https://ip-172-31-29-90:8443> local <unix:///var/lib/lxd/unix.socket>
ライブマイグレーション用profile作成
プロファイルを作ります。以下のコマンドを入れると、エディタが立ち上がるので編集します。copyできるので片側のサーバで設定すればOKです。
デフォルトは非特権コンテナなのですが、ライブマイグレーションがまだサポートされていないので、特権コンテナで起動するように設定します。
$ ubuntu@ip-172-31-29-89:~$ lxc profile copy default criu $ ubuntu@ip-172-31-29-89:~$ lxc profile edit criu
name: criu config: raw.lxc: | lxc.console = none lxc.cgroup.devices.deny = c 5:1 rwm lxc.start.auto = lxc.start.auto = proc:mixed sys:mixed security.privileged: "true" devices: {}
作ったプロファイルをもう一方のホストにもコピーする必要があるため、以下のコマンドを打ちます。
ubuntu@ip-172-31-29-89:~$ lxc profile copy ip-172-31-29-89:criu ip-172-31-29-90:criu
コンテナを作る
ip-172-31-29-89
からip-172-31-29-90
へマイグレーションしようと思うので、ip-172-31-29-89
にだけコンテナを作ります。
イメージ取得
ubuntuのコンテナイメージを取得します。(最初の一回だけ必要です)
ubuntu@ip-172-31-29-89:~$ lxd-images import lxc ubuntu trusty amd64 --alias ubuntu
コンテナ生成
container01という名前のコンテナを作ります。
ubuntu@ip-172-31-29-89:~$ lxc init ubuntu container01
コンテナにプロファイルを設定します。
ubuntu@ip-172-31-29-89:~$ lxc profile apply container01 default,criu
Profile default,criu applied to container01
コンテナを起動する
ubuntu@ip-172-31-29-89:~$ lxc start container01 ubuntu@ip-172-31-29-89:~$ lxc list +-------------+---------+------+------+-----------+-----------+ | NAME | STATE | IPV4 | IPV6 | EPHEMERAL | SNAPSHOTS | +-------------+---------+------+------+-----------+-----------+ | container01 | RUNNING | | | NO | 0 | +-------------+---------+------+------+-----------+-----------+
IPV4の項目が空だった場合は、ホスト側でdnsmasqが動いているので、DHCPでアドレスを取得します。
ubuntu@ip-172-31-29-89:~$ lxc exec container01 dhclient
コンテナをライブマイグレーションする!
ようやくという感じがしますが、ここまで準備したらあとはコマンド一発打つだけでライブマイグレーションできちゃいます。
移行前のホストで確認
ubuntu@ip-172-31-29-89:~$ lxc list +-------------+---------+------------+------+-----------+-----------+ | NAME | STATE | IPV4 | IPV6 | EPHEMERAL | SNAPSHOTS | +-------------+---------+------------+------+-----------+-----------+ | container01 | RUNNING | 10.0.3.187 | | NO | 0 | +-------------+---------+------------+------+-----------+-----------+
ip-172-31-29-89
からip-172-31-29-90
へマイグレーションを実行!
ubuntu@ip-172-31-29-89:~$ lxc move ip-172-31-29-89:container01 ip-172-31-29-90:container01 # コマンドが終わるまで(15秒くらい)待つ
ubuntu@ip-172-31-29-89:~$ lxc list
+------+-------+------+------+-----------+-----------+
| NAME | STATE | IPV4 | IPV6 | EPHEMERAL | SNAPSHOTS |
+------+-------+------+------+-----------+-----------+
+------+-------+------+------+-----------+-----------+
ip-172-31-29-89
からは先ほどのコンテナは消えてしまいました。では、ip-172-31-29-90
の方はというと…?
ubuntu@ip-172-31-29-90:~$ lxc list +-------------+---------+------------+------+-----------+-----------+ | NAME | STATE | IPV4 | IPV6 | EPHEMERAL | SNAPSHOTS | +-------------+---------+------------+------+-----------+-----------+ | container01 | RUNNING | 10.0.3.187 | | NO | 0 | +-------------+---------+------------+------+-----------+-----------+
無事マイグレーションされています!
その他
LXDでコンテナのライブマイグレーションに成功したのですが、実際のダウンタイムはどれくらいなんだろう?と思って、コンテナのnicをNATのネットワークではなく、ブリッジに接続し、外部からpingを打ち続けてみたのですが、pingの応答がなかったのは3秒くらいでした。
ただし、コンテナと通信を頻繁に行ったり、ディスクに書き込みをしている状態でマイグレーションをしようとすると、リソースのロックに失敗して、マイグレーションが失敗してしまいました。
失敗の仕方も、マイグレーションせず元の状態で動き続けたり、コンテナが停止してしまったりと不安定で、色々制約もありますので、実用レベルとは言えません。
コンテナを停止してからのマイグレーションは特別なプロファイルの設定も要りませんし、特に問題ありませんでした。LXDの開発は活発なようなので、今後も期待です!