Masatomo Nakano Archives
前回に引き続き、今回はFreeBSDのJailの簡単な説明と、実際にどのような感じで使えるのか、簡単なサンプルを交え紹介します。
「プログラマのための」について
前回書き忘れてしまったのですが、なぜ「プログラマのための」というのをタイトルに入れたかというと、
- プログラマは自分の開発環境/テスト環境の構築ぐらい自分ですべし
- でも、環境構築に時間をかけすぎるのはプログラマとしては本末転倒だよね
この二つをあっさりと解決してくれるのがFreeBSDのJailだと感じているからです。
それと、自分自身そこそこ長いことプログラマをやってますが、Jailは自分にとってなかなか衝撃的だった、というのもこのエントリを書くきっかけになっているというのもあります。
FreeBSDのJailとは
さて、まず基本的なFreeBSDのJailについて簡単に触れておきます。
FreeBSDのJailは仮想環境の一つの実装です。仮想環境にも色々ありますがJailはその中でもとてもシンプルな物です。一つの物理的なサーバ上で動いている一つのFreeBSD(以下Jailホスト)の上で、複数のFreeBSD(以下Jailゲスト)が動いているように見えるようにする仕組です。「見えるようにする」だけというのがポイントで、実際にはJailホスト上のカーネルの上ですべてのプロセスが動いているだけです。
また、Jailとchrootを同じようなもの、と考えている人もいるようですが、chrootがファイルシステムだけが対象なのに対し、Jailはファイルシステムに加えネットワークやプロセスといったものも管理下になるのが違います。Jailゲスト一つが独立したIP addressを持ちます。
外からネットワーク越しに見ると、Jailゲストは一つのFreeBSD OSのように見えます。しかし、実際には、Jailホスト上の1つのカーネルで、Jailゲスト上のすべてのプロセスが動いています。このことは、Jailホスト上のカーネルからJailゲスト上の各プロセスを普通にpsやtopコマンド等で確認することができます。
また、この仕組みがそのままいくつかのJail自体の制限になります。たとえば、違うバージョンのFreeBSDや、違うOSを仮想環境として入れるといったVMWareやXenといった他の仮想環境でできることができません。そして、(今のところ)各Jailゲストで動くプロセスに対してリソースの割当や制限をすることができません。ですので一つのJailゲストがリソースを食い過ぎてしまうと他のJailゲストに大きく影響を与えます。この辺は将来的には何かできるようになるかも、という話です。
実際に動いている環境での例を示します。

これは、実際に弊社で稼働中のJailホストでtopした結果です。”j”を押すと左から2列目にJID (Jail ID)というものが表示されます。これはそのプロセスがどのJailゲストで動いているかということを示します。このようにJailホストからは、Jailゲストのプロセスが普通に見ることができますし、またJailホスト上からJailゲストのプロセスのkillなどは普通にできます。
では、その中の一つのJailゲストに入り、同じようにtopコマンドを実行してみます。すると、以下のようにそのJailゲストのプロセスのみが表示されます。

