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