お名前.comのVPSで作る!
ZFS on Linux活用の開発支援環境
2012/7/19
レンタルサーバのなかでもVPSサービスは使い勝手のよいサービスです。低価格でありながら、仮想マシンによってサーバ1台をまるごと自由に使うことができます。VPSの使いどころとしては、小規模なWebアプリケーションサーバやメールサーバが主流ですが、本稿では開発者向けの「開発支援環境としてのVPS」として、お名前.comのVPSサービスを利用してみることにします。
200GBと余裕の容量の低価格VPS
ここでいう開発支援環境とは、ソースコードやプロジェクト情報の共有や、バグトラッキングのためのWebシステムです。さらにビルドや自動テストを実施することもあるでしょう。こういったサーバは、社内に設置することが一般的です。しかしながら、設置の手間やコスト、社外の開発メンバーからのアクセスといった問題がつきまといます。
そこでVPSの出番です。開発支援環境として十分な性能があり、月々1000円ちょっとからと、今では社内にサーバを設置するよりも低コストといえるでしょう。VPSではディスク容量の不足が懸念されることもありますが、お名前.comのVPSサービスであれば最小のプランでも200GBと、その心配も無用です。200GBのディスクは、コントロールパネルから任意のサイズの2つの領域に分割できます。ディスクの分割そのものは、OSのインストールから自分で実施すれば当然自由に行えます。ですが、お名前.comのVPSサービスでは標準のOSであってもディスク分割が可能で、手軽に実現できるのが特徴です。
本VPSのスペック例を挙げると、メモリ2GB、ディスク200GBのプランで月額1153円からです(8月2日までは初期費用1680円も無料)。これでCPU3コア、回線速度100Mbpsというスペックですから、最も低価格なプランでも今回のような用途には申し分ありません。ちなみにOSは標準のCentOS 6.2 x86_64のほかにも、Ubuntu/Debian/Fedora/FreeBSDなどが選べます(その他のプランを含むスペック一覧)。KVMを利用した完全仮想化なので、今回の記事のようにファイルシステムとして非標準のものを使うといったことができる柔軟さもあります。
今回は2つ目のディスクを先進的なファイルシステムである「ZFS」にしたうえで、バグトラッキングシステムである「Trac」を動作させてみます。ZFSは多くの機能がありますが、本稿では中でもスナップショット機能によるバックアップに注目します。LinuxでのZFSはライセンスの問題で紆余曲折があるものの、安定しつつある状況です。先取りした格好になりますので、安定性を求める場合はLVMなどスナップショット機能を利用すると良いでしょう。
まずはコンパネを使ってサービスを初期化
お名前.comのVPSサービスのコントロールパネルにログインすると、以下の画面が表示されます。
画面1 コントロールパネルログイン直後の画面 |
左側のメニューの上部には「サーバリスト」と表示されていますが、本サービスでは複数のVPSを同じアカウントからコントロール出来るようになっています。「サーバリスト」の下にある文字列が、サーバの識別ラベルになっています。VPSの場合、1サーバごとに1アカウントでコントロールパネルも別々であることが多いですが、本サービスではこのように複数のサーバをまとめて管理することができます。
サーバの識別ラベルをクリックすると、そのサーバのコントロール画面になります(画面2)。メニューの右側にサーバの概要が表示され、メイン領域にはコンソール画面があります。サーバの起動中であれば、ここにそのコンソールが表示されるわけです。コンソールを使えば、もし設定を誤るなどしてネットワーク経由で接続できなくなっても操作可能です。
画面2 各サーバのコントロール画面。仮想マシンの操作ができる |
「OS再インストール」タブをクリックすると、OSの選択などの入力画面になります(画面3)。OSは標準OSを選択、rootパスワードは適切に設定します(パスワードの強度も表示されます)。SSH Key Pairの欄は、後述するキーペアを複数作成している場合はどれを使うか選択します。ディスク構成はカスタムを選択すると、サイズの割り当てを設定できるようになります。ここでは40GB/160GBという分割にしました。
画面3 OS再インストール。ディスクサイズもここで設定しておく |
OSの再インストールにはしばらく時間がかかりますので、その間にSSHクライアントの設定をすませましょう。左のメニューから「SSH Key Pair」をクリックします(画面4)。
画面4 SSHキーペアの管理画面。「+」ボタンでさらに追加することもできる |
次に「Private Keyダウンロード」ボタンを押して、秘密鍵ファイルをダウンロードします。起動したサーバにSSHで接続する際、この秘密鍵ファイルが必要になります。秘密鍵の設定方法はSSHクライアントによりますが、コントロールパネル右上にある「ガイド」をクリックすると、代表的なクライアントでの設定方法の解説がありますので、そちらを参照してください。
サーバの基本的な設定
サーバが起動したら、SSHクライアントを使って、rootユーザでログインします。無事ログインができたら、まずは基本的なOSの設定を実施します。最初に行うべきは一般ユーザの作成です。ここではatmarkitというユーザを使うことにします。次のようにして作成とパスワード設定を行います。
# useradd atmarkit # passwd atmarkit
次に、visudoコマンドを実行します。エディタが起動するので次の行をファイルの末尾に加えます。
atmarkit ALL=(ALL) ALL
ここからはrootユーザではなく、いま作成したatmarkitユーザでSSH接続して操作します。rootユーザ権限が必要なときは、sudoコマンドで明示的に利用するようにします。こうすることでミスを防ぎ、また操作記録を残すことができるようになります。rootユーザの秘密鍵ファイルとパスワードは、厳重に保管しておきましょう。
次はSSH接続の制限を行います。まず秘密鍵ファイルではなく、パスワードを使ったrootログインを禁止します。設定は/etc/ssh/sshd_configにありますので、sudo vi /etc/ssh/sshd_configを実行します。
#PermitRootLogin yes
という行を次のように変更します。
PermitRootLogin without-password
変更したらsshdを再起動して設定を有効にします。
$ sudo /etc/init.d/sshd restart
これでインターネット側からは、秘密鍵ファイルを持っていないユーザはrootでログインできない状態になりました。つまり、パスワードを総当たりで攻撃するといったことは、不可能になります。
企業では固定のIPアドレスを利用していることが多いと思いますが、SSH接続の接続元IPアドレスを限定できればさらに安全です。これには/etc/hosts.allowと/etc/hosts.denyファイルを使います。
/etc/hosts.allowには次の内容を追加します。
sshd: IPアドレス1, IPアドレス2, ...
/etc/hosts.denyには次の内容を追加します。
ALL: ALL
これで/etc/hosts.allowに記述したIPアドレスからしかSSHができなくなったはずです。設定をミスしてSSHできなくなってしまった場合は、前述のコンソールから修正しましょう。
次に、CentOSを最新の状態にしておきましょう。
$ sudo yum update $ sudo reboot
サーバからメールを送信できるようにするため、MTAの基本的設定もしておきます。/etc/postfix/main.cfファイルを次の内容で作成します。この設定により、外部からのSMTP接続は受け付けず、サーバ内からのSMTP接続だけを許可します。
mailq_path = /usr/bin/mailq.postfix newaliases_path = /usr/bin/newaliases.postfix sendmail_path = /usr/sbin/sendmail.postfix inet_interfaces = localhost inet_protocols = ipv4 mynetworks = 127.0.0.0/8 alias_maps = hash:/etc/aliases
postfixをリロードして設定を有効にします。
$ sudo /etc/init.d/postfix reload
2つ目のディスクですが、標準状態ではすでに/dataにマウントされています。これをアンマウントしておきます。
$ sudo umount /data
/etc/fstabファイルにある/dataの行も削除します。これで基本的な準備は完了です。
ZFSをソースからビルドしてインストールする
次に、ZFS on Linuxをインストールします。最新のZFS on Linuxのソースコードパッケージを取得します。ソースコードは2つのパッケージに分割されています。現時点で0.6.0rc9が最新です。
$ sudo yum install wget $ wget https://github.com/downloads/zfsonlinux/spl/spl-0.6.0-rc9.tar.gz $ wget https://github.com/downloads/zfsonlinux/zfs/zfs-0.6.0-rc9.tar.gz
次に、ビルドに必要なパッケージをインストールします。
$ sudo yum groupinstall "Development Tools" $ sudo yum install zlib-devel libuuid-devel libblkid-devel libselinux-devel parted lsscsi bc mdadm
spl-0.6.0-rc9.tar.gzを展開し、次のようにしてビルド、インストールします。
$ ./configure $ make rpm $ sudo rpm -Uvh *.x86_64.rpm
zfs-0.6.0-rc9.tar.gzを展開し、次のようにしてビルド、インストールします。
$ ./configure $ make rpm $ sudo rpm -Uvh *.x86_64.rpm
splの時とコマンドは同じですが、最後にrpmコマンドでインストールされるパッケージが異なります。これでZFSが使える状態になりました。
ZFSファイルシステムの構築
ZFSによるファイルシステムを作成する前に、2つ目のディスクのパーティションテーブルを作成します。
$ sudo parted /dev/vdb mklabel gpt
ZFSでは、まずディスクのプールを作成します。ここでは2つ目のディスクである/dev/vdbをプールに登録します。複数のディスクがある環境では、プール構築時にRAID構成にすることも可能です。プールを作成するには、次のようにzpoolコマンドを使います。ここではtankという名前のプールとしました。
$ sudo zpool create tank /dev/vdb
このコマンドを実行するとtankというプールが作成されます。プールはそのままZFSの領域となり、自動的に/tankというディレクトリにマウントされてすぐに利用可能になります。ZFSではマウントまで面倒を見るので、通常のmountコマンドは用いません。この状態をdfコマンドで確認してみると次のようになります。
$ df -Th Filesystem Type Size Used Avail Use% Mounted on /dev/mapper/VolGroup-lv_root ext4 37G 1.5G 34G 5% / tmpfs tmpfs 939M 0 939M 0% /dev/shm /dev/vda1 ext4 485M 72M 388M 16% /boot tank zfs 157G 0 157G 0% /tank
プールである/tankをそのまま使うこともできるのですが、通常はプール内にファイルシステムを作成します。ファイルシステムはプール内に複数作成でき、その場合はプールを共有することになります。データで消費した分だけプールを使うイメージです。
今回は各種データは/srvに置く予定なので、tankプールに作成したファイルシステムを/srvにマウントします。
$ sudo zfs create -o mountpoint=/srv tank/srv
このコマンド1発で、tank/srvというファイルシステムを作成したうえで、/srvにマウントします。dfコマンドの結果は次のようになります。
$ df -Th Filesystem Type Size Used Avail Use% Mounted on /dev/mapper/VolGroup-lv_root ext4 37G 1.5G 34G 5% / tmpfs tmpfs 939M 0 939M 0% /dev/shm /dev/vda1 ext4 485M 72M 388M 16% /boot tank zfs 157G 128K 157G 1% /tank tank/srv zfs 157G 128K 157G 1% /srv
ぱっと見だと157GBの領域が2つあるように見えてしまいますが、そうではなく、もとはtankというプールの領域です。親のプールの最大サイズまで使うことができる状態ですが、最大の大きさ(クオータ)の設定も可能です。
ついでに/homeもtank内に配置してみましょう。いったん/mntにマウントしたうえで現在の内容をコピー、再マウントします。
$ sudo zfs create -o mountpoint=/mnt tank/home $ cd / $ sudo mv /home/* /mnt/ $ sudo zfs set mountpoint=/home tank/home $ sudo zfs mount tank/home
これで/homeが切り替わりました。dfコマンドで確かめてみます。
$ df -Th Filesystem Type Size Used Avail Use% Mounted on /dev/mapper/VolGroup-lv_root ext4 37G 1.5G 34G 5% / tmpfs tmpfs 939M 0 939M 0% /dev/shm /dev/vda1 ext4 485M 72M 388M 16% /boot tank zfs 157G 0 157G 0% /tank tank/srv zfs 157G 0 157G 0% /srv tank/home zfs 157G 33M 157G 1% /home
この状態から、/homeは10GBまでに制限する事もできます。
$ sudo zfs set quota=10G tank/home $ df -Th Filesystem Type Size Used Avail Use% Mounted on /dev/mapper/VolGroup-lv_root ext4 37G 1.5G 34G 5% / tmpfs tmpfs 939M 0 939M 0% /dev/shm /dev/vda1 ext4 485M 72M 388M 16% /boot tank zfs 157G 0 157G 0% /tank tank/srv zfs 157G 0 157G 0% /srv tank/home zfs 10G 33M 10G 1% /home
これはZFSのほんのさわりですが、非常に高機能で柔軟でありながらも、容易に扱えるファイルシステムであることが分かると思います。
ApacheおよびTracのインストール
まずはApacheをインストールし、起動します。
$ sudo yum install httpd mod_wsgi $ sudo /etc/init.d/httpd start
なお、標準状態ではSSHで使用する22番ポート以外、iptablesによって外部からの接続は遮断されるようになっていますので、/etc/sysconfig/iptablesファイルを編集して80番ポートを許可しなければなりません。
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
という行があるはずなので、その次の行に、次の行を挿入します。22の部分を80にしたものを追加するということです。
-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
設定を有効にするため、iptablesを再起動します。
$ sudo /etc/init.d/iptables restart
これでブラウザからアクセスすれば、CentOSの標準ページが表示できるはずです。
次にTracのインストールを行います。まずはPythonの仮想環境を作ります。仮想環境を使うと、OS上のPythonにまったく影響を与えずPythonのライブラリをインストールできます。
$ wget https://raw.github.com/pypa/virtualenv/master/virtualenv.py $ sudo python virtualenv.py /srv/python
これで/srv/pythonに仮想環境が構築されました。仮想環境の構築時に、pipという自動インストールコマンドも同時にセットアップされますので、これを使ってTracをインストールします。
$ sudo /srv/python/bin/pip install Trac $ sudo /srv/python/bin/pip install Babel $ sudo /srv/python/bin/pip install pytz $ sudo /srv/python/bin/pip install Pygments
以上でTracのインストールは完了です。
Tracの環境構築
Tracの環境はtrac-adminコマンドで初期化します。
$ sudo mkdir /srv/trac $ sudo /srv/python/bin/trac-admin /srv/trac/proj1 initenv
実行すると「Project Name [My Project]>」と表示されるので、プロジェクト名を入力します。ここでは「Test Project」と入力しました。次にデータベースの設定ですが、デフォルトのままで良いので何も入力しません(エンターのみ)。最後に所有者をapache:apacheに変更します。
$ sudo chown apache:apache -R /srv/trac/proj1
次に、この環境をApacheからWSGI経由で参照可能にするための設定ファイルを作成します。WSGIのスクリプトファイルはどこに置いてもよいのですが、今回は/srv/trac/proj1.wsgiとします。次の内容で作成します。
import trac.web.main def application(environ, start_response): environ['trac.env_path'] = '/srv/trac/proj1' return trac.web.main.dispatch_request(environ, start_response)
3行目が先ほど作成したTrac環境へのパスになります。このWSGIスクリプトを呼び出すApacheの設定は、/etc/httpd/conf.d/wsgi.confに記述します。もちろんこのファイルでなくとも、Apacheの設定ファイルであればどこでも構いません。
LoadModule wsgi_module modules/mod_wsgi.so WSGIPythonHome "/srv/python" WSGIPythonEggs "/tmp/.python-eggs_httpd" WSGISocketPrefix "/var/run/wsgi" WSGIDaemonProcess trac processes=1 threads=50 maximum-requests=10000 \ home=/tmp display-name=%{GROUP} WSGIScriptAlias "/proj1" "/srv/trac/proj1.wsgi" <Location "/proj1"> WSGIProcessGroup trac WSGIApplicationGroup %{GLOBAL} </Location>
Apacheを再起動し、ブラウザで/proj1にアクセスしてみてください。Tracの画面が表示されれば成功です(画面5)。なお、Tracへのアクセスに対しユーザ認証を設定する場合がほとんどだと思いますが、それは上記の<Location>内に設定します。
画面5 Tracの画面。左上の画像が表示されないのは、アイコン画像が未設定のため |
ここまでの設定は、Tracの環境ディレクトリである/srv/trac/proj1を/proj1として公開するものでした。同じようにすることで、複数のTrac環境を構築できるということは自ずと分かると思います。
Tracでメール通知をする設定
Tracの設定は、前述の/srv/trac/proj1の場合は、/srv/trac/proj1/conf/trac.iniで行います。ある程度の設定はWebからも変更できるようになってきているのですが、この設定ファイルでしか変えられない設定も多数あります。すべての解説はできませんので、本稿では設定ファイルでしか変更できない設定のうち、メール通知に関するものを紹介します。
この設定ファイルはいわゆるINI形式になっています。メール通知に関する設定はnotificationセクションにまとめられています。メール通知を有効にするため、最低限変更しなくてはならないのは次の設定です。
smtp_enabled = true smtp_from = trac-admin@example.com smtp_replyto = trac-admin@example.com smtp_server = 127.0.0.1 mime_encoding = base64 ambiguous_char_width = double
smtp_fromおよびsmtp_replytoは管理者のメールアドレスにすると良いでしょう。このほか、メール通知のタイミングに関する設定があります。
よく使うのは、常にあるアドレスに通知を行いたい場合、smtp_always_cc、あるいはsmtp_always_bccにそのメールアドレスを設定します。後者を使うとメールのヘッダ中にそのメールアドレスが現れません。プロジェクト参加者全員に常に通知したい場合、メーリングリストのアドレスを設定するとよいでしょう。その場合、always_notify_updaterはfalseにしないと二重にメールが送信されるので要注意です。
ZFSのスナップショット機能で楽々バックアップ
/srvはTracのデータベースが保存されているため、定期的にバックアップする必要があります。Tracの管理コマンドでもバックアップは取得できますが、複数のプロジェクトを構築するとそれも面倒です。そこで/srvを丸ごとバックアップをすることを考えます。
いちばん簡単なのは、Apacheなどを停止し、書き換えがない状態にしてコピーしたり、tar等でアーカイブすることです。首尾一貫したコピーを取るには、書き換えがない状態にしないといけないためです。
しかしこれでは面倒ですし、サービスを停止しなければならないので不便です。そこでZFSのスナップショット機能を使えば、停止をすることなくバックアップを取得可能です。
スナップショットは次のようにして作成します。
$ sudo zfs snapshot tank/srv@backup
@の後ろがスナップショットの名前になります。ここではbackupとしました。スナップショットは、マウントディレクトリの.zfs/snapshot/内に作成されます。なお、このディレクトリは見えません。
$ ls -F /srv/.zfs/snapshot/ backup/
backupというディレクトリがあります。この中は、先ほどzfs snapshotを実行した瞬間の内容になっています。このディレクトリをコピーすればバックアップ完了、というわけです。
使い終わったスナップショットの削除は次のように行います。
$ sudo zfs destroy tank/srv@backup
この一連の操作をシェルスクリプトにすれば、容易にバックアップ取得ができるようになります。スナップショットを用いたロールバックも可能ですので、ディスクに余裕があるのであれば、毎日スナップショットを残し、何か不具合があったら戻すといった運用も不可能ではありません。
以上で開発支援環境の構築はひととおり完了です。今回解説できなかった内容としてはバージョン管理システムのインストールなどもありますが、皆さんでチャレンジしてみてください。
関連リンク
提供: GMOインターネット株式会社
アイティメディア営業企画/制作:@IT 編集部
掲載内容有効期限:2012年8月18日