第二十一章 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 的伺服器操作失敗時,重試幾次後就不再試了。