タグ別アーカイブ: nfs

NFSはアンダースコアのあるexportsをマウントできない?

こんにちは、岡田洋一です。

最近は引き続いてファイルサーバの移行を行っています。
さてそのファイルサーバではNFSを提供しています。
ローカル環境の各ホストに対して同じホームディレクトリを提供してくれる非常に心強い存在です。
NFSも少し前にバージョンが3から4になり、パフォーマンスの向上やUID、GIDを揃えるidmapdとの連携など便利になったりしました。

さてそんなNFSなのですが、今回新サーバに移行するにあたってうまくマウントできない症状が起きました。

shell> sudo mount nfs.l2tp.org:/path_service /mnt/path_service
mount.nfs: Connection timed out

なにやらエラーが起きてますね。
NFSではexportsというファイルに設定を書いて色んなディレクトリを他のホストからマウントすることができるのですが、うまくいきません。
実はこれ、他のディレクトリではうまくいっていたんですね。でもこのディレクトリだけうまくいきません。

今回設定したのは下記の通りです。サーバクライアントともにUbuntu 14.04LTSです。

NFSサーバにて、fstabでbindマウントを行う
shell> grep service /etc/fstab
/pool/path_service       /exports/path_service  none    bind              0    0

次にexportsに記載
shell> /exports/path_service 192.168.1.0/24(async,nohide,no_subtree_check,no_root_sq
uash,rw)

最後に関連サービスの再起動などなど
shell> sudo mount -a
shell> sudo service nfs-kernel-server restart
shell> sudo exportfs -ra


クライアント側にてマウントさせる
shell> sudo mount nfs.l2tp.org:/path_service /mnt/path_service
mount.nfs: Connection timed out

うまくいかないです。

もう一度言いますが他のディレクトリはうまくマウントできているのです。このディレクトリがダメなのですね。
うまくいっている所と見比べてみると、ディレクトリ名にアンダーバー、アンダースコアがあることが考えられます。

この後実際にアンダーバーを省いたものでマウントさせてみると… ちゃんと動きました!

NFSはアンダーバーを含むファイル名をマウントする事ができないのでしょうか?

少しググってはみたのですがそれらしき記述は見当たらなくて、これまでも聞いたことが無くて…うーん。

もしどなたかご存じの方がいらっしゃった場合には教えてください!

追記:
ちなみにクライアント側でマウント先ディレクトリにアンダーバーがある場合には大丈夫でした。

shell> sudo mount nfs.l2tp.org:/pathservice /mnt/path_service

この場合には通るのでexportsでアンダーバーを許可していない、とかなのでしょうか。
またexportsにアンダースコア含みでディレクトリを記載してもマウント時にアンダースコア無しでマウントできてしまいました。
アンダーバーは無視されるのかな?

NFSでマウントしているホスト一覧を取得

こんにちは。

秋口もずいぶんと涼しくなってきて肌寒いぐらいになってきました。

さて現在、うちではファイルサーバの移行を行っています。
今までFreeNASを使ってきたのですがそろそろNFSv4とかも欲しいのでUbuntuへ移行することになりました。

NFSサーバの構築も終わり一通りファイルもコピーし終わりましたが、次の重要な作業が待っています。

各ホストではfstabを使って旧サーバをマウントしていますが、これを新サーバに書き換える必要があります。

ホストにログインしてfstabを書き換える…、この作業も重要ですが、何より既にマウントして使っているホスト一覧を調べ上げるということが重要です。
どのホストが利用しているかを把握できないと移行がうまくいっているかという確認すらできず、気がついたらサービスが停止していました,ということになりかねませんからね。

NFSでマウントさせているおおよその台数は20台ぐらいです。
なのでつい漏らしてしまうことがあるんですね。

こういうときにはNFSサーバ側でshowmount -aを使うとその一覧を取得することができます。

shell> showmount -a
All mount points on localhost:
192.168.1.36:/path/to/home
192.168.1.37:/path/to/home
192.168.1.45:/path/to/home

簡単ですね!

FreeBSDでnfsをマウントするときのマウントオプションについて

1. FreeBSDとNFS

