インフィニットループ 技術ブログ

2015年05月14日 (木)

著者 : mizuno_as

Ubuntu 15.04とLXDではじめるコンテナ型仮想化

こんにちは、mizuno_asです。
2015年4月23日、UbuntuチームはUbuntu 15.04 Vivid Vervetをリリースしました。このリリースから、UniverseリポジトリにコンテナハイパーバイザーであるLinux Container Daemon(LXD)が含まれるようになりました。それではさっそくUbuntu 15.04とLXD 0.7を使って、お手軽なコンテナ環境の構築を試してみましょう。

Photo by Philippe PutCC BY 2.0

LXDってなんだろう?

Linuxカーネルが持つ機能を利用して実現されるコンテナのことをLinux Container(LXC)と呼ぶのはご存じの通りです。それとは別に、コンテナを扱うためのユーザー空間インターフェイスとして、同名のLXCというソフトウェアが存在します ((ややこしいですね!)) 。このLXCの作者でもあるStéphane Graberによって開発された「コンテナハイパーバイザー」がLXDです。LXDは、ホスト上で動作するコンテナ全体を管理するデーモンとして動作するソフトウェアです。ストアしたイメージから素早くコンテナを展開したり ((Vagrantのboxをイメージするといいかもしれません。)) 、ネットワーク越しに複数のLXDホストを扱うことも可能になっています ((そのためのREST APIを備えています。)) 。
……と言われてもピンとこないかもしれませんね。なにはともあれ、動かしてみることにしましょう。

LXDのインストール

Ubuntu 15.04にlxdパッケージをインストールします。この時点でlxdというグループが作成され、ユーザーがグループに追加されます。LXDを利用するにはグループに所属している必要がありますので、一度ログアウトしてログインし直しておきましょう。

$ sudo apt-get install lxd

インストールしただけでは、lxdデーモンは起動していません。systemctlコマンドでサービスを起動します ((Ubuntuは15.04からinitにsystemdを利用するようになりました。)) 。

$ sudo systemctl start lxd.service

list-unit-filesを見るとわかるように、lxd.serviceはdisabledになっています。このままではシステムを再起動するとLXDが停止してしまいますので、システム起動時に自動起動するようにもしておきましょう。

$ systemctl list-unit-files
lxc-net.service                        enabled
lxc.service                            enabled
lxcfs.service                          enabled
lxd.service                            disabled
$ sudo systemctl enable lxd.service
Synchronizing state for lxd.service with sysvinit using update-rc.d...
Executing /usr/sbin/update-rc.d lxd defaults
Executing /usr/sbin/update-rc.d lxd enable

イメージのインポート

それではコンテナのイメージをダウンロードしてLXDにインポートしましょう。LXDのコマンドラインインターフェイスはlxcというコマンドです ((例によってややこしいですね……。)) 。linuxcontainers.orgから公開されているイメージをダウンロードしてlxc image importコマンドでインポートするとよいでしょう。ですがこの作業はlxd-imagesというPython製のフロントエンドを使えば簡単に済ますことができます。以下の例はUbuntu 14.04(trusty)の64bit版をtrustyという名前でインポートする、という意味で、イメージのダウンロード、署名の検証、インポートまでを自動的に行ってくれます。

$ lxd-images import lxc ubuntu trusty amd64 --alias trusty

lxc image listコマンドを実行すると、インポート済みのイメージ一覧を得ることができます。

$ lxc image list
+--------+--------------+--------+-------------+--------+------------------------------+
| ALIAS  | FINGERPRINT  | PUBLIC | DESCRIPTION |  ARCH  |         UPLOAD DATE          |
+--------+--------------+--------+-------------+--------+------------------------------+
| trusty | e04d2a4bed59 | no     |             | x86_64 | May 11, 2015 at 6:40pm (JST) |
+--------+--------------+--------+-------------+--------+------------------------------+

イメージにはみんな大好きCentOS 6もありますよ。

