検索
連載

軽量仮想化機能「chroot」と「jail」FreeBSDのコレ知ってる?(2)(2/2 ページ)

現在主流の仮想化技術は、ハードウェアをソフトウェアで仮想化する方法を採用していますが、そこまで仮想化する必要がないケースもあります。そんな時に便利な2つのリソース・コンパートメント機能を紹介します。(編集部)

Share
Tweet
LINE
Hatena
前のページへ |       

chroot(2)とよく似ているjail(2)の利用手順

 chroot(2)のアプローチを推し進めて、ファイルシステムの名前空間のみならず、ほかのリソースについても隔離できるようにした機能がFreeBSDのjail(2)だ。操作にはjail(8)コマンドjexec(8)jls(8)などを使用する。

 隔離環境の作り方はchroot(8)の場合と同じだ。例えば次のようにすれば、現在の環境から隔離された環境を作ることができる。

# mkdir -p /jail/a
# cp -Rp /bin /sbin /lib /libexec /usr /var /etc /jail/a/
# mkdir /jail/a/dev
# mount -t devfs devfs /jail/a/dev

 jail(8)コマンドは次のように使用する。この使い方で「chroot /jail/a /bin/sh」に相当している。

 jail -c name=a path=/jail/a command=/bin/sh

 現在どの程度のjailが作成されているかはjls(8)コマンドで確認できる。

$ jls 
   JID  IP Address      Hostname                      Path
     2  -                                             /jail/a
$ 

 ちなみに隔離空間は現在のシステムからコピーしなくても、make buildworld installworldで次のようにオプションを指定することで実施することもできる。

# /usr/src
# make buildworld
# make DESTDIR=/jail/b installworld

ファイルシステムの名前空間以外も隔離できるjail

 さて、それではjail(2)がchroot(2)とはどう違うのかを調べてみよう。まず、ps(1)の出力の違いを調べてみる。

# ps
  PID  TT  STAT    TIME COMMAND
 1021  v0  Is   0:00.00 login [pam] (login)
 1029  v0  I+   0:00.03 -csh (csh)
 1022  v1  Is+  0:00.00 /usr/libexec/getty Pc ttyv1
 1023  v2  Is+  0:00.00 /usr/libexec/getty Pc ttyv2
 1024  v3  Is+  0:00.00 /usr/libexec/getty Pc ttyv3
 1025  v4  Is+  0:00.00 /usr/libexec/getty Pc ttyv4
 1026  v5  Is+  0:00.00 /usr/libexec/getty Pc ttyv5
 1027  v6  Is+  0:00.00 /usr/libexec/getty Pc ttyv6
 1028  v7  Is+  0:00.00 /usr/libexec/getty Pc ttyv7
 1132   0  I    0:00.00 su -l
 1133   0  S    0:00.02 -su (csh)
 1188   0  R+   0:00.00 ps
# jail -c name=a path=/jail/a command=/bin/sh
# ps
  PID  TT  STAT    TIME COMMAND
 1189   0  SJ   0:00.00 /bin/sh
 1190   0  R+J  0:00.00 ps
# 

 jailの内部に入ると、外部のプロセスが見えなくなっていることが確認できる。jail(2)はプロセスリストを隔離しており、jail以外のプロセスが見られなくなる。見えなくなるだけでなく、操作の対象とすることもできない。

 試しにkill(1)を実行しても、そのようなプロセスは存在しないというエラーが返ってくる。

# kill 1024
kill: 1024: No such process
#

 ただし、プロセスリストを隔離しただけで、プロセス番号はシステムにおいて唯一であることに注意しておきたい。つまり、init(8)は必ずプロセス番号1として最初に起動されるから、プロセス番号1のinit(8)がjailの中に現れることは絶対になく、プロセス番号1がjailの中から見えることも絶対にないということになる。あくまでも隔離して仮想化されたように振る舞っているのであって、実際に動作しているカーネルは1つである。

 rootの権限も一部降格となる。特に外部にアクセスするために使用できるシステムコールの権限が降格となり、さまざまな違いが現れる。

 例えばdf(1)の出力の違いを比べてみる。jailに入る前は見えていたパーティション/マウント情報が、jailの内部から見えなくなっていることが分かる。