FreeBSDでNFSを利用している。サーバはFreeNAS 0.7.2 (NFSv3)、クライアントもFreeBSD (versionは7.3以降)。

このとき、どんなオプションでマウントするのが良いのかなと思って調べてみた。

歴史的経緯というか実装系が違うからだろうか、詳しい理由はわからないんだけれど、LinuxとFreeBSDはnfsのマウントオプションが違かったりする。

Linuxだとnfs周りのマウントコマンドはドットで区切られた実行ファイル名、mount.nfsとかだったりするけれど、freebsdだとmount_nfsとかっていうアンダースコアで区切られた実行ファイル名だったりする。

そんでmount –t nfsってのはmount_nfsを参照してる?のかな。

man mount_nfsするとオプションの一覧とか出てくるんだけれど、ここにあるマウントオプションでどれを使えば良いかよくわからない。いつもテキトウに使ってる。そんでどれ使えば良いか、何となくのメモ。

続きを読む FreeBSDでnfsをマウントするときのマウントオプションについて

時刻のズレが呼ぶサービスダウン

1. メールが見れない!

ある日突然、メールが見れなくなった。imapでcourier-mtaのサーバに接続してメールを取得しようとしたらエラーが出ていた。

OK [CAPABILITY IMAP4rev1 UIDPLUS CHILDREN NAMESPACE THREAD=ORDEREDSUBJECT THREAD=REFERENCES SORT QUOTA IDLE AUTH=PLAIN ACL ACL2=UNION] Courier-IMAP ready. Copyright 1998-2010 Double Precision, Inc.  See COPYING for distribution information.
0000 CAPABILITY
CAPABILITY IMAP4rev1 UIDPLUS CHILDREN NAMESPACE THREAD=ORDEREDSUBJECT THREAD=REFERENCES SORT QUOTA IDLE AUTH=PLAIN ACL ACL2=UNION
0000 OK CAPABILITY completed
0001 LOGIN ******** ********
BYE Clock skew detected. Check the clock on the file server

エラーとしては “BYE Clock skew detected. Check the clock on the file server” と言うものらしい。どうやら時刻がズレているようだ。

続きを読む 時刻のズレが呼ぶサービスダウン

Ubuntu serverのNFSをMac OS X 10.7.1でマウント

yousanに聞かれて試行錯誤してたんだけど、うまくいかなかったので、自分の環境でもやってみた。
元々うちではNFSを使ってなかったんだけど、よく考えたらNISも入れてるし、MacとWindows以外はUIDもGIDも同じなので、ちょっと使ってみることにした。

まず、Macで
/アプリケーション/ユーティリティ/ディスクユーティリティ.app
(/Applications/Utilities/Disk Utility.app)
を開いて、メニューの “ファイル”->”NFS マウント” を開く
左下の+ボタンを押して項目を追加する。

リモートNFSのURLは、少し注意が必要で、nfs://server_address:/path は動作しない
必ず nfs://server_address/path で、コロンを入れない事。
マウント先は好きなように指定して問題なくて、ディレクトリは自分で作る必要が無い。むしろ存在しない方が良い?

で、詳細マウントパラメータには、サーバ側の設定にもよるけど、まず必要なのが
resvportとnolocksとlocallocks
それ以外は環境によって。

後はNFSマウントのウィンドウを閉じようとすると、管理者パスワードを聞かれるので、入力したら終わり。
マウント先をlsしてみるとマウントされてると思うけど、サーバがUbuntuの場合はおそらく、UID/GIDが1000から開始されるので、Macの501から開始と食い違ってる。map_staticとか試してみたけど、反映されなかったのでMac側のUID/GIDを変更することにした。

一応、sudo suでルートのターミナルを作ってそこで作業する
MacのUIDが501 GIDが20
UbuntuのUIDが1000 GIDが1000
の場合

#dscl . -change /Users/username UniqueID 501 1000
#dscl . -create /Groups/groupname
#dscl . -create /Groups/groupname name groupname
#dscl . -create /Groups/groupname gid 1000
#dscl . -change /Users/username PrimaryGroupID 20 1000
#dscl . -append /Groups/staff GroupMembership yubird

で、Macのユーザ所有ファイルなどのパーミッションがおかしくなったので修正

