一、NFS工作原理
1、什么是NFS服務(wù)器
NFS就是Network File System的縮寫,它最大的功能就是可以通過網(wǎng)絡(luò),讓不同的機器、不同的操作系統(tǒng)可以共享彼此的文件。
NFS服務(wù)器可以讓PC將網(wǎng)絡(luò)中的NFS服務(wù)器共享的目錄掛載到本地端的文件系統(tǒng)中,而在本地端的系統(tǒng)中來看,那個遠程主機的目錄就好像是自己的一個磁盤分區(qū)一樣,在使用上相當(dāng)便利;
2、NFS掛載原理
NFS服務(wù)器的掛載結(jié)構(gòu)圖:

如上圖示:
當(dāng)我們在NFS服務(wù)器設(shè)置好一個共享目錄/home/public后,其他的有權(quán)訪問NFS服務(wù)器的NFS客戶端就可以將這個目錄掛載到自己文件系統(tǒng)的某個掛載點,這個掛載點可以自己定義,如上圖客戶端A與客戶端B掛載的目錄就不相同。并且掛載好后我們在本地能夠看到服務(wù)端/home/public的所有數(shù)據(jù)。如果服務(wù)器端配置的客戶端只讀,那么客戶端就只能夠只讀。如果配置讀寫,客戶端就能夠進行讀寫。掛載后,NFS客戶端查看磁盤信息命令:#df –h。
既然NFS是通過網(wǎng)絡(luò)來進行服務(wù)器端和客戶端之間的數(shù)據(jù)傳輸,那么兩者之間要傳輸數(shù)據(jù)就要有想對應(yīng)的網(wǎng)絡(luò)端口,NFS服務(wù)器到底使用哪個端口來進行數(shù)據(jù)傳輸呢?基本上NFS這個服務(wù)器的端口開在2049,但由于文件系統(tǒng)非常復(fù)雜。因此NFS還有其他的程序去啟動額外的端口,這些額外的用來傳輸數(shù)據(jù)的端口是隨機選擇的,是小于1024的端口;既然是隨機的那么客戶端又是如何知道NFS服務(wù)器端到底使用的是哪個端口呢?這時就需要通過遠程過程調(diào)用(Remote Procedure Call,RPC)協(xié)議來實現(xiàn)了!
3、RPC與NFS如何通訊
因為NFS支持的功能相當(dāng)多,而不同的功能都會使用不同的程序來啟動,每啟動一個功能就會啟用一些端口來傳輸數(shù)據(jù),因此NFS的功能對應(yīng)的端口并不固定,客戶端要知道NFS服務(wù)器端的相關(guān)端口才能建立連接進行數(shù)據(jù)傳輸,而RPC就是用來統(tǒng)一管理NFS端口的服務(wù),并且統(tǒng)一對外的端口是111,RPC會記錄NFS端口的信息,如此我們就能夠通過RPC實現(xiàn)服務(wù)端和客戶端溝通端口信息。PRC最主要的功能就是指定每個NFS功能所對應(yīng)的port number,并且通知客戶端,記客戶端可以連接到正常端口上去。
那么RPC又是如何知道每個NFS功能的端口呢?
首先當(dāng)NFS啟動后,就會隨機的使用一些端口,然后NFS就會向RPC去注冊這些端口,RPC就會記錄下這些端口,并且RPC會開啟111端口,等待客戶端RPC的請求,如果客戶端有請求,那么服務(wù)器端的RPC就會將之前記錄的NFS端口信息告知客戶端。如此客戶端就會獲取NFS服務(wù)器端的端口信息,就會以實際端口進行數(shù)據(jù)的傳輸了。
提示:在啟動NFS SERVER之前,首先要啟動RPC服務(wù)(即portmap服務(wù),下同)否則NFS SERVER就無法向RPC服務(wù)區(qū)注冊,另外,如果RPC服務(wù)重新啟動,原來已經(jīng)注冊好的NFS端口數(shù)據(jù)就會全部丟失。因此此時RPC服務(wù)管理的NFS程序也要重新啟動以重新向RPC注冊。特別注意:一般修改NFS配置文檔后,是不需要重啟NFS的,直接在命令執(zhí)行/etc/init.d/nfs? reload或exportfs –rv即可使修改的/etc/exports生效。
4、NFS客戶端和NFS服務(wù)端通訊過程