このJailゲストはPostgreSQL用のものなのでPostgreSQLに関連するプロセスとcronなどの基本的なプロセスだけが走っているのがわかります。Jailゲストの中からは、他のJailゲストやJailホストの情報は見えません。これはプロセスだけではなくてファイルシステムなどもそうです。
とてもシンプルです。そして、シンプルなだけにに仮想環境を動かすこと自体のオーバヘッドが少なく、無駄なく一台のハードウェアの資源を使うことができます。また9年前にリリースされたFreeBSD 4.0Rからの機能なので安定度も非常に高いです。
資源という面では、Jailゲスト同士でFreeBSDのユーザランド部分をファイルレベルで共有するのでディスクスペースもそれほど無駄になりません。どう作るかにもよりますが、大雑把に言うと、/etc, /usr/local, /var あたりはJailゲスト毎ですが、/usr 以下は共有されます。また、もちろんパッケージからインストールしたものはJail毎になります。これにより資源を節約できるだけなく、Jailゲストの数をたくさん増やしたとしてもFreeBSDとしてのベース部分のメンテナンスは1カ所で済むのも楽なところです。
また、Jailゲストで使うファイルもJailホストと同じファイルシステム上にあるので、簡単に直感的に扱うことができます。例えば、あるJailゲスト上で「/etc/pam.d/systemを壊してしまって、仮想環境に入れなくなってしまった」というトラブルが起きたとします。Jailホスト上から見ると、このファイルは、/foo/bar/jails/hogehoge.example.com/etc/pam.d/system にあります。Jailホストにとっても普通のファイルなのでお使いのエディタで簡単に修復できます。
Jailの導入
Jail自体はFreeBSDに標準で組み込まれているのですが、その他にいくつか設定が必要です。また、Jail単体だと管理が大変なので、packageまたはportsから管理ツールであるsysutils/ezjailも導入してください。
さて、普通ならここでJailシステムのインストールの仕方等を紹介するべきなのかもしれませんが、ちょっと大変だし、世の中にあるものより劣化したドキュメントを垂れ流すだけになりそうなので、どこか適当な情報を探してください。
また、Jail自体についてはこの辺が詳しいです。
Jailを使用した運用例
以下の例ではJailの管理ツールであるezjailを使っています。私はezjailができる前のJail事情を知らないのですが、その時代は色々と大変だったみたいです。
例1: Jailの新規作成
Jailゲストを新しく作ります。JailゲストはFQDNをディレクトリ名として作成され、その下がそのJailゲストの/(root)ディレクトリになります。
$ sudo ezjail-admin create newjail.example.com 192.168.4.25
/usr/local/jails/newjail.example.com/./bin/usr/local/jails/newjail.example.com/./boot
/usr/local/jails/newjail.example.com/./dev
/usr/local/jails/newjail.example.com/./etc
/usr/local/jails/newjail.example.com/./etc/X11
/usr/local/jails/newjail.example.com/./etc/bluetooth
/usr/local/jails/newjail.example.com/./etc/bluetooth/hcsecd.conf
/usr/local/jails/newjail.example.com/./etc/bluetooth/hosts
/usr/local/jails/newjail.example.com/./etc/bluetooth/protocols
/usr/local/jails/newjail.example.com/./etc/defaults
(中略)
/usr/local/jails/newjail.example.com/./.cshrc
/usr/local/jails/newjail.example.com/./COPYRIGHT
/usr/local/jails/newjail.example.com/./basejail
この例では、192.168.4.25 というIP addressがこのJailゲストに設定されます。(Jailホスト側にも192.168.4.25というIP addressをaliasとしてふる必要もあります。)
作成したJailゲストを起動してみます。
$ sudo ezjail-admin start newjail.example.com
Configuring jails:.
Starting jails: newjail.example.com.
Consoleに入ります。
$ sudo ezjail-admin console newjail.example.com
Copyright (c) 1992-2009 The FreeBSD Project.
Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994
The Regents of the University of California. All rights reserved.
FreeBSD 7.2-STABLE (GENERIC) #0: Fri Aug 7 20:52:37 BST 2009
Welcome to FreeBSD!
(中略)
You may also use sysinstall(8) to re-enter the installation and
configuration utility. Edit /etc/motd to change this login announcement.
newjail#
ここれでJailゲストが一つ作成され起動しました。newjail# のプロンプトが表示され、この以下の操作はJailゲストの仮想環境内の操作になります。この中からは他のJailゲストやJailホストの情報は全く見えません。この先は普通のFreeBSDと同じように好きなようにパッケージを入れたり設定したりできます。もちろんsshdを起動すれば外から直接newjailに入ってこれます。
このようにコマンド2、3個、所要時間1分未満で簡単に1つの仮想環境を作成することができます。
例2: Jailゲストのコピー
似たような環境を作るときにいちいち0から設定するのは大変です。こういうときは既にあるJailを簡単にコピーできます。
先ほど作成したnewjailをコピーし、newjail2を作成してみましょう。
いったんnewjailを停止。
$ sudo ezjail-admin stop newjail.example.com
コピー
$ sudo cp -a /usr/local/jails/newjail.example.com /usr/local/jails/newjail2.example.com
単純なファイルコピーなので、rsyncでもtarでもお好きなものでどうぞ。(パーミッションとかに気をつけて)
コピーしたファイルを元にnewjail2を作成します。(すでにあるファイルを使う場合は-xをつける)
$ sudo ezjail-admin create -x newjail2.example.com 192.168.4.26
これで、完了です。
先ほどと同じようにコンソールに入りコピーされていることを確認します。(起動していない場合にはconsoleコマンドでstartもします。)
$ sudo ezjail-admin console newjail2.example.com
Configuring jails:.
Starting jails: cms3-build.uk.reallyenglish.com.
Copyright (c) 1992-2009 The FreeBSD Project.
Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994
The Regents of the University of California. All rights reserved.
FreeBSD 7.2-STABLE (GENERIC) #0: Fri Aug 7 20:52:37 BST 2009
Welcome to FreeBSD!
(中略)
You may also use sysinstall(8) to re-enter the installation and
configuration utility. Edit /etc/motd to change this login announcement.
newjail2#
これでコピーされたJailゲストが動きだしました。
ファイルのコピーにかかる時間は、もちろんその中のファイルの量によるので何とも言えませんが、実作業時間はこちらも数分といったところでしょう。
同じようなやり方で複数のJailホスト間でJailゲストをコピー(または、元のを消せば移動)することもできます。この場合コピー先のJailホストは同一のアーキテクチャのサーバ、同一のFreeBSDのバージョンのものにしておいた方が無難です。
今回のまとめ
とにかくJailは簡単です。よほど深いことをするのでない限りJail自体の知識はあまり必要となりません。普通のUNIX的な知識とFreeBSD的な知識があれば普段使いとしては十分です。
個人的な経験では、他の仮想環境はメンテナンス含め色々と手間がかかります。気づいたら動くなくなってた仮想環境というのも目にします。またメモリやディスクスペースのオーバヘッドも大きいので簡単にいくつも作ったりもできません。Jailはそういう意味でもとても軽いし堅いです。もし何らかの理由で動かなくなったとしても、上記で説明したようにとてもシンプルなのでわりと簡単に修復できますし、仮想環境の中のファイルを外から取り出すのも簡単です。
次回はもう少しだけ運用のTipsなどを紹介して最後にしたいと思っています。
それでは!
reallyenglishでは、開発環境、また一部のプロダクション環境でFreeBSDのJail機能を使っています。このJailを使うことによりシンプルで柔軟な開発環境が構築できます。
“FreeBSD”と聞いて、「ああ、関係ないや」と思われた方へ。
ちょっとだけでも読んでみてください。JailのためだけでもFreeBSDを導入する価値があると思っています。もし、FreeBSDの導入が無理だとしても考え方自体は他のFreeBSDのJail以外の仮想環境でも使えるはずです。
前提
Webシステム開発ではたくさんのサーバソフトウェアが必要です。システムの中心部であるPHPやRuby On Railsといったアプリケーションサーバや、データを格納するデータベースサーバは最低限必要でしょう。またロードバランサやメールサーバといったものも必要なることもあります。
また開発時にはGitやSubversionのようなSCMや、コミュニケーションのためのIRCサーバなども必要かもしれません。同じような環境を開発者やテスター毎、開発拠点毎に設置する必要があることも珍しくないでしょう。さらに、一つのWebアプリケーションでも、プロダクション用や、開発用と複数のバージョンを持ちつつ同時に開発するのもよくあることです。
さらに、予算やスペースの関係で、プロダクションサーバでは多くの物理的なサーバで行っていることを開発環境では少ない台数のサーバで賄わないといけない、ということもよくあることでしょう。
そのような様々なことから、ちょっとしたWebサービスの開発でも、かなりの複雑な環境が必要になることがわかります。
そう言った複雑な環築をなるべくシンプルに構築するためにreallyenglishではFreeBSDのJailを使用した仮想環境を使っています。
基本的な方針
まず、基本的な方針として、1サービス=1仮想環境にします。これはプロダクション環境でも、開発環境でも同じです。つまり、Apacheでも、PostgreSQLでも、Memcacheでも、Postfixでも、Gitでも、とにかくサーバ的なものは必ず一つの仮想環境にしてしまいます。
つまり「このサービスは軽いから、他のサービスと同じところで動かしちゃおう」的なことをやめました。何か新しく必要になったら、仮想環境を新規で作成しそこにインストールします。ちょっとした実験的なサービスを入れる場合でも同じです。「Nginx試したい。じゃー、Jail作ってそこでやろう。」と言った感じです。
また、同じサービスでも、用途が違えば別に仮想環境を作ります。例えば、Apache等のWebサーバはVirtual Host機能を使うことにより1つのWebサーバを複数の用途として使えますが、そういうこともやめました。
狙いは2つです。
- 設定をシンプルにする。一つのサーバで、あれもこれもしようとすると、どうしても設定ファイルが複雑にいなってしまいます。1サービス1Jailとすると必然的に設定はかなりシンプルになります。また、設定をシンプルにすることでPuppetと言ったツールも導入しやすくなります。
- ハードウェアとサービス、サービス間を疎結合にする。粗結合にしておくと色々なことがとてもフレキシブルになります。例えば、一つのサービスの負荷が非常に高くなり他のサービスに影響を与え始めた。こういう場合、別のハードウェアを用意し、そのサービスだけ移動する、と言ったことがよく行われます。このときに1サービス = 1 仮想環境ならその仮想環境をコピー(移動)するだけで完了します。同一のネットワーク内で移動するだけなら、仮想環境のIP addressの付け替えさえ必要ありません。
いちいち仮想環境を作る。というのは一見めんどくさいようにも思えますし、リソース的にも無駄が多そうだ、と思われるかもしれません。しかし、FreeBSDのJailとその管理ツールを使用するとその辺は驚くほど問題になりません。
次回、実際にどう使っているかを紹介します。

Recent Comments