#cd /Users
#chown -R username:groupname username

もしかしたらApplicationsでも、ドラッグアンドドロップで追加した物がおかしくなってるので、同様にchownしてやればいい。
id username の結果が良さそうなら再起動して、マウント出来ている事を確認

FreeBSDのNFSでファイルロックをとれるようにする

FreeBSDのNFSでファイルロックをとれるようにする。

OSのバージョンは、サーバ側がFreeBSD 7.3(FreeNAS 0.7.2)、クライアントがFreeBSD 8.2。6系列だと動かないとか。

ずっと、NFSではファイルのロックがとれないと聞いていた(思い込んでいた)けど、さっくり調べたらLinuxではとれるとか。 だったらFreeBSDでもいけるっしょ、と調べてみた。

結論から行くとロックはとれる様子。

まずはテストコードを書いてみた。

<?php
$fp = fopen("/mnt/nfs/hoge.txt", "r+");
if(flock($fp, LOCK_EX)){
 echo 'got exclusive file lock'."\n";
 flock($fp, LOCK_UN);
}else{
 echo 'cannot get file lock'."\n";
}
fclose($fp);
?>

shell> touch /mnt/nfs/hoge.txt
shell> php flock.php
cannot get file lock

ファイルのロックはとれていない。これが普通の(mountでnfsserver:/path/to/mount /mnt/nfsとかしたときの)nfsをマウントしたときの動作。いままではここであきらめていたけどここからちょっと突っ込んでみる。

さっくり調べてみるとrpc.lockd, rpc.statdを起動させるとロックが取得できるらしい。で、早速起動させてみる。rc.confに以下を追加して起動する。


shell> grep rpc /etc/rc.conf
rpc_lockd_enable="YES"
rpc_statd_enable="YES"

shell> sudo /etc/rc.d/statd start
shell> sudo /etc/rc.d/lockd start

shell> php flock.php
got exclusive file lock

サーバ側でもrpcを走らせる必要があるとか色々書いてあった。今回サーバはFreeNASのNFSを使っている。確認したらrpc.{statd, lockd}は動いていた。


shell> ssh freenas ps auxww | grep rpc

root         69671  0.0  0.0  6912  1452  ??  Ss   Mon10AM   0:00.37 /usr/sbin/rpcbind
root         69955  0.0  0.0 267976  1348  ??  Is   Mon10AM   0:00.03 /usr/sbin/rpc.statd
root         69992  0.0  0.0  6912  1300  ??  Is   Mon10AM   0:00.00 /usr/sbin/rpc.lockd

おかげでうまくいっているみたい。めでたしめでたし。

参考リンク

http://groups.google.com/group/mailing.freebsd.fs/browse_thread/thread/0cd34288efff29ec/d8202d636557a2ae

nfsのアクセスが遅そうなので調べてみた

nfsのアクセスが遅そうなのでphpを使って調べてみた。

nfsサーバAは

FreeBSD 7.1 (古い・・・)
500GBのHDDをRAID1で接続してある。(ハードウェアRAID)

サーバBは

FreeNAS 0.72 (freebsd 7.2)
2TB*6のHDDをzfsでraidzしてる。

クライアントは

FreeBSD 8.2
CPU Xeon3330

すべてGbEで接続されている。

テストコード。 nfs上のファイル、ローカルのHDD上のファイルそれぞれに読み出しをかける。

100,000回 (10万回)実行の時間を計る。

<?php
main();

function openRead($filename){
 define(READ_BUF, 1024);
 if(FALSE === ($handle = fopen($filename, "r"))){
   echo 'file open error: ' . $filename . "\n";
   exit(1);
 }
 while(!feof($handle)){
   $str = fread($handle, READ_BUF);
   //echo $str;
 }
 fclose($handle);
}

function main(){
 define(ATTEMPT, 100*1000); // 100,000回
 $filenames = array
 ('/mnt/sa/test.txt', '/mnt/sb/test.txt', '/tmp/test.txt');
 foreach($filenames as $filename){
   echo 'to ' . $filename . "\n";
   $time = microtime(true);
   for($i = 0; $i < ATTEMPT; $i++){
     if(!($i%1000)){
       if(!($i%10000)){
         echo $i;
       }else{
         echo '.';
       }
     }else{
       //echo $i."\n";
     }
       openRead($filename);
   }
   echo "\n". 'elapsed time: ' . (microtime(true) - $time) . 'seconds'."\n\n";
 }
}


