一、NFS工作原理
1、什么是NFS服務器
NFS就是Network File System的縮寫,它最大的功能就是可以通過網絡,讓不同的機器、不同的操作系統可以共享彼此的文件。
NFS服務器可以讓PC將網絡中的NFS服務器共享的目錄掛載到本地端的文件系統中,而在本地端的系統中來看,那個遠程主機的目錄就好像是自己的一個磁盤分區一樣,在使用上相當便利;
2、NFS掛載原理
NFS服務器的掛載結構圖:
如上圖示:
當我們在NFS服務器設置好一個共享目錄/home/public后,其他的有權訪問NFS服務器的NFS客戶端就可以將這個目錄掛載到自己文件系統的某個掛載點,這個掛載點可以自己定義,如上圖客戶端A與客戶端B掛載的目錄就不相同。並且掛載好后我們在本地能夠看到服務端/home/public的所有數據。如果服務器端配置的客戶端只讀,那么客戶端就只能夠只讀。如果配置讀寫,客戶端就能夠進行讀寫。掛載后,NFS客戶端查看磁盤信息命令:#df –h。
既然NFS是通過網絡來進行服務器端和客戶端之間的數據傳輸,那么兩者之間要傳輸數據就要有想對應的網絡端口,NFS服務器到底使用哪個端口來進行數據傳輸呢?基本上NFS這個服務器的端口開在2049,但由於文件系統非常復雜。因此NFS還有其他的程序去啟動額外的端口,這些額外的用來傳輸數據的端口是隨機選擇的,是小於1024的端口;既然是隨機的那么客戶端又是如何知道NFS服務器端到底使用的是哪個端口呢?這時就需要通過遠程過程調用(Remote Procedure Call,RPC)協議來實現了!
3、RPC與NFS如何通訊
因為NFS支持的功能相當多,而不同的功能都會使用不同的程序來啟動,每啟動一個功能就會啟用一些端口來傳輸數據,因此NFS的功能對應的端口並不固定,客戶端要知道NFS服務器端的相關端口才能建立連接進行數據傳輸,而RPC就是用來統一管理NFS端口的服務,並且統一對外的端口是111,RPC會記錄NFS端口的信息,如此我們就能夠通過RPC實現服務端和客戶端溝通端口信息。PRC最主要的功能就是指定每個NFS功能所對應的port number,並且通知客戶端,記客戶端可以連接到正常端口上去。
那么RPC又是如何知道每個NFS功能的端口呢?
首先當NFS啟動后,就會隨機的使用一些端口,然后NFS就會向RPC去注冊這些端口,RPC就會記錄下這些端口,並且RPC會開啟111端口,等待客戶端RPC的請求,如果客戶端有請求,那么服務器端的RPC就會將之前記錄的NFS端口信息告知客戶端。如此客戶端就會獲取NFS服務器端的端口信息,就會以實際端口進行數據的傳輸了。
提示:在啟動NFS SERVER之前,首先要啟動RPC服務(即portmap服務,下同)否則NFS SERVER就無法向RPC服務區注冊,另外,如果RPC服務重新啟動,原來已經注冊好的NFS端口數據就會全部丟失。因此此時RPC服務管理的NFS程序也要重新啟動以重新向RPC注冊。特別注意:一般修改NFS配置文檔后,是不需要重啟NFS的,直接在命令執行/etc/init.d/nfs reload或exportfs –rv即可使修改的/etc/exports生效。
4、NFS客戶端和NFS服務端通訊過程
1)首先服務器端啟動RPC服務,並開啟111端口
2)服務器端啟動NFS服務,並向RPC注冊端口信息
3)客戶端啟動RPC(portmap服務),向服務端的RPC(portmap)服務請求服務端的NFS端口
4)服務端的RPC(portmap)服務反饋NFS端口信息給客戶端。
5)客戶端通過獲取的NFS端口來建立和服務端的NFS連接並進行數據的傳輸。
二、NFS部署
1、 查看系統信息
[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 #1 SMP Wed Jan 25 12:55:04 UTC 2017 i686 i686 i386 GNU/Linux
要養成一個習慣,就是先查看系統版本和內核參數。同一個軟件在不同版本,內核之間是有差異的,所以部署的方法也不一樣,不要因為這個而造成不必要的錯誤。
2、NFS軟件安裝
要部署NFS服務,必須安裝下面兩個軟件包:nfs-utils:NFS主程序,rpcbind:PRC主程序;
NFS服務器端和Client端都需要這安裝這兩個軟件。
注意:NFS的RPC服務器,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"
[root@server7 ~]#
我的CentOS release 7.3.1611是最小化安裝,默認沒有安裝nfs和rpcbind
Yum搜尋下安裝包是否存在
[root@server7 ~]# yum search nfs-utils rpcbind
2.2、安裝NFS和RPC服務
[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服務
3.1、啟動NFS服務之前先啟動rpcbind服務
查看rcpbind狀態
[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
9月 04 10:03:19 server7.ctos.zu systemd[1]: Starting RPC bind service...
9月 04 10:03:20 server7.ctos.zu systemd[1]: Started RPC bind service.
注:rpcbind安裝成功后默認已經開啟,並且為開機自動啟動。如果沒有啟動的話,我們來重新啟動rcpbind服務
[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服務向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服務啟動后再啟動NFS服務
查看狀態
[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)
默認未啟動,系統開機重啟后不啟動,啟動nfs服務,將設置為開機啟動。
[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
9月 04 10:15:21 server7.ctos.zu systemd[1]: Starting NFS server and services...
9月 04 10:15:21 server7.ctos.zu systemd[1]: Started NFS server and services.
啟動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服務提供程序,這個daemon主要的功能就是管理客戶端是否能夠使用服務器文件系統掛載信息,其中還包含判斷這個登錄用戶的ID。
- rpc.mountd
這個daemon主要功能則是管理NFS的文件系統。當client端順利通過rpc.nfsd登入主機后,在它可以使用NFS服務器提供規定文件之前,還會經過文件使用權限的認證程序。它會去讀取NFS的配置 文件/etc/exports來對比客戶端的權限,當通過這一關之后,client端也就取得使用NFS文件的權限。
- rpc.lockd (非必要)
這個daemon用於管理文件的鎖定方面,當多個客戶端同時嘗試寫入某個文件時就可以對該文件造成一些問題。rpc.lockd則可以用來克服這此問題。但rpc.lockd必須要同時在客戶端和服務器端都開 啟才行。
- rpc.statd(非必要)
這個daemon可以用來檢查文件的一致性,若發生因為客戶端同時使用同一個文件造成文件損壞時,rpc.statd可以用來檢測並嘗試恢復該文件
5、配置NFS服務
NFS軟件很簡單,主要配置文件:/etc/exports,默認這個里面內容是空的,如果沒有這個文件,可以使用vim主動建立這個文件。至於NFS服務器的搭建也很簡單,只要編輯好主要配置文件/etc/exports之后,先啟動rpcbind(若已經啟動了,就不要重新啟動),然后再啟動nfs,NFS就成功了。
那么/etc/exports應該如何設置?
[root@server7 etc]# vi /etc/exports
/tmp/data 192.168.1.0/24(ro) client-A.ctos.zu(rw,sync)
#[共享目錄] [客戶端地址1(權限)] [客戶端地址2(權限)]
以上是一個簡單案例配置,每一行最前面是要共享出來的目錄,注意是以目錄為單位的
共享目錄:存在於我們本機上的目錄,我們想共享給網絡上的其他主機使用。如我要共享/tmp/data目錄,那么此選項可以就直接寫/tmp/data目錄,這個目錄可以依照不同的權限共享給不同的主機。
客戶端地址1(參數1,參數2):客戶端地址能夠設置一個網絡,也可以設置單個主機。參數:如讀寫權限rw,同步更新sync,壓縮來訪賬號all_squash,壓縮后的匿名賬號anonuid=uid,anongid=gid等等;
客戶端地址的設置主要有以下幾種方式:
1)、 可以使用完整的IP或者是網絡號,例如192.168.100.100 或 192.168.8.0/24
2)、 可以使用主機名,但這個主機名必須要在/etc/hosts內,或可以使用DNS找到該名稱才行,反正重點是可找到IP就行,如果是主機名的話,還可以支持通配符,例如‘*’或‘?’均可接受;例如:host[1-8].ctos.zu,server?.test.com
NFS權限設置
NFS配置權限設置,即/etc/exports文件配置格式中小括號()里的參數集;
參數命令 |
參數用途 |
rw |
表示可讀寫 |
ro |
Read-only表示只能讀權限 |
Sync |
請求或者寫入數據時,數據同步寫入到NFS server的硬盤中后才會返回 |
no_root_squas |
訪問nfs server共享目錄的用戶如果是root的話,它對該目錄具有root權限。這個配置原本為無盤用戶准備的。用戶應避免使用! |
root_squash |
對於訪問NFS server共享目錄的用戶,如果是root的話會被壓縮成為nobody用戶身份。 |
all_squash |
不管訪問nfs server共享目錄的用戶身份如何包括root,它的權限都將被壓縮成為匿名用戶,同時他們的udi和gid都會變成nobody或nfsnobody賬戶的uid,gid。在多個nfs客戶端同時讀寫nfs server數據時,這個參數很有用可以確保大家寫入的數據的權限是一樣的。 但不同系統有可能匿名用戶的uid,gid不同。因為此處我們需要服務端和客戶端之間的用戶是一樣的。比如說:服務端指定匿名用戶的UID為2000,那么客戶端也一定要存在2000這個賬號才可以 |
anonuid |
anonuid就是匿名的uid和gid。說明客戶端以什么權限來訪問服務端,在默認情況下是nfsnobody。Uid65534. |
anongid |
同anongid,就是把uid換成gid而已 |
配置實例:
/home/test 1192.168.1.0/24(rw,sync,all_squash,anonuid=2000,anongid=2000)
###注意紅色部分不能有空格!!生產環境中常用的一種配置,適合多客戶端共享一個NFS目錄。All_squash 也就是說不管客戶端是以什么樣的身份來進行訪問的,都會被壓縮成為all_squash后面所接的用戶和群組身份。這邊用anonuid、anongid編號來標示。=
小結:
服務器共享配置格式:
1)基本格式:共享目錄 ip/24(共享屬性) ->注意無空格
2)共享權限設置:
rw讀寫屬性
sync文件實際寫入磁盤后才返回
all_squash:所有訪問用戶均被壓縮成后續接的用戶。
anonuid:默認壓縮的用戶
anongid:默認壓縮的用戶組
那么客戶端以什么身份來訪問?
客戶端訪問服務端默認是使用nfsnobody這個用戶來進行訪問的。uid和gid為65534。服務器默認共享時,也是加上了all_squash這個參數。並制定anonuid為65534(也就是nfsnobayd用戶)。當然如果系統中nfsnobody是其他的uid,那么就有可能造成訪問權限出現問題。所以最好我們可以通過一設置一個用戶來訪問,統一UID、GID。
掛載情況怎樣呢?
有兩個重要的文件,能夠解決這個疑問。/var/lib/nfs/etab、/var/lib/nfs/rmtab這兩個文件就能夠查看服務器上共享了什么目錄,到底有多少客戶端掛載了共享,能查看到客戶端掛載的具體信息。
1、etab這個文件能看到服務器上共享了哪些目錄,執行哪些人可以使用,並且設定的參數為何。
2、rmtab這個文件就是能夠查看到共享目錄被掛載的情況。