第二十一章 NFS

在 UNIX 的世界里,二台 UNIX 系统要共享档案时,最常使用的协议是 NFS (Network File System)。NFS 是一个历史悠久的协议,它就像是 Windows 世界中的网络芳邻一样,可以让我们将另一台机器的目录当成本机的目录使用。

本章将介绍如何架设 NFS 服务器,读完本章后,您将了解下列主题:

21.1 概论

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

由于 NFS 发展已久,它和一般档案分享协议最大的差别在于 NFS 的主要程序是内建在系统核心中,而非像 Samba、FTP 等主要的程序是安装在另一套软件上。不过这不代表 NFS 不需要任何软件就可以运行,在 FreeBSD 中,它还是需要下列几支程序的帮忙:

如果您使用的是 FreeBSD 4.x,您会使用 portmap 而非 rpcbind 这支程序。

在客户端方面,要使用 NFS 服务并不需要任何 daemon,但您也可以执行 nfsiod 这支程序以提高 NFS 的效能。

21.2 NFS 设定

首先,我们要先编辑 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

21.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 的服务器操作失败时,重试几次后就不再试了。