https://www.cnblogs.com/yeungchie/linux
它的主要功能是經過網絡(通常是局域網)讓不一樣的主機系統之間能夠共享文件或目錄。NFS客戶端能夠經過掛載(mount)的方式將NFS服務端共享的數據目錄掛載到NFS客戶端本地系統中(就是某一個掛載點下)。從NFS客戶端的機器本地看,NFS服務端共享的目錄就好像是客戶本身的磁盤分區或者目錄同樣,而實際上確是遠端的NFS服務端的目錄。NFS主要用於類Unix系統之間的共享, 最先是由Sun公司發展出來的。vim
NFS網絡文件系統相似windows系統的網絡共享、安全功能、網絡驅動器映射,這也和linux系統裏的samba服務相似。應用於互聯網中小型集羣架構後端做爲數據共享,若是是大型網站,那麼有可能還會用到更復雜的分佈式文件系統,例如Moosefs(mfs)、glusterfs、FastDFS。windows
既然NFS是經過網絡來進行服務器端和客戶端之間的數據傳輸,那麼二者之間要傳輸數據就要有相對應的網絡端口,NFS服務器到底使用哪一個端口來進行數據傳輸呢?基本上NFS這個服務的端口開在2049,但因爲文件系統很是複雜。所以NFS還有其餘的程序去啓動額外的端口,這些額外的用來傳輸數據的端口是隨機選擇的,是小於1024的端口;既然是隨機的那麼客戶端又是如何知道NFS服務器端到底使用的是哪一個端口呢?這時就須要經過遠程過程調用(Remote Procedure Call,RPC)協議來實現了!後端
NFS RPC最主要的功能就是記錄每一個NFS功能所對應的端口號,而且在NFS客戶端請求時將該端口和功能對應的信息傳遞給請求數據的NFS客戶端,讓客戶端能夠連接到正確的端口上去,從而實現數據傳輸。只在第一次創建鏈接時候幫助網絡應用程序找到正確的port,當雙方正確鏈接時,端口就和應用綁定,PPC就無用了。至關於媒婆。安全
RPC怎樣知道NFS的每一個端口呢?
緣由是,當NFS服務啓動時會隨機取用數個端口,並主動向RPC服務註冊取用的相關端口信息,這樣,RPC服務就能夠知道每一個端口所對應的NFS功能了,而後RPC服務使用固定的端口號111來監聽NFS客戶端提交的請求,並將正確的NFS端口應答給NFS客戶端,這樣一來,就可讓NFS客戶端與服務端進行數據傳輸了。服務器
提示:在啓動NFS SERVER以前,首先要啓動RPC服務(即rpcbind服務,下同)不然NFS SERVER就沒法向RPC服務註冊,另外,若是RPC服務從新啓動,原來已經註冊好的NFS端口數據就會所有丟失。所以此時RPC服務管理的NFS程序也要從新啓動以從新向RPC註冊。
特別注意:通常修改NFS配置文檔後,是不須要重啓NFS的,直接在命令執行exportfs –rv便可使修改的/etc/exports生效。網絡
客戶端NFS和服務端NFS通信過程:架構
首先服務器端啓動RPC服務,並開啓111端口app
啓動NFS服務,並向RPC註冊端口信息異步
客戶端啓動RPC(rpcbind服務),向服務端的RPC(rpcbind)服務請求服務端的NFS端口
服務端的RPC(rpcbind)服務反饋NFS端口信息給客戶端。
客戶端經過獲取的NFS端口來創建和服務端的NFS鏈接並進行數據的傳輸
[root@CentOS ~]# yum install nfs-utils
[root@CentOS ~]# yum install rpcbind
[root@CentOS ~]# service rpcbind start
[root@CentOS ~]# service nfs start
[root@CentOS ~]# chkconfig rpcbind on
[root@CentOS ~]# chkconfig nfs on
[root@CentOS ~]# chkconfig --list rpcbind [root@CentOS ~]# chkconfig --list nfs
主要的配置文件:/etc/exports
這個文件是NFS的主要配置文件,若是不存在新建這個文件,後面介紹他的用法。
NFS文件系統的維護命令:exportfs
這個是維護NFS共享資源的命令,咱們能夠利用這個命令從新共享/etc/exports更新的目錄資源、將NFS server共享的的目錄卸載或從新共享等,這是NFS系統裏面至關重要的一個命令,後面會具體介紹。
[root@CentOS ~]# vim.tiny /etc/exports /media 192.168.1.0/24(rw,sync) *(ro) #[共享目錄] [能夠訪問的主機(權限)] [*表明全部用戶(權限)]
這個配置文件很簡單,每一行前面是要共享的目錄,是以目錄爲單位。而後這個目錄能夠依照不一樣的權限共享給不一樣的主機,不一樣的主機用空格分開,主機後面是以小括號"()"定義權限參數,若權限參數不僅一個時,則以逗號","分開,而且主機名與小括號是連在一塊兒的,主機與共享目錄之間用空格分開,在這個文件內也能夠利用#號來進行註釋。
192.168.1.100
網絡號:192.169.1.0/24
或192.168.1.0/255.255.255.0
可使用主機名,但這個主機名必需要在/etc/hosts
內,或可使用DNS找到該名稱,重點是能夠找到IP地址,若是是主機名能夠支持通配符,例如*
或?
都可接受。
ro:共享目錄只讀; rw:共享目錄可讀可寫 sync:同步,將數據同步寫入內存緩衝區與磁盤中,效率低,但能夠保證數據的一致性; async:異步,將數據先保存在內存緩衝區中,必要時才寫入磁盤,效率高,但有丟失數據的風險; wdelay(默認):若是有多個客戶端要對同一個共享目錄進行寫操做,則將這些操做集中執行。對有不少小的IO寫操做時,使用該選項能夠有效的提升效率; no_wdelay:若是有多個客戶端要對同一個共享目錄進行寫操做則當即寫入。當設置了async選項時,no_wdelay選項無效,應與sync配合使用; root_squash(默認):未來訪的root用戶映射爲匿名用戶或用戶組; no_root_squash:來訪的root用戶保持root賬號權限; all_squash:全部訪問用戶都映射爲匿名用戶或用戶組; no_all_squash(默認):訪問用戶先與本機用戶匹配,匹配失敗後再映射爲匿名用戶或用戶組; anonuid=<UID>:指定匿名訪問用戶的本地用戶UID,默認爲nfsnobody(65534); anongid=<GID>:指定匿名訪問用戶的本地用戶組GID,默認爲nfsnobody(65534); secure(默認):限制客戶端只能從小於1024的tcp/ip端口鏈接服務器; insecure:容許客戶端從大於1024的tcp/ip端口鏈接服務器; subtree_check :若輸出目錄是一個子目錄,則nfs服務器將檢查其父目錄的權限; no_subtree_check(默認) :即便輸出目錄是一個子目錄,nfs服務器也不檢查其父目錄的權限,這樣能夠提升效率; hide:共享一個目錄時,不共享該目錄的子目錄; no_hide:共享子目錄;
若是想了解更多的參數,可使用man exports
NFS服務器的架設比較簡單,最大的問題在於權限方面的管理。前面已經介紹了NFS提供了ro和rw選項,能夠控制客戶端對共享文件的讀或寫權限。其實NFS共享文件的訪問權限並不只僅由這些選項決定,它由三方面控制,第一方面就是服務器端nfs配置文件裏權限參數的控制,第二方面就是服務器端文件在操做系統裏的權限控制,包括共享的目錄和裏面文件的權限,也就是文件的屬性中的rwx(讀、寫、執行)。第三方面就是客戶端,共享的目錄須要先掛載到客戶端指定的目錄上,客戶端才能經過掛在目錄訪問,因此客戶端掛載目錄的權限也起做用,就是目錄屬性中的rwx(讀、寫、執行)後面客戶端將再介紹。只有客戶端的用戶同時知足上面的三個條件才能訪問共享目錄裏面的文件。
操做系統對用戶的判斷其實並非經過用戶名,而是經過/etc/passwd文件中所記錄的UID號,因爲NFS客戶端和NFS服務器是兩臺不一樣的機器,即便他們的操做系統有相同的用戶名,其UID也不必定同樣,那麼客戶端用戶訪問NFS服務器的過程是怎樣的那?下面舉例說明下。
查看用戶UID的命令以下:
[root@CentOS ~]# id -u 用戶名
客戶端用戶訪問共享目錄文件的過程以下:
先假設客戶端用戶名爲laopi,UID暫定,用於掛載的共享目錄爲/Client目錄,用戶laopi對這個目錄的權限爲讀寫執行(目錄的執行權限是能夠進入這個目錄),服務器端共享目錄爲/Server目錄權限爲drwxr-xr-x(目錄的全部者用戶爲pipci,UID爲1000),nfs共享配置文件裏設置爲rw
當客戶端用戶laopi的UID與服務器端用戶pipci的UID相同時,即laopi的UID也爲1000,這種狀況因爲用戶laopi對掛載目錄/Client具備讀寫權執行限,nfs共享配置文件裏設置爲讀寫,NFS服務器上pipci用戶對共享目錄/Server具備讀寫執行權限,因此客戶端用戶對共享目錄/Server也具備讀寫執行權限,由於UID相同。
當客戶端用戶laopi的UID與服務器端用戶pipci的UID不一樣時,假設laopi的UID爲1010,這種狀況因爲用戶laopi對掛載目錄/Client具備讀寫權執行限,nfs共享配置文件裏設置爲讀寫,可是NFS服務器上UID爲1010的用戶對共享目錄/Server只具備讀寫權限,因此客戶端用戶對共享目錄/Server也只具備讀寫權限,由於UID爲1010的用戶對/Server目錄來講是其餘用戶。若是也想讓laopi用戶具備讀寫執行的權限能夠爲目錄/Server添加其餘用戶的執行權限
當客戶端用戶爲root,由於正常全部Linux操做系統裏的root用戶UID都爲0,因此限制權限的只有nfs共享配置文件裏設置參數了,若是權限參數有root_squash選項和rw選項,則就的看共享目錄對匿名用有什麼權限,若是權限參數root_squash改成no_root_squash選項,那就沒有限制了。
NFS服務啓動時會讀取/etc/exports配置文件中的內容,把文件中設置的共享目錄輸出供客戶端使用,在NFS服務啓動後,若是對/etc/exports進行了更改,須要經過exports命令對共享的目錄進行輸出,輸出完成後,客戶端才能訪問新設置的共享目錄。exportfs命令的用法以下:
[root@CentOS ~]# exportfs [參數]
參數:
-a :所有輸出或取消輸出/etc/exports中共享的內容 -r :從新讀取/etc/exports中的配置 -u :取消一個或多個共享目錄的輸出 -i :忽略/etc/exports中的配置,而使用默認或命令行中指定的選項 -o :經過命令添加共享目錄,重啓後失效。 -v :若是不跟其餘選項一塊兒使用,則顯示當前共享的全部目錄及他們的選項設置,若是輸出或取消輸出共享目錄,則顯示進行了那些操做。
具體例子:
[root@CentOS ~]# exportfs -v #產看因此共享目錄 [root@CentOS ~]# exportfs -rv #使/etc/exports更改的配置生效 [root@CentOS ~]# exportfs -Au #取消當前全部的共享目錄 [root@CentOS ~]# exportfs -Av #只查看/etc/exports中共享的目錄同時恢復取消的共享目錄 [root@CentOS ~]# exportfs -o rw,async 192.168.2.100:/mnt #添加共享目錄/mnt,注意命令格式-o參數後面是權限,多個權限用逗號分開,權限後面是能夠訪問的主機或網段,後面是共享的目錄,主機和共享目錄之間有冒號(:)而且不能夠有空格。 oot@debian:~# exportfs -uv 192.168.2.100:/mnt #取消exportfs命令添加的共享目錄
[root@CentOS ~]# yum install rpcbind
[root@CentOS ~]# service rpcbind start
[root@CentOS ~]# chkconfig rpcbind on
[root@CentOS ~]# chkconfig --list rpcbind
showmount
查看共享的目錄[root@CentOS ~]# showmount [選項] [主機的IP或名稱]
經常使用的選項以下:
-a:該選項通常在NFS服務器上使用,用於顯示已經掛載了服務器共享目錄的客戶端及他們所使用的共享目錄。 -d:與-A相似,但只顯示目錄,不顯示具體的客戶端。 -e:顯示指定NFS服務器輸出的共享目錄列表 -h:顯示幫助信息 -v:顯示版本信息 --no-headers:不輸出標題信息
具體例子:
root@debian:~$ showmount -e 192.168.1.102 #顯示NFS服務器192.168.1.102 輸出的共享目錄
用戶能夠自定義掛載點,而與需與NFS服務器上共享目錄同樣的路徑,用戶能夠建立多個掛載點,掛載同一個共享目錄。建立的目錄若是由使用者全權控制,使用者對掛載目錄應該有讀寫執行的權限。
掛載共享目錄使用的命令與掛載本地文件系統使用的命令同樣,都是使用mount命令,其格式以下:
[root@CentOS ~]# mount [選項] NFS服務器IP或主機名:共享目錄 掛載點
命令格式中的冒號(:
)必定不要少,他是在NFS服務器IP或主機名和共享目錄中間,沒有空格,mount命令與nfs相關選項說明以下:
-t nfs:指定要掛載的文件系統類型爲NFS,不加這個選項也能夠,mount命令會自動識別 -o ro:只掛載的文件系統爲只讀 -o rw:可讀寫 -o port=n:指定鏈接NFS服務器使用的端口號 -o retry=n:指定放棄掛載前嘗試的時間,單位爲分鐘。前臺掛載的默認值爲2,後臺掛載的默認值爲10000 -o fg:指定之前臺方式完成掛載工做。若是與NFS服務器之間的鏈接存在問題,那麼mount命令會一直重複嘗試掛載,直到成功或超時爲止。在這個過程當中,mount命令會佔用終端窗口,用戶沒法在窗口中運行其餘命令 -o bg:與fg相反,使用後臺方式完成掛載工做。若是與NFS服務器之間的鏈接存在問題,那麼mount命令會在後臺進行掛載,而不會佔用終端窗口。
注意:-o選項能夠經過逗號(,)分隔,聯合使用。
具體例子: 把NFS服務器192.168.1.102的共享目錄/media掛在到本地的/media目錄,掛載選項設置爲只讀,後臺掛載方式,放棄掛載前嘗試的時間爲1分鐘
[root@CentOS ~]# mount -t nfs -o rw,bg,retry=1 192.168.1.102:/media /media
與卸載普通的本地文件系統同樣,能夠經過umount命令把它卸載,終止與NFS服務器的鏈接。但在卸載前,應該確保已經沒有任何進程在使用該文件系統。用戶能夠經過fuser命令進行檢查。
卸載NFS文件系統的命令格式以下所示:
[root@CentOS ~]# umount [遠程文件系統或掛載點]
卸載上面例子掛載的NFS文件系統的方法:
[root@CentOS ~]# umount /media 或[root@CentOS ~]# umount 192.168.1.102:/media
linux環境下,當使用umount命令卸載掛載點時,會遇到「device is busy」提示,這時fuser就能查出誰在使用這個資源;固然umount –lf [掛載點] 也能夠強制卸載
運行下面命令看一下哪一個用戶哪一個進程佔用着此目錄,假設掛載的目錄爲/media
[root@CentOS ~]# fuser -mvu /media
運行下面命令殺掉佔用此目錄的進程
[root@CentOS ~]# fuser -mvk /media
或者fuser -mvki /media
(每殺掉一下進程會讓你確認)
選項說明:
-m name 指定一個掛載文件系統上的文件或者被掛載的塊設備(名稱name)。 -u 在每一個PID後面添加進程擁有者的用戶名稱 -v 詳細模式 -k 殺掉訪問文件的進程 -i 殺掉進程以前詢問用戶,若是沒有-k這個選項會被忽略
NFS文件系統具備動態性,即須要的時候纔有必要掛載。咱們怎麼才能夠作到僅在訪問時候才動態掛載共享目錄那,咱們用autofs服務來實現。Autofs與Mount/Umount的不一樣之處在於,它是一種看守程序。若是它檢測到用戶正試圖訪問一個還沒有掛載的文件系統,它就會自動檢測該文件系統,若是存在,那麼Autofs會自動將其掛接。另外一方面,若是它檢測到某個已掛接的文件系統在一段時間內沒有被使用,那麼Autofs會自動將其卸載。所以一旦運行了Autofs後,用戶就再也不須要手動完成文件系統的掛接和卸載。
[root@CentOS ~]# yum install autofs
[root@CentOS ~]# service autofs start
[root@CentOS ~]# chkconfig autofs on
[root@CentOS ~]# chkconfig --list autofs
掛載點父目錄 映射文件
掛載點父目錄:例如要把共享目錄掛載到本地的/media/nfsdd目錄下,那麼這個掛載點父目錄就是/media,而子目錄nfsdd並不須要手工建立,他會由autofs服務管理,在須要掛載時動態建立,這個父目錄最好是空白的,由於若是不是空的那麼當啓動這個服務時這個父目錄裏的文件會所有不可見。
映射文件:該文件是由用戶自行制定並建立(通常設置爲/etc/auto.nfs),在該文件中設置了NFS文件系統應該如何掛載。
映射文件格式以下:
掛載點 掛載選項 NFS服務器IP或主機名:共享目錄
其中掛載點爲/etc/auto.master文件中設置的父目錄下的子目錄,子目錄爲相對目錄,如上面的掛載點應該是nfsdd而不是/media/nfsdd ,掛載選項與mount命令中的選項同樣,可是選項前面須要加一個減號(-),配置文件更改後須要重啓autofs服務才能使配置生效。
先配置/etc/auto.master文件,內容以下:
/media /etc/auto.nfs
在配置映射文件/etc/auto.nfs,內容以下:
nfsdd -rw,bg,retry=1 192.168.1.102:/media
選項前面須要加一個減號(-)
配置完上面的文件重啓autofs服務
[root@CentOS ~]# systemctl restart autofs.service
在目錄/media下直接cd nfsdd就能夠完成進入nfsdd目錄而且已經掛載成功
[root@CentOS media]# cd nfsdd [root@CentOS nfsdd]#
當NFS服務器上啓用了防火牆,客戶端經過命令showmount -e 192.168.1.102查看共享的目錄可能會出現clnt_create: RPC: Port mapper failure - Unable to receive: errno 0 (Success)這個錯誤,解決的辦法有兩種,一種是直接關閉防火牆,第二種是添加策略,添加策略比較麻煩由於除了固定的端口port 111和2049以外還有不少服務開啓不固定的端口,經過下面的方法處理:
[root@CentOS ~]# rpcinfo -p program vers proto port service 100000 4 tcp 111 portmapper 100000 3 tcp 111 portmapper 100000 2 tcp 111 portmapper 100000 4 udp 111 portmapper 100000 3 udp 111 portmapper 100000 2 udp 111 portmapper 100011 1 udp 875 rquotad 100011 2 udp 875 rquotad 100011 1 tcp 875 rquotad 100011 2 tcp 875 rquotad 100005 1 udp 32923 mountd 100005 1 tcp 33612 mountd 100005 2 udp 42439 mountd 100005 2 tcp 44098 mountd 100005 3 udp 60318 mountd 100005 3 tcp 45099 mountd 100003 2 tcp 2049 nfs 100003 3 tcp 2049 nfs 100003 4 tcp 2049 nfs 100227 2 tcp 2049 nfs_acl 100227 3 tcp 2049 nfs_acl 100003 2 udp 2049 nfs 100003 3 udp 2049 nfs 100003 4 udp 2049 nfs 100227 2 udp 2049 nfs_acl 100227 3 udp 2049 nfs_acl 100021 1 udp 44604 nlockmgr 100021 3 udp 44604 nlockmgr 100021 4 udp 44604 nlockmgr 100021 1 tcp 32829 nlockmgr 100021 3 tcp 32829 nlockmgr 100021 4 tcp 32829 nlockmgr [root@CentOS ~]#
經過上面的顯示能夠看到NFS啓動了portmapper、rquotad、mountd、nfs、nlockmgr五個服務和對應的端口號, portmapper和nfs是固定端口,咱們能夠將剩下的三個服務的端口也固定下來。
RQUOTAD_PORT=875 LOCKD_TCPPORT=32829 LOCKD_UDPPORT=44604 MOUNTD_PORT=32923
注意,要把選項前面對應註釋符#號刪掉,端口號就是等號後面的數字,能夠自定義也能夠用選項默認帶的。
修改上面的配置後須要重啓nfs服務
[root@CentOS ~]# service nfs restart
[root@CentOS ~]# iptables -I INPUT -p tcp --dport 111 -j ACCEPT [root@CentOS ~]# iptables -I INPUT -p udp --dport 111 -j ACCEPT [root@CentOS ~]# iptables -I INPUT -p tcp --dport 2049 -j ACCEPT [root@CentOS ~]# iptables -I INPUT -p udp --dport 2049 -j ACCEPT [root@CentOS ~]# iptables -I INPUT -p tcp --dport 875 -j ACCEPT [root@CentOS ~]# iptables -I INPUT -p udp --dport 875 -j ACCEPT [root@CentOS ~]# iptables -I INPUT -p tcp --dport 32923 -j ACCEPT [root@CentOS ~]# iptables -I INPUT -p udp --dport 32923 -j ACCEPT [root@CentOS ~]# iptables -I INPUT -p tcp --dport 32829 -j ACCEPT [root@CentOS ~]# iptables -I INPUT -p udp --dport 44604 -j ACCEPT
開放上面的端口,客戶端就能夠正經常使用了,須要注意的是添加規則時候最好把規則添加到最前面用-I不要用-A要否則極可能被前面的規則屏蔽了。