15分で分かるLXC(Linux Containers)の仕組みと基本的な使い方

 最近注目されている仮想化技術の1つにLXC(Linux Containers)がある。LXCはコンテナ型仮想化技術と呼ばれるものの1つで、OS上に別の隔離された環境を構築するものだ。今回はLXCの仕組みと、基本的なインストールについて紹介する。

さまざまな仮想化技術とLXC

 仮想化技術を使って一台のマシン上に複数の隔離された環境を構築する、というのはメインフレームの世界では古くから行われていたが、近年ではマシンの性能向上により、エントリレベルのサーバーでもこのような使われ方が実用的になっている。そういった背景の下注目されているのがLXC(Linux Container)と呼ばれる仮想化技術だ。

 広く使われている仮想化技術としてはXenやKVMがあるが、これらはホストOS(もしくはハイパーバイザ)上で演算によって仮想的なマシン環境を作り出し、その上でOSを実行させることで複数のOS環境の構築を可能にしている(図1)。

図1 Xen/KVMによる仮想化
図1 Xen/KVMによる仮想化

 この場合、ホストOSとは異なるOSを仮装マシン上で実行できる、ホストOSとゲストOSを完全に分離できる、といったメリットがあるが、ハードウェアを演算によってシミュレートするため、そのためのオーバーヘッドが必要になるというデメリットもある。

 いっぽうLXCはXenやKVMといった仮想化技術とは異なり、仮想マシンを作り出すのではなく、OSが利用するリソースを隔離することで複数の環境を並立させることを可能にしている(図2)。

図2 LXCによる仮想化
図2 LXCによる仮想化

 この方式ではハードウェアをシミュレートする必要がないため、仮想化によるオーバーヘッドはほぼ存在しない。また、仮想マシンのブートやシャットダウンという概念も存在しないため、仮想環境の立ち上げや停止を高速に実行できる。さらに、仮想マシン上で実行されている環境上でも利用できるというメリットもある。

LXCはどのように実装されているのか

 LXCと似た技術として、「chroot」というものが存在する。chrootはプロセスのルートディレクトリを変更するもので、これによってプロセスがアクセスできるディレクトリを制限したり、システムが通常使用するライブラリとは異なるライブラリを読み込ませることが可能になる。ただし、chrootで制御できるのはファイルやディレクトリに対するアクセスのみで、ネットワークやプロセスなどについてはコントロールできない。

 また、FreeBSDにはchrootを発展させた機構として「jail」と呼ばれる機能が搭載されている。jailではファイルシステムに対するアクセスだけでなく、プロセスやデバイスといったリソースについても制御が可能になっている。LXCはこのjailと同様の考え方で実装されたもので、Linuxカーネル2.6.24より搭載された「cgroups」と呼ばれるリソース管理機構を用いて実装されている。

 cgroupsは、OSが管理するさまざまなリソースを一元的に制御するための機構だ。リソースをグループ化し、グループごとに優先度や利用できるリソースを制限したり、グループを隔離して他のグループからは不可視にする、といった機能を提供する。

 cgroupsで管理できるのはファイルシステムやプロセスに加え、CPUリソースやメモリ、各種デバイス、ネットワークパケット、ネットワークインターフェイスなど多岐に渡る。cgroupsの利用例としては特定のプロセスが利用できるメモリ量やCPU時間などを制限する、といったものがあるが、LXCではプロセスに対しchrootのように特定のディレクトリをルートディレクトリと認識させ、かつcgroupsの名前空間機能を使って各種リソースを隔離することで、仮想的な環境の構築を実現している(図3)。

図3 cgroupsによるリソースのグルーピング
図3 cgroupsによるリソースのグルーピング

 なお、cgroupsについてはRed Hatの日本語ドキュメントが詳しいので、より詳しくその機能を知りたい方はそちらを参照してほしい。