shell> php filetouch.php
to /mnt/sa/test.txt
0.........10000.........20000.........30000.........40000.........50000.........60000.........70000.........80000.........90000.........
elapsed time: 36.0750498772seconds

to /mnt/sb/test.txt
0.........10000.........20000.........30000.........40000.........50000.........60000.........70000.........80000.........90000.........
elapsed time: 18.9572398663seconds

to /tmp/test.txt
0.........10000.........20000.........30000.........40000.........50000.........60000.........70000.........80000.........90000.........
elapsed time: 3.80465817451seconds

ううーん、かなり差が出てる。ローカルのHDD早いなぁ。

マウントオプションを変えてみる。 noatime付与。



shell> mount
sa:/tmp/hoge on /mnt/sa (nfs, noatime)
sb:/tmp/hoge on /mnt/sb (nfs, noatime)

shell> php filetouch.php
to /mnt/sa/test.txt elapsed time: 34.3628730774seconds
to /mnt/sb/test.txt elapsed time: 18.9743080139seconds
to /tmp/test.txt elapsed time: 3.80826997757seconds

うーん、変わらず、noatimeってあまり効果が出ないのか・・・。

noatime自体が有効じゃないのかと疑って、ファイルのアクセス日時を確認してみたけどちゃんと更新されていませんでした。

続いてファイルの非同期読み書きオプションのasyncをつけてみる。


shell> mount
sb:/usr/home on /mnt/sa (nfs, asynchronous)
sb:/mnt/main_pool/common/backup on /mnt/sb (nfs, asynchronous)

time php filetouch.php
to /mnt/sa/test.txt elapsed time: 33.7545938492seconds
to /mnt/sb/test.txt elapsed time: 18.9745950699seconds
to /tmp/test.txt elapsed time: 3.80167484283seconds

こちらも大して結果がよくならない。

この辺で興味が薄れてきたので終了。

まとめ

サーバ構成など

サーバ名 OS HDD
NFSサーバA (sA) FreeBSD 7.1 500GB * 2 (hardware RAID1)
NFSサーバB (sB) FreeNAS 0.72 2TB * 6 with zfs raidz
NFSクライアント (c) FreeBSD 8.2 160GB ST3160023AS

100,000回の読み出しにかかった時間

やったこと オプション 時間
c -> c の読み出し(ローカルでのアクセス) /dev/ad6s1e on /tmp (ufs, local, soft-updates) 3.80 sec
sA -> cの読み出し デフォルトのマウント 36.07 sec
sB -> cの読み出し デフォルトのマウント 18.95 sec
sA -> cの読み出し noatime 34.36 sec
sB -> cの読み出し noatime 18.97 sec
sA -> cの読み出し async 33.75 sec
sB -> cの読み出し async 18.97 sec

考察

どうやったらはやくなるのかなあ!

FreeBSDのシステム構成を複製する

FreeBSDのシステム構成を複製する。

複製と言っても色々な状況が考えられるが、おおむね以下の目的のために複製してみよう。

  • それなりの台数(3台を超えたらもう面倒)を扱う。
  • →それなりの台数だからOSのインストール、パッケージのインストールが面倒
  • 同じ設定(厳密には同じ*ような*設定。hostname, ipaddressなどは違う。)を使う。
  • →仮想マシンならイメージのコピー、実マシンならddとかで複製されたHDDイメージを流用する。pxeブート環境もしくはUSBでディスクレスってのもいいよね
  • →→となるとできる限り容量を抑えたい。usbに収まるなら2GB以下、pxeでもそれぐらいが望ましいな~。
  • パッケージ管理を簡略化したい。追加、削除、バージョンアップを一台のマシンで済ますことができないか。
  • →CPUタイプ、FreeBSDのバージョンが一緒ならバイナリの複製でだいたい動く。親元マシンにパッケージを追加したら他のやつでも使えるといいな。
  • →→ってことは/usrあたりをnfsで共有するとだいたいオッケー。rc.confに起動オプションを与える必要はあるけどまぁそれはやろう。
  • →→昔は/etcに設定ファイルを置いたりしてたけど、最近は全部/usr/local/etcに統一されてるから楽ちん。
  • →→まずいことがありそうだけどよくわからない。
  • パッケージ情報は見たい。pkg_infoしたら見れるようにしておきたい。