# df
Filesystem  1K-blocks    Used     Avail Capacity  Mounted on
/dev/ada0p2 127975772 3342736 114394976     3%    /
devfs               1       1         0   100%    /dev
devfs               1       1         0   100%    /jail/a/dev
# jail -c name=a path=/jail/a command=/bin/sh
# df
Filesystem  1K-blocks    Used     Avail Capacity  Mounted on
/dev/ada0p2 127975772 3342736 114394976     3%    /
#

 jailの内部からはmount(8)コマンドを実行することもできない。

# mkdir dev2
# mount -t devfs devfs /dev2
mount: devfs : Operation not permitted
#

 jail(2)は基本的にプロセスを特定の隔離空間に閉じ込めるものだが、プロセスがない状態でもjailを作って保持しておくといったこともできる。また、システム起動時に自動的にjailが動作するようにするには、/etc/rc.confに次のような設定を追加しておけばよい。この場合、service jail startやservice jail stopでjail環境の有効、無効を切り替えることができる。

# jail
jail_enable="YES"
jail_list="a"
jail_a_devfs_enable="YES"
jail_a_rootdir="/jail/a"
jail_a_hostname="a.jail.example.org"
jail_a_interface="em0"
jail_a_ip="192.168.1.201"
jail_a="/bin/sh /etc/rc"

 ただしjailを運用する場合、jail内部の/etc/rc.confの設定をよく考えておく方がよい。

 例えば、時刻を設定するシステムコールsettimeofday(2)はjail内部では実行できないため、時刻を調整するコマンドが実行されないようにcron(8)を無効にするなり、該当するサービスをcron(8)経由で実行されないようにしておかないと、エラーメッセージが定期的にメールで送られてくるという面倒な事態になる。

 FreeBSDのホスティングサービスを提供しているベンダは、実際にはjailで隔離空間を構築し、サービスを提供していることが多い。この方法は軽量で高速であり、1台のマシンに何中、何百というjailを構築して運用できるという特徴がある。前回紹介したRACCT/RCTL rctl(8)でリソースを制御すれば、そのままサービスとして提供できるレベルということになる。

さらに隔離機能の強化が進むjail

 FreeBSD jailはネットワークインターフェイスを別途割り当てる。

 また、まだデフォルトでは有効になっていないが、それぞれのjailが独立したネットワークスタックを持てるようにする機能も追加されている。VIMAGEのカーネルオプションを追加してカーネルを再構築し、「jail -c vnet」でjailを作成すると、ネットワークスタックも独立するようになる。この機能を使うと、1つのマシン内に複数のネットワークを構築できるようになる。エンタープライズレベルのルータなどが実装している機能だ。

 FreeBSDのjailは今後も個別リソースの隔離機能を進め、機能強化していく方向にある。今後もFreeBSDを特徴づける機能であり続ける見通しだ。ほかの仮想化技術と比較した場合のjailの特徴は、何といっても軽量さと高速さにあり、活用できれば費用対効果で優れた結果を期待できる。

 chroot(2)はだいぶ古い機能だし、jail(2)もFreeBSDを特徴づける機能だが、最近になって仮想化機能を扱うようになった方は、こうした隔離機能を知らない方も多いのではないかと思い、今回はこの機能を紹介した。便利で面白い機能なので、ぜひ一度使ってみてほしい。

Profile

後藤 大地

後藤 大地

BSDコンサルティング株式会社 取締役、オングス代表取締役。@ITへの寄稿、MYCOMジャーナルにおけるニュース執筆のほか、アプリケーション開発やシステム構築、『改訂第二版 FreeBSDビギナーズバイブル』『D言語パーフェクトガイド』『UNIX本格マスター 基礎編〜Linux&FreeBSDを使いこなすための第一歩〜』など著書多数。


Index

連載:FreeBSDのコレ知ってる?

 第2回 軽量仮想化機能「chroot」と「jail」

Page 1
 非ハイパーバイザ型の仮想化機能
 リソース・コンパートメント(資源隔離)による仮想化
 chroot(8)で使うファイルを用意
 名前空間を隔離して上のパスへのアクセスを制限

Page 2
 chroot(2)とよく似ているjail(2)の利用手順
 ファイルシステムの名前空間以外も隔離できるjail
 さらに隔離機能の強化が進むjail


Copyright © ITmedia, Inc. All Rights Reserved.

前のページへ |       
ページトップに戻る