LXCを利用する際の注意点

 LXCはcgroupsの機能を使って各種リソースを隔離することで独立した環境を提供している。そのため、CPUやハードウェア固有の機能を必要としない。XenやKVMといった仮想化技術にって作成された仮想マシン上での動作も可能だ。

 また、LXCで作られた仮想環境はホスト環境から完全に隔離された状態になり、仮想環境からホスト環境のリソースに直接アクセスすることはできない。ただし、注意が必要なのはroot権限の扱いだ。コンテナ内でroot権限で実行されているプロセスは、ホスト環境内のroot権限を持つことになる。ただし、この問題を解決するための仕組みも開発されており、LXC 1.0ではコンテナ内のrootユーザーをコンテナ外では別のユーザーとして扱う仕組み(非特権コンテナ)が実装されている。これにはカーネル側でのサポートも必要であるため、環境によっては利用できないこともあるので注意したい。

LXC 1.0のインストール

 LXCは比較的新しいソフトウェアであるため、公式パッケージとしては提供されていないディストリビューションもあるほか、パッケージが提供されていてもそのバージョンが古い、といった場合がある。LXCはバージョン1.0で大幅に機能が強化・改善されているため、可能な限りバージョン1.0以降のものを利用することをおすすめする。

Red Hat Enterprise Linuxやその互換ディストリビューションの場合

 Red Hat Enterprise Linux(RHEL)の最新版であるRHEL 6.5では、LXCは公式パッケージとしては提供されていない。また、Fedora Projectが公開しているRHEL向けの追加パッケージ集であるEPELではLXCのパッケージが提供されているものの、そのバージョンは0.9.0とやや古い。そのため、最新のLXCを利用したい場合、EPEL以外のサードパーティのリポジトリを利用するか、ソースコードからビルドしてインストールすることになる。

 ソースコードからビルドする場合、LXCが配布しているソースアーカイブにはRPMパッケージを作成するためのSPECファイルと呼ばれる設定ファイルが含まれているので、これを利用すると簡単にRPMパッケージを作成できる。この際、ビルドに必要なGCCなどの開発ツールや、RPM作成ツールである「rpm-build」パッケージが必要となる。なお、作業の流れとしては以下のようになる。

$ tar xvzf lxc-1.0.3.tar.gz 
$ mkdir ~/rpmbuild/SPECS
$ cp lxc-1.0.3/lxc.spec ~/rpmbuild/SPECS/
$ mkdir ~/rpmbuild/SOURCES
$ cp lxc-1.0.3.tar.gz ~/rpmbuild/SOURCES/
$ rpmbuild -bb ~/rpmbuild/SPECS/lxc.spec
$ cd ~/rpmbuild/RPMS/x86_64
$ rpm -Ivh lxc-1.0.3-1.el6.x86_64.rpm lxc-libs-1.0.3-1.el6.x86_64.rpm

 なお、RPMパッケージの作成について詳しくはカスタムRPMや独自yumリポジトリではじめるソフトウェア管理術で解説しているので、そちらを参照してほしい。

 また、この方法で作成したLXCのRPMパッケージは「docbook2X」というパッケージを必要とする。このパッケージは標準パッケージとしては提供されていないものの、EPELでは提供されているので、そちらを利用してインストールしておこう。EPELを利用していない場合、以下のようにして「epel-relese」パッケージをインストールすることでEPELを有効化できる。

# rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm

 さらに、CentOS上でLXCを利用する場合、libvirtおよびcgconfigが必要となることがある。事前に以下のようにしてそれぞれのデーモンを起動させておこう。

# service libvirtd start
# service cgconfig start

Debian/Ubuntuの場合

 Ubuntuの最新版であるUbuntu 14.04 LTS(Trusty Tahr)では、LXC 1.0.3が「lxc」というパッケージ名で提供されているため、こちらを利用するれば良い。また、Debianの場合は次期版であり現在テスト段階の「jessie」でLXC 1.0.3のパッケージが提供されている。

 それ以前のバージョンのDebianもしくはUbuntuを利用している場合で最新版のLXCを利用したい場合、ソースコードからビルドしてインストールする形となる。LXCのビルドは一般的な、いわゆる「configure、make、make install」という手順で行える。