$ lxd-images import lxc centos 6 amd64 --alias centos/6
$ lxc image list
+----------+--------------+--------+-------------+--------+------------------------------+
|  ALIAS   | FINGERPRINT  | PUBLIC | DESCRIPTION |  ARCH  |         UPLOAD DATE          |
+----------+--------------+--------+-------------+--------+------------------------------+
| trusty   | e04d2a4bed59 | no     |             | x86_64 | May 11, 2015 at 6:40pm (JST) |
| centos/6 | e62ba8829de0 | no     |             | x86_64 | May 11, 2015 at 6:45pm (JST) |
+----------+--------------+--------+-------------+--------+------------------------------+

せっかくなので、最新のCentOS 7も使いたいですよね。しかし実行すると、以下のようにイメージが存在しないと言われてしまいます。linuxcontainers.orgを見るとイメージ自体は存在するのに、なぜでしょうか?

$ lxd-images import lxc centos 7 amd64 --alias centos/7
Downloading the GPG key for https://images.linuxcontainers.org
Downloading the image list for https://images.linuxcontainers.org
Validating the GPG signature of /tmp/tmphfrlcl40/index.json.asc
Requested image doesn't exist.

lxd-iamgesコマンドは、内部でインデックスを見て、イメージが存在するかどうかをチェックしています。(理由はわかりませんが)イメージ自体は存在するのに、インデックスが更新されていないのが悪いようです。そういう時はlxd-imagesを使わず、手動でインポートしてみましょう。wgetコマンドなどでイメージをダウンロードして、tar.xzをlxc image importコマンドに食わせてみます。

$ lxc image import lxd.tar.xz --alias centos/7
Image imported with fingerprint: b140ade8feef81826b0dbbf0f1f68894fb2c7335d714103da4910106f5c2dc1e
$ lxc image list
+----------+--------------+--------+-------------+--------+------------------------------+
|  ALIAS   | FINGERPRINT  | PUBLIC | DESCRIPTION |  ARCH  |         UPLOAD DATE          |
+----------+--------------+--------+-------------+--------+------------------------------+
| centos/7 | b140ade8feef | no     |             | x86_64 | May 11, 2015 at 7:01pm (JST) |
| trusty   | e04d2a4bed59 | no     |             | x86_64 | May 11, 2015 at 6:40pm (JST) |
| centos/6 | e62ba8829de0 | no     |             | x86_64 | May 11, 2015 at 6:45pm (JST) |
+----------+--------------+--------+-------------+--------+------------------------------+

インポートできました!

コンテナを起動する

コンテナの起動にはlxc launchコマンドを使います。引数にはコンテナの作成に使うイメージの名前と、起動後のコンテナにつける個別の名前を指定します。

$ lxc launch trusty trusty-test
Creating container...done
Starting container...done

lxc listコマンドでは、起動中のコンテナの一覧を見ることができます。

$ lxc list
+-------------+---------+------------+------+-----------+
|    NAME     |  STATE  |    IPV4    | IPV6 | EPHEMERAL |
+-------------+---------+------------+------+-----------+
| trusty-test | RUNNING | 10.0.3.225 |      | NO        |
+-------------+---------+------------+------+-----------+

コンテナにはIPアドレスが振られていますが、まだSSHサーバーが起動していないため、SSHで接続することができません。そこでroot権限のシェルを直接取ることにします。コンテナ内でプロセスを起動するにはlxc execコマンドを使います。ここではtrusty-testコンテナの中でbashを起動しています。これでコンテナ内でroot権限でシェルを起動することができました。

$ lxc exec trusty-test bash
root@trusty-test:~#

プロファイルでコンテナをカスタマイズする

LXDから起動するコンテナは、プロファイルを使って構成をカスタマイズすることができます。デフォルトでdefaultというプロファイルが用意されており、その中身は以下のように、eth0というNICがひとつだけ登録されています。

$ lxc config profile show default
eth0: nic

