Amazon EC2 で手元のホストとファイルを共有する
Amazon EC2 はVMを好きなタイミングで好きなだけ使うことができるので、複数のサーバを使う分散システムの検証環境として非常に使いやすい*1。費用を計算してみても、自宅でクラスタを動かすことを考えれば、十分安く上がりそうである。
しかし、VMを起動するたびに環境を設定したり、新しいテストを実行するたびにファイルを配ったりするのは面倒なので、ファイルを共有したくなる。
通信の遅延がかなり大きいので、EC2上でssh越しにファイルを編集するのも少々つらい。
そこで、手元のホストとホームディレクトリを共有する。さらに、一度転送したデータはキャッシュさせる。
共有ホームディレクトリ環境の管理方法と組み合わせれば、便利に使えるに違いない。
戦略
ファイル共有には NFSv4 over ssh を使う。NFSv4はポート番号を1つしか使わない(portmapperも要らない)ので、ssh越しで使いやすい。
これに FS-Cache を組み合わせて、データをキャッシュさせる。FS-Cache は Linux 2.6.30 から組み込まれている機能で、メモリだけでなくローカルディスクも使ってデータをキャッシュできるようにする。
NFSv4の設定
手元のホストでは、NFSv4サーバをセットアップしておく*2。 /etc/exportsでは127.0.0.1からのmountを許可しておく。
次にEC2でVMを立ち上る。ディスクイメージには "instance-store" 版のAmazon Linuxを使う。"ebs" 版ではキャッシュデータを置くローカルストレージが使えない*3。
VMが立ち上がったら、sshでログインする。このときに、以下のように2049番ポートを remote port forwarding しておく:
ssh -R2049:127.0.0.1:2049 ec2-user@ec2-host.compute-1.amazonaws.com
ログインしたら、nfs-utilsをインストールする。また、後述するcachefilesdをコンパイルするために、gccもインストールしておく:
yum install nfs-utils gcc
NFSv4サーバとuidを合わせたユーザーを作っておくと、ユーザ管理が簡単になるので便利だろう。
# uidはサーバ側に合わせる useradd -m -u 502 -d /home/viver viver
併せてidmapdの設定が必要になるかもしれない。/etc/idmapd.conf で、"Domain" をサーバの idmapd.conf と同じにしておく:
[General] # The following should be set to the local NFSv4 domain name # The default is the host's DNS domain name. #Domain = local.domain.edu Domain = localdomain
rpc_pipefsをmountし、idmapdを起動する。
mount -t rpc_pipefs rpc_pipefs /var/lib/nfs/rpc_pipefs service rpcidmapd restart
ここで試しにmountしてみる。mountできなければ、何かが間違っている。NFSv4サーバ/クライアント双方のdmesgを見るなどして修正する。
mount -t nfs4 127.0.0.1:/ /mnt umount /mnt
キャッシュの設定
次にFS-Cacheの設定をする。
FS-Cacheを有効にするには、cachefilesdというパッケージをインストールする必要がある。現時点ではyumにバイナリパッケージが用意されていないので、Webサイトからダウンロードして自前でコンパイルする。実は./configureさえ無いので、軽くソースを眺める必要があるかもしれない。
wget http://people.redhat.com/~dhowells/fscache/cachefilesd-0.10.tar.bz2 tar jxvf cachefilesd-0.10.tar.bz2 cd cachefilesd-0.10 make sudo cp cachefilesd /usr/sbin/ sudo cp cachefilesd.conf /etc/
/etc/cachefilesd.conf を編集する。最低限、キャッシュを保存するディレクトリと、SELinuxの設定を書き換える。
キャッシュの保存先はローカルディスク(/media/ephemeral0)とする。SELinuxの設定はコメントアウトする。
#dir /var/fscache dir /media/ephemeral0/fscache tag mycache brun 10% bcull 7% bstop 3% frun 10% fcull 7% fstop 3% # Assuming you're using SELinux with the default security policy included in # this package #secctx system_u:system_r:cachefiles_kernel_t:s0
キャッシュを保存するファイルシステムはuser_xattrが有効になっている必要があるらしいので、remountして有効にしておく。
mount -o remount,user_xattr /media/ephemeral0 mkdir /media/ephemeral0/fscache /usr/sbin/cachefilesd
最後に、キャッシュを有効にしてNFSv4をmountする。キャッシュを有効にするには -o fsc オプションを付ける:
mount -t nfs4 -o fsc 127.0.0.1:/ /mnt mount --bind /mnt/home/viver /home/viver
いくつかファイルを読み込み、キャッシュの保存先ディレクトリを見てみると、サイズが膨らんでいた。きっとキャッシュが効いているのだろう。
$ du -sh /media/ephemeral0/fscache 261M /media/ephemeral0/fscache/