第十八章 NFS

18.1 概论

NFS 是 Network File System。NFS 就好像是 UNIX 系统中的网络芳邻,您可以使用 NFS 将服务器上的资料夹汇出,让其它 UNIX 主机可以将所汇出的数据夹挂入。当您有多台 UNIX 主机时,使用 NFS 可以让您共享同一个数据夹。如此一来,同一份数据就不必放在多台机器上,而可以经由 NFS 来节省空间并达到数据的同步。

18.2 NFS 设定

使用 NFS,我们必须启动三个 Daemon,nfsd、mountd、及 portmap。nfsd 用以接收 NFS client 所传来的联机要求。当接到联机要求时,nfsd 会将联机的请求交由 mountd 来执行。而 portmap 是用来让 client 端可以正确找到 NFS server 所开放的 port,以使 client 能找到 server 上正确的联机窗口。

首先,我们要先编辑 server 端的 /etc/rc.conf ,并加入下列的设定:

# 如果您使用 FreeBSD 4.x,请使用 portmap_enable。
portmap_enable="YES"
# 由于 FreeBSD 5.x 中,portmap 这支程序己被取代为 rpcbind,
# 所以如果您使用 FreeBSD 5.x,请使用 rpcbind_enable。
rpcbind_enable="YES"
nfs_server_enable="YES"
nfs_server_flags="-u -t -n 4"
mountd_enable="YES"
mountd_flags="-r"

在选项 nfs_server_flags 中,-u 表示我们提供 UDP 方式联机,而 -t 表示以 TCP 方式联机。如果您所要使用 NFS 的 client 都是 FreeBSD,您可以只以 TCP 联机,如此可以有较佳的效能。-n 4 表示我们一次打开四个 nfsd 的 daemon。

接着我们要设定 /etc/exports,这个档案是用来设定我们所要分享的数据夹及其权限。/etc/exports 可能长得像这个样子。

/usr/src /usr/local     -maproot=root
/home      -alldirs    -maproot=root  -network  192.168.0.0  -mask  255.255.255.0
/cdrom    -ro    -mapall=alex

第一个字段为所要分享的目录,如果所要分享的目录位于同一个 slice 上,则必须写在同一行。例如我们要分享的目录是 /usr/src 及 /usr/local,因为这二个目录位于同一个硬盘的分割区上,所以必须写在同一行,也就是说同一个分割区只有一种权限。在目录之后,我们会指定一些设定权限的参数,其意义如下:

参数 意义
-ro 表示 read only,只读。
-maproot=user 如果 client 以 root 存取,则将它的权限对映成本机 user 的权限。
-mapall=user 将所有 client 的存取联机对映到 user,也就是说所有人的身份都转成 user。
-alldirs 可以让使用者将该分享数据夹的任一目录做为 mount point。也就是说当我们分享的是 /usr 时,client 也可以将 /usr/include 当成挂入点来 mount。但前提是 /usr 必须是一个独立的 filesystem,也就是说 /usr 必须是独立分割成一个 slice。
-network IP -mask MASK  指定允许联机的网域。

您可以 man exports 来获得更多关于 exports 格式的信息。我们每次设定完 /etc/exports 都必须以下列指令重新启动 mountd:

# kill -HUP `cat /var/run/mountd.pid`

不过由于我们是第一次设定,所以连 mountd 都还没有启动,所以你可以选择重新开机或是执行下列指令来启动 NFS 服务。

首先是启动 RPC port map,如果您是使用 FreeBSD 4.x,请将下列 rpcbind 指令改为 portmap

# rpcbind
# nfsd -u -t -n 4
# mountd -r

完成了 Server 端的设定后,我们还要做 client 端的设定。在 client 端的 rc.conf 中,我们要加入下列的设定:

nfs_client_enable="YES"
nfs_client_flags="-n 4"

当设定了 nfs_client_enable 为 YES 后,在开机时即会自动启动 nfsiod ,而这里的 -n 4 和 server 的设定一样,代表我们一次要启动四份 nfsiod 来做 nfs 联机。我们不一定要在 NFS client 启动 nfsiod,如果没有 nfsiod,照样可以使用,但 nfsiod 可以提高联机效率。

设定完 rc.conf 后,要重新开机才会生效,同样的,如果您不想重新开机,你可以手动执行下列指令来让 nfs client 生效:

# nfsiod -n 4

现在我们可以开始使用 NFS 了。首先,我们可以使用 showmount 这个指令来查看 server 上有哪些分享的数据夹,假设 NFS server为 192.168.1.1:

# showmount -e 192.168.1.1
Exports list on 192.168.1.1:
/home Everyone
/usr 192.168.1.2

接着我们就可以将想要挂入的数据夹 mount 进来:

# mount 192.168.1.1:/home /mnt

如果您要想在一开机就将该数据夹挂入,您可以编辑 /etc/fstab,并加入下列设定:

192.168.1.1:/home   /mnt    nfs rw  0   0

18.3 NFS 的限制

在使用 NFS 时,有些事我们必须特别注意。如果您 NFS server 负担相当重,也许你会发现该服务器时常没有响应,而 client 端也会因此而无法动作。这并非 FreeBSD 独有的问题,使用 NFS 时,网络卡的选择及网络整体的品质很重要。否则在 client 和 server 系统负担不一时,很容易产生没有响应的情形。

有时候我们将 mount 某台服务器的数据夹,但如果该服务器关机或是停止 NFS 服务,当您 ls 所挂入的目录时,整台机器会因而停止动作。此时除非该 NFS 服务器又开启,否则您只能重新启动了。因此,建议您 mount NFS 并完成所需的存取动作后,就立即 umount,才不会使 client hang 住。如果您希望当所 mount 的服务器发生问题时,本机可以不受到影响,您可以改用 mount_nfs 指令并加上参数 -i 及 -s。

# mount_nfs -s -i 192.168.1.1:/home /mnt

参数 -i 允许我们在使用 Ctrl+C 来中断 mount 的动作。参数 -s 是使用 soft mount 模式,当档案系统对于所 mount 的服务器操作失败时,重试几次后就不再试了。