今回からはいよいよLXCの話題です。まずは開発の歴史と現在の開発体制を少し紹介したあと、LXC自身が持つ特徴を紹介したいと思います。
LXCの歴史
LXCはLinuxカーネルにコンテナ関連の機能が実装されはじめた2008年頃から、当時IBMフランスのDaniel Lezcano氏を中心にして、カーネルの機能を使用してコンテナの操作を行うためのツールとして開発がはじまっています。当時の文書を読むと、カーネルに実装されたコンテナ関連の機能をカーネル開発者が簡単に試せるようにすることを目的としていたようです。
その後、開発はかなり活発に行われ2009年にはバージョンは0.6に達しています。筆者が初めてLXCを使い始めたのは2009年の年末で0.6.4の頃です。この頃にはすでに簡単にコンテナの起動や管理ができていました。この後はAppArmorのサポートのようにセキュアにコンテナを使用するための機能など、実用に向けた機能が徐々に実装されていきました。
2012年にリリースされたUbuntu 12.04 LTSではUniverseリポジトリですがLXCパッケージが含まれており、この頃にはかなり安定して実用的にコンテナが扱えるツールに成長していました。この年にリリースされた0.8.0で、2008年から開発が進められたLXCとしてはほぼ完成の域に達していたと言えるかもしれません。Ubuntu 12.04 LTSに含まれるLXCは0.7.5ですが、0.8.0の新機能がバックポートされており、実質0.8.0と言っても良い機能を持っています。
この頃までのLXCは、主要機能を扱うコマンドはC言語で実装されていましたが、周辺の管理コマンド等はLinuxに通常含まれているコマンドのラッパーとして実装されているシェルスクリプトだったりしました。手間をかけずにあるものをうまく工夫して使っている所があり、必要最低限の機能が実装されているものの、少し寄せ集め感がありましたし、コマンドによっては柔軟な使い方ができないこともありました。
2013年9月にはDaniel Lezcano氏が多忙のため、メンテナがこの頃実質的に開発を引っ張っていたSerge Hallyn氏とStéphane Graber氏に交代し、開発もGitHub上で行われるようになりました[1]。両氏ともにCanonical社のエンジニアですので、この頃から開発はUbuntuを中心に行われていくようになりました。
この後0.9.0の頃からAPIの整備が始まり、その後も1.0を安定版としてUbuntu 14.04 LTSに入れることを目標にAPIの整備が進められました。各種コマンドはそのAPIを使用して一貫性を持つ実装になり、APIを使った各種言語のバインディングも整備されていきました。
1.0の開発はリリース直前までかなり激しく機能が追加されていました。それでも無事2014年の2月20日にリリースされ、4月にリリースされたUbuntu 14.04 LTSでは目玉となる新機能のひとつとしてLXC 1.0が含まれました。
以上のようにUbuntuを中心にして開発が進んでいるため、Ubuntu以外で動かすときは問題があるのではないかと心配される方もいらっしゃるかもしれません。しかし、アクティブな開発者の中にはOracleのエンジニアやFedora上で開発をしている開発者もいますので、Ubuntu以外のディストリビューションでも問題なく動きますし、問題がある場合でもすぐに修正がされます。
LXCの特徴
通常はLXCの特徴というとコンテナが持つ特徴をあげることが多いです。しかしそれは第2回ですでに紹介していますので、ここではLXC自身の特徴をいくつか紹介したいと思います。
豊富なテンプレート
コンテナを使用する際は、仮想マシンの時のようにCD、DVD、ISOイメージなどを用いて一からインストールできません。コンテナが起動したときの/(ルート)以下のディレクトリツリー(以降、コンテナイメージ)を作り、起動に必要な設定を行うのは少し面倒です。またコンテナとして起動させるために設定ファイルのカスタマイズが必要な場合もあります。
そこでLXCにはコンテナを作成するためのスクリプトとしてテンプレートが付属しています。テンプレートを使うと、簡単にコンテナイメージを作成し、コンテナの起動に必要な変更を行い、設定ファイルを作成できます。このテンプレートはコンテナを作成するためのlxc-create
コマンドから直接使えます。
各種ディストリビューションに対応したテンプレートは、そのテンプレートと同じディストリビューション上で動かすのが基本ですが、DebianやUbuntuのように多数のパッケージが準備されているディストリビューションだと、rpmやyumのパッケージをインストールしてFedoraやCentOSのコンテナを作成できます。
ディストリビューション用のテンプレートだけでなく、アプリケーションコンテナとしてsshdやbusyboxを起動させるためのテンプレートも付属しています。
テンプレートは全てシェルスクリプトで書かれていますので簡単にカスタマイズできます。実際、LXC 1.0に含まれているlxc-plamoというテンプレートは、筆者がubuntu用のテンプレートなどの他のテンプレートを真似しながら作ったものをマージしてもらいました。
1.0に標準で含まれるテンプレートは以下の17個です。
テンプレートの中も少し紹介しておきましょう。以下は17個のうちで一番シンプルなlxc-sshdテンプレートの一部です。ご覧のようにシェルスクリプトで書かれていますし、sshdを起動するのに必要なファイルを作成したりしているだけで、複雑なことをしているわけでもありませんので、これを見ながらカスタマイズを行うのもそれほど難しくはありません。
イメージのダウンロード
テンプレートには、手元でコンテナイメージを作成するためのもの以外にlxc-download
という名前のテンプレートが付属しており、あらかじめ構築されたコンテナイメージをLXCのサイトからダウンロードしてコンテナを作成できます。
この機能は1.0リリース前に準備されました。あとで紹介する一般ユーザでコンテナの利用する場合は、テンプレートを使ってコンテナイメージの作成が難しいためです。もちろんroot権限でコンテナを利用する場合も利用できます。
このコンテナイメージは、LXCに付属しているテンプレートを使って定期的にLXCのサーバ上で構築されていますので、各種ディストリビューションのテンプレートを使って作成した場合と同じイメージが、手元のホスト環境で使用しているディストリビューションに関わらず使用できます。
Dockerではあらかじめ作成したイメージが提供されており、それを利用してコンテナを起動します。LXCでもダウンロード用のテンプレートを使ってそれと同じことができます。
執筆時点で準備されているダウンロード用のイメージは以下の通りです。
ディストリビューション | バージョン | アーキテクチャ | バリアント |
CentOS | 6 | amd64 i386 | default |
7 | amd64 | default |
Debian | jessie sid wheezy | amd64 armel armhf i386 | default |
Fedora | 19 20 | amd64 armhf i386 | default |
Gentoo | current | amd64 armhf i386 | default |
openSUSE | 12.3 | amd64 i386 | default |
Oracle | 6.5 | amd64 i386 | default |
Plamo | 5.x | amd64 i386 | default mini |
Ubuntu | lucid | amd64 i386 | default |
precise | amd64 armel armhf i386 | default |
trusty utopic | amd64 arm64 armhf i386 ppc64el | default |
「バリアント」とは
ディストリビューションによってはコンテナイメージ内に含まれるパッケージが異なる複数のイメージが準備されていることがあります。このイメージごとに名前が付けられており、これを「バリアント」と呼んでいます。ダウンロードテンプレートのオプションとして与えることができます。デフォルトでは "default" というバリアントが使われます。
APIと各種言語のバインディングの提供
LXCにはlxc-
で始まるコンテナ用のコマンドが付属しています。これらは全てLXCライブラリのAPI(liblxc1)を使用して作られており、一部は後述のスクリプト言語のバインディングで書かれています。
このAPIを使って自分でアプリケーション内からコンテナが操作できます。また、このAPIを使用した各種言語のバインディングが提供されていますので、以下の言語からコンテナが操作できます。
このうち、Python3とLuaはLXCのソースに同梱されており、GoとRubyは別に配布されています。なおLXCのGoバインディングは、Go言語で書かれたDockerとは全く無関係です。また、最近githubのLXCプロジェクトにPython 2.7用のリポジトリができていました[2]。
LXCでインストールされるコマンドのいくつかはPython3とLuaで書かれています。
- Python3で書かれているコマンド
- lxc-device, lxc-ls, lxc-start-ephemeral
- Luaで書かれているコマンド
- lxc-top
いろいろなストレージバックエンドのサポート
ストレージバックエンドは、LXCのマニュアルでは"backingstore"として説明されており、コンテナイメージの置き場として使う領域の形式です。デフォルトではファイルシステム上のディレクトリが使われますが、ここにさまざまなファイルシステムやデバイスを使い、それぞれの特徴を活かして管理もできます。
1.0でサポートされているストレージバックエンドは以下です。
- ディレクトリ (デフォルト)
- btrfs
- zfs
- lvm
- ループデバイス
- aufs
- overlayfs
作成時やクローン、スナップショットの時にストレージバックエンドを指定すると、それぞれのストレージバックエンドに応じた処理がなされます。たとえばコンテナ用の領域としてbtrfsの領域を準備してコンテナを作成すると、コンテナ専用のsubvolumeが作成され、そこにコンテナイメージを作成します。
またlvmを使用する場合、その上に作成するファイルシステムは自由に選べますので、ここにないファイルシステムも使えます。
クローンとスナップショット
テンプレートを使ってコンテナを新規に作成するのでなく、既にあるコンテナをクローンして作成できます。デフォルトではrsyncを使ってコピーされます。
btrfsやzfsやlvmのような多機能なストレージバックエンドを使っている場合は、そのファイルシステム実装されているスナップショット機能を使ったりして、ストレージバックエンドの特徴を活かしたクローンが可能です。
通常のディレクトリを使用している場合でも、カーネルがサポートしていれば、aufsやoverlayfsと言った重ね合わせが可能なファイルシステムを使い、容量を節約したり、差分管理を行ったりできます。
また、あるコンテナの状態をスナップショットとして保存できます。クローンと違ってスナップショットは取得元のコンテナに紐付いた状態になり、コンテナをスナップショット時点のものにリストアできます。
セキュリティ
コンテナごとの隔離がされていない部分などに対するセキュリティの確保や、コンテナを安全に使用するための機能としてAppArmor、SELinuxがサポートされています。
また、seccompを使ってシステムコールのフィルタがコンテナごとに行えますし、コンテナごとに与えたり削除したりするケーパビリティを指定できます。
一般ユーザでのコンテナの起動
第2回で説明したユーザ名前空間を使った一般ユーザでのコンテナの作成と起動が可能です。
root権限で実行するコンテナと全く同じことが一般ユーザでできるわけではありませんが、ホスト環境や他のコンテナに対してはセキュアになりますし、root権限を持たない一般ユーザでもコンテナの起動ができることで、利用の幅が大きく広がるのではないでしょうか。
ネストしたコンテナ
コンテナのネストが可能です。つまりLXCで作成し起動したコンテナの中でコンテナが動作します。
日本語マニュアルの付属
これは機能ではありませんし、JM Projectの成果としてLinuxの基本的なコマンドは日本語のオンラインマニュアルが提供されているので、マニュアルが日本語で読めるからといって珍しいことでもないのですが、筆者が貢献した成果なのでぜひ紹介させてください。(^_^)
LXC 1.0からは日本語のオンラインマニュアルが付属していますので、日本語環境では日本語でマニュアルが読めます。現時点で英語以外の言語でマニュアルがあるのは日本語だけです[4]。
LXCの気になる点
LXCの改良すべき点はたくさんあると思います。しかし、こんな短所があるからLXCが使いづらい!という点は筆者はあまり思いつきません。
短所は思いつきませんが気になる点はあります。現時点で筆者が一番気になる所はcgroupの設定です。
コンテナに対してcgroupでリソース制限をかける場合、第4回、第5回で一部説明した、各サブシステムの設定を行うcgroupfs以下のファイル名や、ファイルに書き込むべき内容をそのまま設定ファイルに書くことになります。
たとえばdevicesサブシステムの場合、devices.allow
とdevices.deny
というファイルに許可したいデバイス用のアクセス権を設定しました。これをLXCで設定すると以下のようになります。
lxc.cgroup
に続いて、cgroupfsにできるファイル名をそのまま続けて設定のキーとしています。値はそのファイルに書き込む設定そのままです。
カーネルのバージョンやディストリビューションの設定によってcgroupfs以下に現れるファイルが異なることもあります。細かくコンテナのリソース制御を行いたい場合にはcgroupの知識が必要なことに加えて、使っているカーネルのcgroupを設定する知識も必要になる可能性があります。これは少し敷居が高い気がします。
この辺りを改善する提案はでていましたので、バージョン1.1が出る頃にはもう少し簡単にリソース制限が行えるようになっているかもしれません。
まとめ
今回はLXC開発の歴史について紹介したあと、LXC自身の持つ特徴をいくつか紹介しました。コンテナという仕組みが持つ以外のLXCが持つ特徴についておわかりいただけたのではないかと思います。
次回からは今回紹介した特徴の説明も含めて、LXCの機能を実際に紹介していく予定です。機能の紹介はUbuntu 14.04 LTS上で行っていきたいと思いますので、Ubuntuに依存したLXC環境の話も含めて説明していく予定です。
Ubuntuを使った基本的な機能の紹介が済んだ後に、Ubuntu以外のディストリビューションでのLXCの構築や活用のお話をする予定です。
最近のLXCのリリース
第4回の記事を執筆中にLXC 1.0.4がリリースされ(6月13日)、前回(第6回)の記事を執筆中にLXC 1.0.5がリリースされています(7月14日)。
1.0系列は仕様は変わらずバグフィックスのみ行う方針ですので、細かいバグフィックスが中心ですが、1.0.4ではsystemdベースのディストリビューションでの問題を解決するために若干仕様が変わっていたり、1.0.4, 1.0.5の両方で、まだまだ変化しているLinuxカーネルの仕様に合わせるために内部的な動きを変更したりしています。
一方で次のバージョンとなる1.1の話もメーリングリストでは話題にのぼりはじめました。
1.0系列の各バージョンでの変更点については日本語サイトでも翻訳して紹介していますのでご覧ください。