介紹如何在 Ubuntu Linux 中安裝 NFS 伺服器,並設定 NFS 用戶端,讓多台 Linux 主機共享檔案。

NFS(Network File Share)是 Linux 系統上常用的檔案分享協定,可以讓 Linux 系統上的目錄與檔案分享給網路上其他台 Linux 主機,以下是在 Ubuntu Linux 中安裝與設定 NFS 伺服器與用戶端的步驟教學。

安裝 NFS 伺服器

在 Ubuntu Linux 中若要安裝 NFS 伺服器,可以透過 apt 安裝 nfs-kernel-server 套件:

# 安裝 NFS 伺服器
sudo apt install nfs-kernel-server

安裝好 NFS 伺服器套件之後,該服務會自動啟動,我們可以透過以下指令查看、啟動或停止 NFS 伺服器服務:

# 查看 NFS 伺服器服務狀態
systemctl status nfs-server

# 啟動 NFS 伺服器服務狀態
systemctl start nfs-server

# 停止 NFS 伺服器服務狀態
systemctl stop nfs-server

# 重新啟動 NFS 伺服器服務狀態
systemctl restart nfs-server

我們可以透過 /proc/fs/nfsd/versions 這個檔案來查看 NFS 伺服器支援的 NFS 版本:

# 查看 NFS 伺服器支援的 NFS 版本
sudo cat /proc/fs/nfsd/versions
-2 +3 +4 +4.1 +4.2

以這個例子來說,NFS 伺服器支援的 NFS 版本有 344.14.2

NFS 伺服器的設定檔位於 /etc/default/nfs-kernel-server/etc/default/nfs-common,但大部分的狀況下使用預設的設定即可,不需要更改。

建立共享目錄

安裝好基本的 NFS 伺服器之後,接著要建立一個要進行分享的共享目錄,隨後 NFS 用戶端就可以透過 NFS 存取放在共享目錄之下的資料。

NFSv4 跟以往舊版的 NFS 不同,其使用 global root directory 的設計,這個目錄之下在 NFSv4 之中是一個虛擬的檔案系統,所有分享出去的目錄都放在這個根目錄之下,我們可以透過 mount 搭配 --bind 參數,將系統上要分享的目錄都掛載到這個虛擬檔案系統中。

這裡我們打算建立一個 /export 目錄,並將其設定為 global root directory,在這個目錄中建立各個共享目錄:

# 建立 export 根目錄
sudo mkdir /export

# 建立各個共享目錄
sudo mkdir /export/home
sudo mkdir /export/data

# 掛載目錄至 NFSv4 虛擬檔案系統
sudo mount --bind /home /export/home
sudo mount --bind /opt/data /export/data

測試掛載成功之後,可以將設定寫進 /etc/fstab 設定檔中,讓重新開機之後可以自動掛載:

# /etc/fstab 設定自動掛載目錄至 NFSv4 虛擬檔案系統
/home      /export/home  none  bind  0  0
/opt/data  /export/data  none  bind  0  0

設定 NFS 存取主機與權限

編輯 /etc/exports 設定檔,設定可存取 NFS 服務的網路主機與對應的權限:

# 設定 /export 為根錄目
/export 192.168.1.0/24(rw,fsid=,no_subtree_check,sync)

# 設定可存取 NFS 的主機與權限
/export/home 192.168.1.0/24(rw,root_squash,no_subtree_check,sync)
/export/data 192.168.1.0/24(ro,no_root_squash,no_subtree_check,async) 192.168.1.3(rw,sync,no_subtree_check)

這裡我們將 /export 設定為根錄目(fsid=0 就是設定為根目錄的意思),僅允許 192.168.1.0/24 網段的主機可以存取此目錄。

/export/home 允許 192.168.1.0/24 網段的主機可以存取,另外設定 root_squash 是將 root 的 UID/GID(也就是 0)轉換為匿名的 UID/GID(例如 nobody),避免用戶端的 root 權限直接影像到 NFS 伺服器的檔案。

/export/data 則是允許 192.168.1.0/24 網段的主機可以讀取,而 192.168.1.3 這台主機則是可以讀取與寫入。

關於 /etc/exports 設定檔的語法,可以參考 exports 的線上手冊。

# 查詢 exports 線上手冊
man exports

設定好 /etc/exports 之後,讓 NFS 伺服器重新載入設定:

# 重新載入 /etc/exports 設定
sudo exportfs -ar

接著顯示目前 NFS 伺服器的 export 設定:

# 顯示 NFS 伺服器 export 設定
sudo exportfs -v
/export/data    192.168.1.3(rw,wdelay,root_squash,no_subtree_check,sec=sys,rw,secure,root_squash,no_all_squash)
/export         192.168.1.0/24(rw,wdelay,root_squash,no_subtree_check,fsid=0,sec=sys,rw,secure,root_squash,no_all_squash)
/export/home    192.168.1.0/24(rw,wdelay,root_squash,no_subtree_check,sec=sys,rw,secure,root_squash,no_all_squash)
/export/data    192.168.1.0/24(ro,async,wdelay,no_root_squash,no_subtree_check,sec=sys,ro,secure,no_root_squash,no_all_squash)

