NFS筆記(一)NFS伺服器工作原理及詳細配置
一、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、 檢視系統資訊
[[email protected] ~]# cat /etc/redhat-release CentOS release 7.3.1611 (AltArch) [email protected] ~]# 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軟體包
[[email protected] ~]# rpm -qa | egrep "nfs|rpcbind"
[[email protected] ~]#
我的CentOS release 7.3.1611是最小化安裝,預設沒有安裝nfs和rpcbind
Yum搜尋下安裝包是否存在
[[email protected] ~]# yum search nfs-utils rpcbind
2.2、安裝NFS和RPC服務
[[email protected] ~]# yum install nfs-utils rpcbind
[[email protected] ~]# 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
檢視這兩個軟體包在電腦裡都安裝了什麼檔案;
[[email protected] ~]# rpm -ql nfs-utils
3、啟動NFS服務
3.1、啟動NFS服務之前先啟動rpcbind服務
檢視rcpbind狀態
[[email protected] ~]# 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服務
[[email protected] ~]# systemctl restart rpcbind
檢視PRC埠
[[email protected] ~]# yum install net-tools lsof
[[email protected] ~]# 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
[[email protected] ~]# 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註冊的埠資訊
[[email protected] ~]# 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服務
檢視狀態
[[email protected] ~]# 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服務,將設定為開機啟動。
[[email protected] ~]# systemctl start nfs
[[email protected] ~]# systemctl enable nfs
Created symlink from /etc/systemd/system/multi-user.target.wants/nfs-server.service to /usr/lib/systemd/system/nfs-server.service.
[[email protected] ~]# 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註冊的埠資訊
[[email protected] ~]# 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到底開了哪些埠
[[email protected] ~]# 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常見程序詳解
[[email protected] ~]# 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應該如何設定?
[[email protected] 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這個檔案就是能夠檢視到共享目錄被掛載的情況。