LXCを使った仮想環境を立ち上げる

 LXCの各種機能は、「lxc-<機能名>」というコマンドを使って操作できる。たとえばコンテナを作成するには「lxc-create」コマンドを、コンテナを起動するには「lxc-start」コマンドを使用する。

 LXCを使って仮想環境を立ち上げるには、「テンプレート」と呼ばれる設定ファイルが必要だ。LXCにはさまざまなテンプレートが同梱されており、デフォルトでは/usr/share/lxc/templatesディレクトリにインストールされる。

$ ls /usr/share/lxc/templates/
lxc-alpine     lxc-centos    lxc-fedora        lxc-oracle  lxc-ubuntu-cloud
lxc-altlinux   lxc-cirros    lxc-gentoo        lxc-plamo
lxc-archlinux  lxc-debian    lxc-openmandriva  lxc-sshd
lxc-busybox    lxc-download  lxc-opensuse      lxc-ubuntu

 これらのテンプレートを指定してlxc-createコマンドを実行すると、そのテンプレートに応じた環境を含むコンテナが作成される、という仕組みだ。LXC 1.0系ではCentOSやFedora、Debian、Ubuntuといった人気Linuxディストリビューション環境を作成する「lxc-centos」や「lxc-fedora」、「lxc-debian」、「lxc-ubuntu」といったテンプレートだけでなく、最低限の機能だけを持つbusybox環境を作成する「lxc-busybox」や、ホストOSと同一かつ隔離された環境を作成する「lxc-sshd」テンプレートといったものも用意されている。

 たとえばCentOS環境を構築するlxc-centosテンプレートを使って「centos-test01」という名前のコンテナを作成する場合、以下のようになる。

# lxc-create -t centos -n centos-test01

 このコマンドを実行すると、最低限のCentOS環境構築に必要なパッケージが自動的にダウンロードされ、コンテナのrootディレクトリに相当するディレクトリにインストールされて環境が作成される。また、このとき下記のようにコンテナ内環境のrootパスワードが/var/lib/lxc/centos-test01/tmp_root_passというファイルに格納されている旨も表示される。このファイルをチェックし、rootパスワードを確認しておこう。

The temporary root password is stored in:

        '/var/lib/lxc/centos-test01/tmp_root_pass'

 作成した「centos-test01」コンテナを起動するには、以下のようにlxc-startコマンドを使用する。

# lxc-start -n centos-test01 -d

 なお、「-d」オプションはコンテナをデーモンとして実行するオプションだ。このオプションを指定しないと、lxc-startを実行したコンソールをコンテナが専有してしまい、コンテナを終了させるまでシェルに戻れない。そのため、通常はこのように「-d」オプション付きでコンテナを立ち上げ、「lxc-console」コマンドでコンソールに接続することをおすすめする。

 lxc-consoleコマンドは、指定したコンテナのコンソールに接続するコマンドだ。たとえば「centos-test01」コンテナのコンソールに接続するには以下のようにする。

# lxc-console -n centos-test01

 また、コンソールから抜けるには、キーボードで「Ctrl-A」を入力したのち、「Q」を押せば良い。

 起動しているコンテナを終了するには、コンテナ内でshutdownコマンドを実行する、もしくはlxc-stopコマンドを実行すれば良い。

# lxc-stop -n centos-test01

LXCの特徴の1つはカスタマイズ性の高さと起動/終了の速さ

 さて、こうしてLXCを使ってみると、KVMやXen、VMwareといった仮想化技術と比べ、仮想環境の作成や起動、終了が速いことに気付くだろう。LXCを使った仮想環境ではカーネルが共有されるため、新たにカーネルを立ち上げる必要は無く、ハードウェアの初期化などの操作が不要であるためだ。必要となるメモリもコンテナ内で動作するプロセスのものだけなので、低スペックの環境でも利用しやすい。仮想環境内でも動作するため、VPSなどでも導入しやすいだろう。

次回予告

 今回はコンテナの作成と起動/停止までの解説を行ったが、次回はlxc-sshdやlxc-busyboxを使った最小環境の利用、そしてコンテナのカスタマイズといった活用法を紹介する。