= NFSv4クライアントの作り方 = <> == 検証環境 == * CentOS/x86_64 6.8(2016年06月10日版)をNFSv4【クライアント】とする。 * FreeBSD をクライアントにするケースは今回は無しで。 * 使用するプロトコルはNFSv4に絞る(重要なので2回ry)。 * [[NFSv4/サーバー|NFSv4サーバー]]については先に行った設定を前提とする。 * バージョンの選択についてだが、過去との互換性?今時 v2 はおろか、v3 でもないでしょ、ということで、v4 ないしは v4.1(pNFS はまだ使えない orz)一択で。 == NFSセキュリティメモ == <> = インストール = == インストール == {{{ yum -y install nfs-utils }}} NFSクライアント・サーバーともに、nfs-utils のインストールで全てまかなえてることになっている。 == ディレクトリ作成 == {{{ #!sh mkdir -p 0755 /export }}} == 自動起動設定 == {{{ chkconfig rpcbind on chkconfig netfs on chkconfig rpcidmapd on chkconfig rpcgssd off chkconfig rpcsvcgssd off chkconfig nfs off chkconfig nfslock off }}} = セットアップ = == MTU値の設定 == 今時のファイル共有ならGbEや10GbE当たり前なので、MTU値を設定する。 MTU値はネットワーク依存で、通信に絡んでいる一番小さな値を指定することになる。 必ずしも9000(バイト)とは限らないので、ちゃんと調べよう(&設定しよう)。 なお手動で設定できるが、設定した瞬間にMTU値が反映される(インターフェース的な問題よりもTCP的に)かわからなかった。 即座に反映されたようにも見えるし、umount→mount したら使ってたような気がしないでもなし。 たぶん、リンクダウン・アップした方がいいとは思うけど。 {{{ ip link set ethn mtu 9000 ip link set ethn down ip link set ethn up }}} リンクダウン時に、そのインターフェースが持っていた経路情報を失うので(設定してなければ問題無い)、厳密には {{{service network restart}}} の方がいいかもしれない。 あるいはそもそも論として、再起動({{{shutdown -r now}}})してしまうのが吉。再起動後、インターフェースの設定を確認する。 {{{ # ip link show ethn m: ethn: mtu 9000 qdisc mq state UP qlen 1000 link/ether 00:0c:29:XX:XX:XX brd ff:ff:ff:ff:ff:ff }}} また、CentOS(RHEL)では、IPアドレス設定が、静的設定か動的設定かで、設定ファイルが分かれる。 === /etc/sysconfig/network-scripts/ifcfg-ethn(静的設定環境用) === {{{ DEVICE=ethn TYPE=Ethernet BOOTPROTO=static HWADDR=00:0c:29:xx:xx:xx IPADDR=XXX.XXX.XXX.XXX PREFIX=XX NM_CONTROLLED=no MTU=9000 ONBOOT=yes }}} === /etc/dhclient-ethn.conf(動的設定環境用) === {{{ default interface-mtu 9000; supersede interface-mtu 9000; }}} ググるとごちゃごちゃ設定(しかもグローバルに)してるケースがあるが、本質的には上記2行だけでok。 環境によってはどちらか1行でもok。 もしかしたら良きに計らってくれてるかもしれないくらい(DHCPサーバーがMTU値を広告してくれる)。 たまたま /etc/sysconfig/network-scripts/network-functions のコード読んでたから知ってたけど、意外と知られてないのかな。 === /etc/sysconfig/nfs === {{{#!highlight udiff --- /etc/sysconfig/nfs.orig 2016-05-11 15:22:22.000000000 +0900 +++ /etc/sysconfig/nfs 2016-06-06 19:32:42.649929205 +0900 @@ -69,7 +69,7 @@ # # # Optional arguments passed to rpc.idmapd. See rpc.idmapd(8) -#RPCIDMAPDARGS="" +RPCIDMAPDARGS="-C" # # Set to turn on Secure NFS mounts. #SECURE_NFS="yes" }}} === /etc/idmapd.conf === {{{#!highlight udiff --- /etc/idmapd.conf.orig 2015-07-24 17:27:51.000000000 +0900 +++ /etc/idmapd.conf 2016-06-06 14:34:41.302648213 +0900 @@ -3,6 +3,7 @@ # 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 = アカウント識別用ドメイン # The following is a comma-separated list of Kerberos realm # names that should be considered to be equivalent to the }}} == /etc/fstab == {{{ NFSクライアントサーバーIP:/NFSv4ライアント名 /export nfs4 defaults,soft,intr,noexec,nosuid 0 0 }}} 上記設定を/ etc/fstab に追加する。 ||<#FFFF00>オプション名 ||<#FFFF00>意味 ||<#FFFF00>備考 || || soft || || || || intr || || || || noexec || || || || nosuid || || || 手動でマウントするなら、以下の通りとなる(必要なデーモンが全て立ち上がってる前提で)。 {{{ mount -t nfs4 -o defaults,soft,intr,noexec,nosuid NFSクライアントサーバーIP:/NFSv4ライアント名 /export }}} = アカウント作成 = == postgres == {{{ groupadd -g 5432 postgres useradd -u 5432 -g postgres postgres }}} CentOS では postgres アカウントのUID:GIDは本来 26:26 である。後述する rpc.idmapd のバグのため、NFSサーバーのUID:GIDと一致させる。 またこの作業は PostgreSQL サーバーをインストールする前に実施するが、すでにインストールされた状態であれば、UID:GIDを変更の上、ディレクトリやファイルの所有者を探し出して変更すること。 {{{ groupmod -g 5432 postgres usermod -u 5432 -g postgres postgres find / -uid 26 -print0 | xargs -0 chown -h postgres find / -gid 26 -print0 | xargs -0 chgrp -h postgres }}} == CentOS 6.x での相互運用問題 == <> = よくある質問とその答え = == Q.ジャンボパケットで通信してますかー? == A.大丈夫だ。問題無い。(なぜ?) サーバーやクライアントはもちろんのこと、サーバーとクライアントの間を結んでいるネットワーク機器の全てでジャンボパケットに対応している必要がある。 単純にジャンボパケットが通るか(設定が正しいのか)確認するのに ping を使う。 {{{ # ping -M do -s 8972 NFSv4サーバーのIP PING NFSv4サーバーのIP (NFSv4サーバーのIP) 8972(9000) bytes of data. 8980 bytes from NFSv4サーバーのIP: icmp_seq=1 ttl=64 time=0.160 ms 8980 bytes from NFSv4サーバーのIP: icmp_seq=2 ttl=64 time=0.151 ms ^C --- NFSv4サーバーのIP ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1388ms rtt min/avg/max/mdev = 0.151/0.155/0.160/0.013 ms }}} 1バイトでもオーバーすると下記のようなメッセージが出力される。 {{{ # ping -M do -s 8973 NFSv4サーバーのIP PING NFSv4サーバーのIP (NFSv4サーバーのIP) 8973(9001) bytes of data. ping: local error: Message too long, mtu=9000 ping: local error: Message too long, mtu=9000 ^C --- NFSv4サーバーのIP ping statistics --- 2 packets transmitted, 0 received, +2 errors, 100% packet loss, time 1349ms }}} しかし、クライアントサイドは問題無くても、途中経路またはサーバーサイドにMTUミスマッチ(典型的には 1500 のまま)があると無応答となる。 この場合、サーバーサイドに問題が無いとすると、特定は非常に困難になる。 一台一台、地味に特定していく必要がある。 '''ping での通信に問題が無ければ、最低限、ネットワーク周りの設定に問題は無い。''' しかし実際にNFS通信(over TCP)がその状態で通信できているか確認するのは難しい。 特に手動で設定した直後は、設定前のMTU値で通信していることがある。 この場合、tcpdump(8)を使えば観測できなくもないが、その場合、length 8948 というパケットが観測できれば、問題無い。 {{{ # tcpdump -npiethn host NFSv4サーバーのIP : XX:XX:XX.XXXXXX IP XXX.XXX.XXX.XXX.782 > YYY.YYY.YYY.YYY.nfs: Flags [.], seq 54720:63668, ack 3705, win 1588, options [nop,nop,TS val 444521882 ecr 816267359], length 8948 : }}} 下記のように length 1448 のままだとMTU値変更が反映されていないか、サーバー側もMTU値が反映されていない可能性がある。 {{{ # tcpdump -npiethn host NFSv4サーバーのIP : XX:XX:XX.XXXXXX IP XXX.XXX.XXX.XXX.782 > XXX.XXX.XXX.XXX.nfs: Flags [.], seq 333288:334736, ack 621, win 1040, options [nop,nop,TS val 2971896848 ecr 2075608049], length 1448 : }}} そのあたり反映させるための操作が面倒なら、サーバーもクライアントも {{{shutdown -r now}}} してしまうのが吉。 = 参考文献 = * [[http://www.torutk.com/projects/swe/wiki/CentOS_6でNFS#NFSクライアントの設定|CentOS 6でNFS]] * [[https://bugzilla.redhat.com/show_bug.cgi?id=829362|Bug 829362 - wrong username/domain passed in nfs4 attribute requests]]