LXCで学ぶコンテナ入門 -軽量仮想化環境を実現する技術

第7回 LXCの歴史と特徴

この記事を読むのに必要な時間:およそ 5.5 分

イメージのダウンロード

テンプレートには,手元でコンテナイメージを作成するためのもの以外にlxc-downloadという名前のテンプレートが付属しており,あらかじめ構築されたコンテナイメージをLXCのサイトからダウンロードしてコンテナを作成できます。

この機能は1.0リリース前に準備されました。あとで紹介する一般ユーザでコンテナの利用する場合は,テンプレートを使ってコンテナイメージの作成が難しいためです。もちろんroot権限でコンテナを利用する場合も利用できます。

このコンテナイメージは,LXCに付属しているテンプレートを使って定期的にLXCのサーバ上で構築されていますので,各種ディストリビューションのテンプレートを使って作成した場合と同じイメージが,手元のホスト環境で使用しているディストリビューションに関わらず使用できます。

Dockerではあらかじめ作成したイメージが提供されており,それを利用してコンテナを起動します。LXCでもダウンロード用のテンプレートを使ってそれと同じことができます。

執筆時点で準備されているダウンロード用のイメージは以下の通りです。

ディストリビューションバージョンアーキテクチャバリアント
CentOS6amd64 i386default
7amd64default
Debianjessie sid wheezyamd64 armel armhf i386default
Fedora19 20amd64 armhf i386default
Gentoocurrentamd64 armhf i386default
openSUSE12.3amd64 i386default
Oracle6.5amd64 i386default
Plamo5.xamd64 i386default mini
Ubuntulucidamd64 i386default
preciseamd64 armel armhf i386default
trusty utopicamd64 arm64 armhf i386 ppc64eldefault
「バリアント」とは

ディストリビューションによってはコンテナイメージ内に含まれるパッケージが異なる複数のイメージが準備されていることがあります。このイメージごとに名前が付けられており,これを「バリアント」と呼んでいます。ダウンロードテンプレートのオプションとして与えることができます。デフォルトでは "default" というバリアントが使われます。

APIと各種言語のバインディングの提供

LXCにはlxc-で始まるコンテナ用のコマンドが付属しています。これらは全てLXCライブラリのAPI(liblxc1)を使用して作られており,一部は後述のスクリプト言語のバインディングで書かれています。

このAPIを使って自分でアプリケーション内からコンテナが操作できます。また,このAPIを使用した各種言語のバインディングが提供されていますので,以下の言語からコンテナが操作できます。

  • Python3
  • Lua
  • Go
  • Ruby

このうち,Python3とLuaはLXCのソースに同梱されており,GoとRubyは別に配布されています。なおLXCのGoバインディングは,Go言語で書かれたDockerとは全く無関係です。また,最近githubのLXCプロジェクトにPython 2.7用のリポジトリができていました※2)⁠

※2)
その後,公式ページにはバインディングとしてHaskellが追加されました。ただしlxc公式リポジトリ外の配布です。

LXCでインストールされるコマンドのいくつかはPython3とLuaで書かれています。

Python3で書かれているコマンド
lxc-device, lxc-ls, lxc-start-ephemeral
Luaで書かれているコマンド
lxc-top
※3)
バージョン1.1からlxc-deviceとlxc-topはCで書かれるようになりました。ソースには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)⁠

※4)
その後韓国語マニュアルがマージされました。次のバージョンには韓国語マニュアルが付属するでしょう。

LXCの気になる点

LXCの改良すべき点はたくさんあると思います。しかし,こんな短所があるからLXCが使いづらい!という点は筆者はあまり思いつきません。

短所は思いつきませんが気になる点はあります。現時点で筆者が一番気になる所はcgroupの設定です。

コンテナに対してcgroupでリソース制限をかける場合,第4回第5回で一部説明した,各サブシステムの設定を行うcgroupfs以下のファイル名や,ファイルに書き込むべき内容をそのまま設定ファイルに書くことになります。

たとえばdevicesサブシステムの場合,devices.allowdevices.denyというファイルに許可したいデバイス用のアクセス権を設定しました。これをLXCで設定すると以下のようになります。

$ cat /usr/share/lxc/config/ubuntu.common.conf
  : (略)
# Default cgroup limits
lxc.cgroup.devices.deny = a
## Allow any mknod (but not using the node)
lxc.cgroup.devices.allow = c *:* m
lxc.cgroup.devices.allow = b *:* m
## /dev/null and zero
lxc.cgroup.devices.allow = c 1:3 rwm
lxc.cgroup.devices.allow = c 1:5 rwm
  : (略)

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系列の各バージョンでの変更点については日本語サイトでも翻訳して紹介していますのでご覧ください。

著者プロフィール

加藤泰文(かとうやすふみ)

2009年頃にLinuxカーネルのcgroup機能に興味を持って以来,Linuxのコンテナ関連の最新情報を追っかけたり,コンテナの勉強会を開いたりして勉強しています。英語力のない自分用にLXCのmanページを日本語訳していたところ,あっさり本家にマージされてしまい,それ以来日本語訳のパッチを送り続けています。

Plamo Linuxメンテナ

Twitter:@ten_forward
技術系のブログ:http://tenforward.hatenablog.com/