ためしにtestというプロファイルを作成し、NICをふたつ搭載したコンテナを作ってみましょう。lxc config profile createでプロファイルを作成し、lxc config profile device addでプロファイルにデバイスを追加します。名前はeth0とeth1で、それぞれホストのlxcbr0にブリッジする設定です。

$ lxc config profile create test
$ lxc config profile device add test eth0 nic nictype=bridged parent=lxcbr0
$ lxc config profile device add test eth1 nic nictype=bridged parent=lxcbr0
$ lxc config profile show test
eth0: nic
eth1: nic

コンテナを起動する際、-pオプションでプロファイル名を指定して起動します。

$ lxc launch trusty nic-test -p test

これで仮想的なNICがふたつ接続された状態でコンテナが起動しました。次にコンテナ内のOSにふたつ目のNICの設定を追加します。/etc/network/interfacesにeth1の設定を追加してあげましょう。

$ cat /etc/network/interfaces
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet dhcp
auto eth1
iface eth1 inet dhcp

コンテナを再起動してみると、このようにふたつのIPアドレスが振られていることが確認できました。

$ lxc list
+-------------+---------+----------------------+------+-----------+
|    NAME     |  STATE  |         IPV4         | IPV6 | EPHEMERAL |
+-------------+---------+----------------------+------+-----------+
| trusty-test | RUNNING | 10.0.3.225           |      | NO        |
| nic-test    | RUNNING | 10.0.3.19, 10.0.3.34 |      | NO        |
+-------------+---------+----------------------+------+-----------+

他にもプロファイルでは、使用するCPUコア数やメモリ量を制限することも可能なようです。詳しくはマニュアルを参照してください。

Ephemeralコンテナを使う

LXD 0.7から、Ephemeralコンテナと呼ばれる機能が実装されました。通常のコンテナはシャットダウン、もしくはlxc stopコマンドで停止状態にすることができますが、Ephemeralコンテナは停止すると即削除される、揮発性のコンテナです。Ephemeralなコンテナを起動するには、lxc launchコマンドに-eオプションをつけて実行します。

$ lxc launch centos/7 centos7 -e
$ lxc list
+-------------+---------+------------+------+-----------+
|    NAME     |  STATE  |    IPV4    | IPV6 | EPHEMERAL |
+-------------+---------+------------+------+-----------+
| trusty-test | RUNNING | 10.0.3.225 |      | NO        |
| nic-test    | STOPPED |            |      | NO        |
| centos7     | RUNNING |            |      | YES       |
+-------------+---------+------------+------+-----------+

この状態でcentos7コンテナ ((EPHEMERALのカラムに注目してください!)) を停止させてみます。

$ lxc list
+-------------+---------+------------+------+-----------+
|    NAME     |  STATE  |    IPV4    | IPV6 | EPHEMERAL |
+-------------+---------+------------+------+-----------+
| trusty-test | RUNNING | 10.0.3.225 |      | NO        |
| nic-test    | STOPPED |            |      | NO        |
+-------------+---------+------------+------+-----------+

このように、centos7コンテナはSTOPPED状態にならず、即リストから削除されました。環境を使い捨てたい時に利用するといいかもしれませんね。

LXD 0.8.1を使う

LXDはUbuntu向けに最新版をPPAで公開しています ((なお一昨日、0.9.0が公開されたようです。)) 。ここではUbuntu 15.04はもちろん、Ubuntu 14.04 LTS向けにもパッケージが公開されていますので、LTS上で最新のLXDを試すこともできそうですね ((筆者は試していませんが……)) 。
LXDは昨年11月に開発がアナウンスされたばかりの非常に若いプロダクトですが、これからの動向に注目していきたいですね。手元のコンテナ管理のお供に、ぜひ一度試してみてはいかがでしょうか?

ブログ記事検索

このブログについて

このブログは、札幌市・仙台市の「株式会社インフィニットループ」が運営する技術ブログです。 お仕事で使えるITネタを社員たちが発信します!