ここで、親マシン、子供マシンとマシン群を分ける。親マシンはnfsで共有される側のnfsサーバとなるマシン。パッケージの新規セットアップとかはこのマシンで行う。

子供マシンは親マシンを参照してnfsでマウントする側のマシン。

親マシンのセットアップ、子供マシンのマスターセットアップ、子供マシンのコピー、という順序で行おう。

ということで、親元マシンをまずはセットアップ、nfsの設定を行って、その後子供マシンを作成する。

今回はVMWare ESXiを利用したよ。

まずは親元のマシンでnfsの設定を行ってやる。

/usrごと引き渡そうと思ったけど、/usr/homeと/usr/portsは別のホストでnfsを利用しているので別個に/usr/以下のディレクトリをnfsで共有してやることにした。

親元マシンが/usr/portsとかも管理するなら/usrまるごとでもいいかも。

nfsの設定

nfsの設定で色々とはまってしまった。(/usr/homeをマウントしたまま/usrをexportしようとしたり、killall -hup mountdをしてなかったり・・・)

次に子供マシンのセットアップ。

次いで子供マシンをセットアップ。

このとき最初に、/usrとかなしで、/を親元からコピーすれば良いんじゃないか、という思い立つ。

/usrのほとんどを親元マシンからnfsでマウントするわけだから、起動に必要な基本的なファイル群だって別に必要ないんじゃないか。カーネルとか/bootとかその辺だけあれば起動できるんじゃないか、と。

結論からすると、できるにはできるが趣旨に反してくる上に面倒、ということでした。

まず起動まではこぎ着けることができる。FreeBSDのsysinstallからfdisk, label editorをつかって/, swap, /tmpのみ作成。Fixitを利用して親元マシンから/をdump and restoreしてコピー。

これでひとまずシステム自体は起動した。/varを作って/var/dbディレクトリがないとちょっと起動がしんどかったり、/ファイルシステムに/usr/以下のディレクトリ群を手動で作ったり、この時点で面倒になってしまった。

そんでいざ起動させようと思ったのだけど、dhcpでipaddressをもらう際に/usr/sbin/dhclientが必要だった。しょうがないのでこのバイナリだけコピーして動かしてみたら今度はchrootが必要だって怒られた。この時点で諦めた。

だったらまぁ、普通にインストールして、その上から上書きする形でnfsでmountする、ってのがお手軽だった。うん。

ということで普通にセットアップを行う。HDD容量は3GB。仮想マシンで作成。

変わった点といえばラベルの付け方。/usrと/varにほとんど割り振らないようにしてみた。

/に500MB, swapに1GB, /tmpに1GB, /varに30MB, /usrに残り、って感じ。

インストールが完了したらipアドレスを取得してnfsでマウントさせる。

fstabの内容が多い。

これで完了。pkg_infoしてみたら確かにいろいろ入ってるように見える。

注意すべきは/varについて。syslogが握っているファイルが実際の/varだったり(このときは/varを実HDDでマウントした状態であとからnfsでマウントしたので握りっぱなしだった)、nfs上の/var/logを子供のマシン側で書き換えたりしそうな点。この点は/etc/syslog.confでログをsyslogサーバに送ることにする。

またログローテートも止めておかないとまずそう。うん。共有するのは/var/pkgだけでもよさそう。/var/db/mount*とかも書き換えられちゃうしね。その辺は今後の様子を見ながら、ってことで。

やっぱり/varは共有しない方がいいっぽい。/var/runのpidsとか共有したってしょうがない。/var/db/pkgだけ共有するように変更した。

また、子供マシンの複製を行う際には、/etc/のrc.conf, syslog.conf, sysctl.conf, crontabあたりを先に書き換えておこう。タイムゾーンの設定も忘れずに。

以上。