exportfs 的輸出中列出許多的選項設定值,比我們在設定檔中所指定的設定還要多,多出來的部分就是系統預設的設定值。

另外 showmount 指令也可以查詢指定 NFS 伺服器所分享出來的目錄,假設 NFS 伺服器的 IP 位址為 192.168.1.5,則可利用以下指令查詢該台 NFS 伺服器所分享出來的目錄:

# 查詢 192.168.1.5 所 export 出來的 NFS 目錄
showmount -e 192.168.1.5
Export list for 192.168.1.5:
/export/home 192.168.1.0/24
/export      192.168.1.0/24
/export/data 192.168.1.0/24

NFS 伺服器防火牆

如果在 Ubuntu Linux 中有啟用 ufw 防火牆,則需要加入允許 NFS 連線的設定:

# 允許來自於 192.168.1.0/24 的 NFS 連線
sudo ufw allow from 192.168.1./24 to any port nfs

設定好之後,查看目前防火牆狀態:

# 查看 Ubuntu Linux 防火牆狀態
sudo ufw status

設定 NFS 用戶端

在要存取 NFS 服務的主機上,安裝 NFS 用戶端的套件:

# 安裝 NFS 用戶端套件(Ubuntu/Debian)
sudo apt install nfs-common

# 安裝 NFS 用戶端套件(RedHat/CentOS/Fedora)
sudo yum install nfs-utils

建立掛載用的目錄:

# 建立掛載用目錄
sudo mkdir /mnt/home
sudo mkdir /mnt/data

假設 NFS 伺服器 IP 位址為 192.168.1.5,執行以下指令將 NFS 伺服器上的 /home/data 兩個虛擬目錄,掛載至 /mnt/home/mnt/data 目錄上:

# 掛載 NFS 磁碟
sudo mount -t nfs 192.168.1.5:/home /mnt/home
sudo mount -t nfs 192.168.1.5:/data /mnt/data

mount 指令查看目前檔案系統的掛載狀態:

# 查看目前檔案系統掛載狀態
mount
[略]
192.168.1.5:/home on /mnt/home type nfs4 (rw,relatime,vers=4.2,rsize=1048576,wsize=1048576,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=192.168.1.2,local_lock=none,addr=192.168.1.5)
192.168.1.5:/data on /mnt/data type nfs4 (rw,relatime,vers=4.2,rsize=1048576,wsize=1048576,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=192.168.1.2,local_lock=none,addr=192.168.1.5)

或是以 df 指令查看掛載狀態也可以:

# 查看目前檔案系統掛載狀態
df -h
Filesystem         Size  Used Avail Use% Mounted on
[略]
192.168.1.5:/home   94G  6.1G   84G   7% /mnt/home
192.168.1.5:/data   94G  6.1G   84G   7% /mnt/data

若要讓系統開機自動掛載,可以將 NFS 掛載設定寫入 /etc/fstab 檔案中:

# NFS 掛載設定
192.168.1.5:/home /mnt/home   nfs   defaults,_netdev    0 0
192.168.1.5:/data /mnt/data   nfs   defaults,_netdev    0 0

其中 _netdev 參數是指名此檔案系統的掛載需要網路,防止系統在網路尚未啟動的狀態下嘗試掛載。

避免掛載失敗無法開機

開機自動掛載 NFS 磁碟雖然方便,但若 NFS 磁碟掛載失敗時,有可能會造成無法開機的狀況,若想要避免這樣的狀況,可以加上 nofail 參數,讓掛載失敗時也不會出現錯誤:

# NFS 掛載設定(忽略掛載失敗的錯誤)
192.168.1.5:/home /mnt/home   nfs   defaults,nofail,_netdev    0 0
192.168.1.5:/data /mnt/data   nfs   defaults,nofail,_netdev    0 0

另外一種方式是改用 noauto 參數,讓系統不要再開機時自動掛載,由管理者手動執行 mount 掛載:

# NFS 掛載設定(手動掛載)
192.168.1.5:/home /mnt/home   nfs   defaults,noauto,_netdev    0 0
192.168.1.5:/data /mnt/data   nfs   defaults,noauto,_netdev    0 0

在這樣的設定之下,我們可以使用以下指令進行手動掛載:

# 手動掛載 NFS 磁碟
sudo mount /mnt/home
sudo mount /mnt/data

或是直接掛載所有 /etc/fstab 中的磁碟:

# 手動掛載所有磁碟
sudo mount -a

跟原本的指令比較起來,可以少打一些字。

以 NFSv3 掛載

在掛載 NFS 檔案系統時,預設會以較新的 NFS 版本來掛載,如果要使用舊版的 NFS 來掛載,可以在掛載時指定 NFS 版本,例如指定以 NFSv3 進行掛載:

# 以 NFSv3 掛載 NFS 磁碟
sudo mount -t nfs -o nfsvers=3 192.168.1.5:/home /mnt/home
sudo mount -t nfs -o nfsvers=3 192.168.1.5:/data /mnt/data

而對應的 /etc/fstab 則為:

# 以 NFSv3 掛載 NFS 磁碟
192.168.1.5:/home /mnt/home   nfs   defaults,nfsvers=3,_netdev    0 0
192.168.1.5:/data /mnt/data   nfs   defaults,nfsvers=3,_netdev    0 0

參考資料