1)首先服務(wù)器端啟動RPC服務(wù),并開啟111端口
2)服務(wù)器端啟動NFS服務(wù),并向RPC注冊端口信息
3)客戶端啟動RPC(portmap服務(wù)),向服務(wù)端的RPC(portmap)服務(wù)請求服務(wù)端的NFS端口
4)服務(wù)端的RPC(portmap)服務(wù)反饋NFS端口信息給客戶端。
5)客戶端通過獲取的NFS端口來建立和服務(wù)端的NFS連接并進行數(shù)據(jù)的傳輸。

二、NFS部署
1、? 查看系統(tǒng)信息
[root@server7 ~]#cat/etc/redhat-release
CentOS release 7.3.1611 (AltArch)
root@server7 ~]#uname-a
Linux server7.ctos.zu 3.10.0-514.el7.centos.plus.i686 #1SMP Wed Jan2512:55:04UTC2017i686 i686 i386 GNU/Linux
要養(yǎng)成一個習(xí)慣,就是先查看系統(tǒng)版本和內(nèi)核參數(shù)。同一個軟件在不同版本,內(nèi)核之間是有差異的,所以部署的方法也不一樣,不要因為這個而造成不必要的錯誤。
2、NFS軟件安裝
要部署NFS服務(wù),必須安裝下面兩個軟件包:nfs-utils:NFS主程序,rpcbind:PRC主程序;
NFS服務(wù)器端和Client端都需要這安裝這兩個軟件。
注意:NFS的RPC服務(wù)器,Centos5下名字為portmap,CentOS6和CentOS7下名稱為rcpbind
NFS軟件包
nfs-utils:NFS主程序,包含rpc.nfsd? rpc.mount兩個deamons
rpcbind:RPC主程序
2.1、查看NFS軟件包
?????? [root@server7 ~]# rpm -qa | egrep "nfs|rpcbind"
2.2、安裝NFS和RPC服務(wù)
?????? [root@server7 ~]# yum install nfs-utils? rpcbind
?????? [root@server7 ~]# rpm -qa? | egrep "nfs|rpcbind"
rpcbind-0.2.0-38.el7_3.1.i686
nfs-utils-1.3.0-0.33.el7_3.i686
libnfsidmap-0.25-15.el7.i686
查看這兩個軟件包在電腦里都安裝了什么文件;
[root@server7 ~]# rpm -ql nfs-utils
3、啟動NFS服務(wù)
3.1、啟動NFS服務(wù)之前先啟動rpcbind服務(wù)
查看rcpbind狀態(tài)
[root@server7 ~]# systemctl status rpcbind
● rpcbind.service - RPC bind service
?? Loaded: loaded (/usr/lib/systemd/system/rpcbind.service; indirect; vendor preset: enabled)
?? Active: active (running) since 一 2017-09-04 10:03:20 CST; 1s ago
? Process: 3583 ExecStart=/sbin/rpcbind -w $RPCBIND_ARGS (code=exited, status=0/SUCCESS)
?Main PID: 3584 (rpcbind)
?? CGroup: /system.slice/rpcbind.service
?????????? └─3584 /sbin/rpcbind -w
注:rpcbind安裝成功后默認已經(jīng)開啟,并且為開機自動啟動。如果沒有啟動的話,我們來重新啟動rcpbind服務(wù)
[root@server7 ~]# systemctl restart? rpcbind
查看PRC端口
[root@server7 ~]# yum install net-tools lsof
[root@server7 ~]# lsof? -i:111
COMMAND? PID USER?? FD?? TYPE DEVICE SIZE/OFF NODE NAME
systemd??? 1 root?? 56u? IPv6? 43164????? 0t0? TCP *:sunrpc (LISTEN)
systemd??? 1 root?? 57u? IPv4? 43165????? 0t0? TCP *:sunrpc (LISTEN)
rpcbind 3584? rpc??? 4u? IPv6? 43164????? 0t0? TCP *:sunrpc (LISTEN)
rpcbind 3584? rpc??? 5u? IPv4? 43165????? 0t0? TCP *:sunrpc (LISTEN)
rpcbind 3584? rpc??? 8u? IPv4? 44975????? 0t0? UDP *:sunrpc
rpcbind 3584? rpc?? 10u? IPv6? 44977????? 0t0? UDP *:sunrpc
[root@server7 ~]# netstat -tlunp |grep rpcbind
udp?? ?????0????? 0 0.0.0.0:111???????????? 0.0.0.0:*???????????????????????? 3584/rpcbind
udp??????? 0????? 0 0.0.0.0:791???????????? 0.0.0.0:*?????????????????????????? 3584/rpcbind
udp6?????? 0????? 0 :::111????????????????? :::*??????????? ????????????????????3584/rpcbind
udp6?????? 0????? 0 :::791????????????????? :::*??????????????????????????????? 3584/rpcbind
未啟動NFS之前查看NFS服務(wù)向PRC注冊的端口信息
[root@server7 ~]# rpcinfo -p localhost
?? 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
3.2、RPC服務(wù)啟動后再啟動NFS服務(wù)
查看狀態(tài)
[root@server7 ~]# systemctl status? nfs
?nfs-server.service - NFS server and services
?? Loaded: loaded (/usr/lib/systemd/system/nfs-server.service; disabled; vendor preset: disabled)
?? Active: inactive (dead)
默認未啟動,系統(tǒng)開機重啟后不啟動,啟動nfs服務(wù),將設(shè)置為開機啟動。
[root@server7 ~]# systemctl start nfs
[root@server7 ~]# systemctl enable nfs
Created symlink from /etc/systemd/system/multi-user.target.wants/nfs-server.service to /usr/lib/systemd/system/nfs-server.service.
[root@server7 ~]# systemctl status? nfs
● nfs-server.service - NFS server and services
?? Loaded: loaded (/usr/lib/systemd/system/nfs-server.service; enabled; vendor preset: disabled)
?? Active: active (exited) since 一 2017-09-04 10:15:21 CST; 19s ago
?Main PID: 3654 (code=exited, status=0/SUCCESS)
?? CGroup: /system.slice/nfs-server.service
啟動NFS后我們再次查看rpc注冊的端口信息
[root@server7 ~]# rpcinfo -p localhost
?? 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
??? 100024??? 1?? udp? 56626? status
??? 100024??? 1?? tcp? 42691? status
??? 100005??? 1?? udp? 20048? mountd
??? 100005??? 1?? tcp? 20048? mountd
??? 100005??? 2?? udp? 20048? mountd
??? 100005??? 2?? tcp? 20048? mountd
?? 100005??? 3?? udp? 20048? mountd
??? 100005??? 3?? tcp? 20048? mountd
??? 100003??? 3?? tcp?? 2049? nfs
??? 100003??? 4?? tcp?? 2049? nfs
??? 100227??? 3?? tcp?? 2049? nfs_acl
??? 100003??? 3?? udp?? 2049? nfs
??? 100003??? 4?? udp?? 2049? nfs
??? 100227??? 3?? udp?? 2049? nfs_acl
??? 100021??? 1?? udp? 57225? nlockmgr
??? 100021??? 3?? udp? 57225? nlockmgr
??? 100021??? 4?? udp? 57225? nlockmgr
?? 100021??? 1?? tcp? 35665? nlockmgr
??? 100021??? 3?? tcp? 35665? nlockmgr
? 100021??? 4?? tcp? 35665? nlockmgr
在確認啟動沒用問題后我們看一看NFS到底開了哪些端口
[root@server7 ~]# netstat -tulnp |grep -E '(rpc|nfs)'
tcp??????? 0????? 0 0.0.0.0:42691?????????? 0.0.0.0:*???????????? ??LISTEN????? 3634/rpc.statd
tcp??????? 0????? 0 0.0.0.0:20048?????????? 0.0.0.0:*?????????????? LISTEN????? 3642/rpc.mountd
tcp6?????? 0????? 0 :::39614??????????????? :::*??????????????????? LISTEN????? 3634/rpc.statd
tcp6?????? 0????? 0 :::20048??????????????? :::*??????????????????? LISTEN????? 3642/rpc.mountd
udp??????? 0????? 0 127.0.0.1:842?????????? 0.0.0.0:*?????????????????????????? 3634/rpc.statd
udp??????? 0????? 0 0.0.0.0:20048?????????? 0.0.0.0:* ??????????????????????????3642/rpc.mountd
udp??????? 0????? 0 0.0.0.0:111???????????? 0.0.0.0:*?????????????????????????? 3584/rpcbind
udp??????? 0????? 0 0.0.0.0:791???????????? 0.0.0.0:*?????????????????????????? 3584/rpcbind
udp??? ????0????? 0 0.0.0.0:56626?????????? 0.0.0.0:*?????????????????????????? 3634/rpc.statd
udp6?????? 0????? 0 :::56122??????????????? :::*??????????????????????????????? 3634/rpc.statd
udp6?????? 0????? 0 :::20048??????????????? :::*???????????? ???????????????????3642/rpc.mountd
udp6?????? 0????? 0 :::111????????????????? :::*??????????????????????????????? 3584/rpcbind
udp6?????? 0????? 0 :::791????????????????? :::*??????????????????????????????? 3584/rpcbind
4、NFS常見進程詳解
[root@server7 ~]# ps -ef |egrep "rpc|nfs“
rpc?????? 3584???? 1? 0 10:03 ???????? 00:00:00 /sbin/rpcbind -w
rpcuser?? 3634???? 1? 0 10:15 ???????? 00:00:00 /usr/sbin/rpc.statd --no-notify
root????? 3637???? 2? 0 10:15 ???????? 00:00:00 [rpciod]
root????? 3642???? 1? 0 10:15 ???????? 00:00:00 /usr/sbin/rpc.mountd
root????? 3652???? 1? 0 10:15 ???????? 00:00:00 /usr/sbin/rpc.idmapd
root????? 3657???? 2? 0 10:15 ???????? 00:00:00 [nfsd4_callbacks]
root????? 3663???? 2? 0 10:15 ???????? 00:00:00 [nfsd]
root????? 3664???? 2? 0 10:15 ???????? 00:00:00 [nfsd]
root????? 3665 ????2? 0 10:15 ???????? 00:00:00 [nfsd]
root????? 3666???? 2? 0 10:15 ???????? 00:00:00 [nfsd]
root????? 3667???? 2? 0 10:15 ???????? 00:00:00 [nfsd]
root????? 3668???? 2? 0 10:15 ???????? 00:00:00 [nfsd]
root????? 3669???? 2? 0 10:15 ???????? 00:00:00 [nfsd]
root????? 3670???? 2? 0 10:15 ???????? 00:00:00 [nfsd]
root????? 3705? 3267? 0 10:23 pts/0??? 00:00:00 grep -E --color=auto rpc|nfs
nfsd
最主要的NFS服務(wù)提供程序,這個daemon主要的功能就是管理客戶端是否能夠使用服務(wù)器文件系統(tǒng)掛載信息,其中還包含判斷這個登錄用戶的ID。
? rpc.mountd
這個daemon主要功能則是管理NFS的文件系統(tǒng)。當(dāng)client端順利通過rpc.nfsd登入主機后,在它可以使用NFS服務(wù)器提供規(guī)定文件之前,還會經(jīng)過文件使用權(quán)限的認證程序。它會去讀取NFS的配置 文件/etc/exports來對比客戶端的權(quán)限,當(dāng)通過這一關(guān)之后,client端也就取得使用NFS文件的權(quán)限。
? rpc.lockd (非必要)
這個daemon用于管理文件的鎖定方面,當(dāng)多個客戶端同時嘗試寫入某個文件時就可以對該文件造成一些問題。rpc.lockd則可以用來克服這此問題。但rpc.lockd必須要同時在客戶端和服務(wù)器端都開 啟才行。
?rpc.statd(非必要)
這個daemon可以用來檢查文件的一致性,若發(fā)生因為客戶端同時使用同一個文件造成文件損壞時,rpc.statd可以用來檢測并嘗試恢復(fù)該文件
5、配置NFS服務(wù)
NFS軟件很簡單,主要配置文件:/etc/exports,默認這個里面內(nèi)容是空的,如果沒有這個文件,可以使用vim主動建立這個文件。至于NFS服務(wù)器的搭建也很簡單,只要編輯好主要配置文件/etc/exports之后,先啟動rpcbind(若已經(jīng)啟動了,就不要重新啟動),然后再啟動nfs,NFS就成功了。
???? 那么/etc/exports應(yīng)該如何設(shè)置?
[root@server7 etc]# vi /etc/exports
/tmp/data?? ???192.168.1.0/24(ro)?? ???????client-A.ctos.zu(rw,sync)
#[共享目錄]?? [客戶端地址1(權(quán)限)] ??? ???[客戶端地址2(權(quán)限)]
以上是一個簡單案例配置,每一行最前面是要共享出來的目錄,注意是以目錄為單位的
共享目錄:存在于我們本機上的目錄,我們想共享給網(wǎng)絡(luò)上的其他主機使用。如我要共享/tmp/data目錄,那么此選項可以就直接寫/tmp/data目錄,這個目錄可以依照不同的權(quán)限共享給不同的主機。
客戶端地址1(參數(shù)1,參數(shù)2):客戶端地址能夠設(shè)置一個網(wǎng)絡(luò),也可以設(shè)置單個主機。參數(shù):如讀寫權(quán)限r(nóng)w,同步更新sync,壓縮來訪賬號all_squash,壓縮后的匿名賬號anonuid=uid,anongid=gid等等;
客戶端地址的設(shè)置主要有以下幾種方式:
1)、 可以使用完整的IP或者是網(wǎng)絡(luò)號,例如192.168.100.100 或 192.168.8.0/24
2)、 可以使用主機名,但這個主機名必須要在/etc/hosts內(nèi),或可以使用DNS找到該名稱才行,反正重點是可找到IP就行,如果是主機名的話,還可以支持通配符,例如‘*’或‘?’均可接受;例如:host[1-8].ctos.zu,server?.test.com
NFS權(quán)限設(shè)置
NFS配置權(quán)限設(shè)置,即/etc/exports文件配置格式中小括號()里的參數(shù)集;
參數(shù)命令參數(shù)用途
rw表示可讀寫
roRead-only表示只能讀權(quán)限
Sync請求或者寫入數(shù)據(jù)時,數(shù)據(jù)同步寫入到NFS server的硬盤中后才會返回
no_root_squas訪問nfs server共享目錄的用戶如果是root的話,它對該目錄具有root權(quán)限。這個配置原本為無盤用戶準備的。用戶應(yīng)避免使用!
root_squash對于訪問NFS server共享目錄的用戶,如果是root的話會被壓縮成為nobody用戶身份。
all_squash不管訪問nfs server共享目錄的用戶身份如何包括root,它的權(quán)限都將被壓縮成為匿名用戶,同時他們的udi和gid都會變成nobody或nfsnobody賬戶的uid,gid。在多個nfs客戶端同時讀寫nfs server數(shù)據(jù)時,這個參數(shù)很有用可以確保大家寫入的數(shù)據(jù)的權(quán)限是一樣的。
但不同系統(tǒng)有可能匿名用戶的uid,gid不同。因為此處我們需要服務(wù)端和客戶端之間的用戶是一樣的。比如說:服務(wù)端指定匿名用戶的UID為2000,那么客戶端也一定要存在2000這個賬號才可以
anonuidanonuid就是匿名的uid和gid。說明客戶端以什么權(quán)限來訪問服務(wù)端,在默認情況下是nfsnobody。Uid65534.
anongid同anongid,就是把uid換成gid而已
配置實例:
/home/test ?1192.168.1.0/24(rw,sync,all_squash,anonuid=2000,anongid=2000)
###注意紅色部分不能有空格!!生產(chǎn)環(huán)境中常用的一種配置,適合多客戶端共享一個NFS目錄。All_squash 也就是說不管客戶端是以什么樣的身份來進行訪問的,都會被壓縮成為all_squash后面所接的用戶和群組身份。這邊用anonuid、anongid編號來標示。=
小結(jié):
服務(wù)器共享配置格式:
1)基本格式:共享目錄 ip/24(共享屬性) ?->注意無空格
2)共享權(quán)限設(shè)置:
rw讀寫屬性
sync文件實際寫入磁盤后才返回
all_squash:所有訪問用戶均被壓縮成后續(xù)接的用戶。
anonuid:默認壓縮的用戶
anongid:默認壓縮的用戶組
那么客戶端以什么身份來訪問?
客戶端訪問服務(wù)端默認是使用nfsnobody這個用戶來進行訪問的。uid和gid為65534。服務(wù)器默認共享時,也是加上了all_squash這個參數(shù)。并制定anonuid為65534(也就是nfsnobayd用戶)。當(dāng)然如果系統(tǒng)中nfsnobody是其他的uid,那么就有可能造成訪問權(quán)限出現(xiàn)問題。所以最好我們可以通過一設(shè)置一個用戶來訪問,統(tǒng)一UID、GID。
掛載情況怎樣呢?
有兩個重要的文件,能夠解決這個疑問。/var/lib/nfs/etab、/var/lib/nfs/rmtab這兩個文件就能夠查看服務(wù)器上共享了什么目錄,到底有多少客戶端掛載了共享,能查看到客戶端掛載的具體信息。
1、etab這個文件能看到服務(wù)器上共享了哪些目錄,執(zhí)行哪些人可以使用,并且設(shè)定的參數(shù)為何。
2、rmtab這個文件就是能夠查看到共享目錄被掛載的情況。