一、概念介紹
NFS 是Network File System的縮寫,即網絡文件系統。一種使用於分散式文件系統的協定,由Sun公司開發,於1984年向外公布。功能是通過網絡讓不同的機器、不同的操作系統能夠彼此分享個別的數據,讓應用程序在客戶端通過網絡訪問位於服務器磁盤中的數據,是在類Unix系統間實現磁盤文件共享的一種方法。
NFS 的基本原則是“容許不同的客戶端及服務端通過一組RPC分享相同的文件系統”,它是獨立於操作系統,容許不同硬件及操作系統的系統共同進行文件的分享。
NFS在文件傳送或信息傳送過程中依賴於RPC協議。RPC,遠程過程調用 (Remote Procedure Call) 是能使客戶端執行其他系統中程序的一種機制。NFS本身是沒有提供信息傳輸的協議和功能的,但NFS卻能讓我們通過網絡進行資料的分享,這是因為NFS使用了一些其它的傳輸協議。而這些傳輸協議用到這個RPC功能的。可以說NFS本身就是使用RPC的一個程序。或者說NFS也是一個RPC SERVER。所以只要用到NFS的地方都要啟動RPC服務,不論是NFS SERVER或者NFS CLIENT。這樣SERVER和CLIENT才能通過RPC來實現PROGRAM PORT的對應。可以這么理解RPC和NFS的關系:NFS是一個文件系統,而RPC是負責負責信息的傳輸。
NFS服務端、RPC協議、客戶端三者可以理解為房源、中介、租客之間的關系:
二、部署說明
1)軟件安裝
NFS只需要安裝下面兩個軟件,在通常情況下是作為系統默認軟件安裝的
rpcbind:centos 下面RPC主程序 (centos5系統之前該軟件叫portmap)
nfs-utils:NFS服務主程序,包括NFS的基本命令和監控程序
[root@dev-huanqiu ~]# yum install rpcbind nfs-utils
2)環境部署說明
將本機(192.168.1.6)的/usr/local/nginx/html/ssapp.test/weiloushu/video目錄共享給192.168.1.19的/data/video
將本機(192.168.1.6)的/usr/local/nginx/html/ssapp.beta/weiloushu/video目錄共享給192.168.1.16的/data/video
服務端的操作:
首先關閉nfs服務端的防火牆,這個很關鍵,否則客戶機掛載nfs時會失敗!(或者不關閉防火牆,需要在iptables中開放nfs相關端口)
[root@dev-huanqiu ~]# /etc/init.d/iptables stop
接着進行nfs共享設置
[root@dev-huanqiu ~]# vim /etc/exports
/usr/local/nginx/html/ssapp.test/weiloushu/video 192.168.1.19(rw,sync,no_root_squash)
/usr/local/nginx/html/ssapp.beta/weiloushu/video 192.168.1.16(rw,sync,no_root_squash)
配置說明:
rw:可讀寫的權限;
ro: 只讀的權限;
no_root_squash:客戶機用root訪問nfs共享文件夾時,保持root權限,root_squash 是把root映射成nobody,no_all_squash 不讓所有用戶保持在掛載目錄中的權限。
sync: 資料同步寫入存儲器中。
async:資料會先暫時存放在內存中,不會直接寫入硬盤。
其中:
客戶端常用的指定方式
指定ip地址的主機:192.168.1.19,如果是一個目錄共享給多台客戶機,那么就配置多行
指定子網中的所有主機:192.168.0.0/24
指定域名的主機:a.liusuping.com
指定域中的所有主機:*.liusuping.com
所有主機:*
訪問權限選項
設置輸出目錄只讀:ro
設置輸出目錄讀寫:rw
用戶映射選項
all_squash:將遠程訪問的所有普通用戶及所屬組都映射為匿名用戶或用戶組,通常也就是nobody(nfsnobody);
no_all_squash:與all_squash取反(默認設置);
root_squash:將root用戶及所屬組都映射為匿名用戶或用戶組(默認設置);
no_root_squash:與rootsquash取反;
anonuid=xxx:將遠程訪問的所有用戶都映射為匿名用戶,並指定該用戶為本地用戶(UID=xxx);比如(rw,sync,all_squash,anonuid=65534,anongid=65534)
anongid=xxx:將遠程訪問的所有用戶組都映射為匿名用 戶組賬戶,並指定該匿名用戶組賬戶為本地用戶組賬戶(GID=xxx);
其它選項
secure:限制客戶端只能從小於1024的tcp/ip端口連接nfs服務器(默認設置);
insecure:允許客戶端從大於1024的tcp/ip端口連接服務器;
sync:將數據同步寫入內存緩沖區與磁盤中,效率低,但可以保證數據的一致性;
async:將數據先保存在內存緩沖區中,必要時才寫入磁盤;
wdelay:檢查是否有相關的寫操作,如果有則將這些寫操作 一起執行,這樣可以提高效率(默認設置);
no_wdelay:若有寫操作則立即執行,應與sync配合使用;
subtree:若輸出目錄是一個子目錄,則nfs服務器將檢查其父目錄的權限(默認設置);
no_subtree:即使輸出目錄是一個子目錄,nfs服務器也不檢查其父目錄的權限,這樣可以提高效率;
可以使用showmount命令查看遠程客戶機上的共享目錄情況,這個命令需要root權限。
它有三個選項,記住這三個選項代表的含義:
showmount –a IP :顯示指定NFS服務器的客戶端以及服務器端在客戶端的掛載點
showmount –d IP :顯示指定NFS服務器在客戶端的掛載點
showmount –e IP :顯示指定NFS服務器上的共享目錄列表(或者叫輸出列表)
[root@dev-huanqiu ~]# showmount -e
Export list for ctl:
/usr/local/nginx/html/ssapp.beta/weiloushu/video 192.168.1.16
/usr/local/nginx/html/ssapp.test/weiloushu/video 192.168.1.19
查看系統加載的配置
[root@dev-huanqiu ~]# cat /var/lib/nfs/etab
/usr/local/nginx/html/ssapp.beta/weiloushu/video 192.168.1.16(rw,sync,wdelay,hide,nocrossmnt,secure,no_root_squash,no_all_squash,no_subtree_check,secure_locks,acl,anonuid=65534,anongid=65534,sec=sys,rw,no_root_squash,no_all_squash)
/usr/local/nginx/html/ssapp.test/weiloushu/video 192.168.1.19(rw,sync,wdelay,hide,nocrossmnt,secure,no_root_squash,no_all_squash,no_subtree_check,secure_locks,acl,anonuid=65534,anongid=65534,sec=sys,rw,no_root_squash,no_all_squash)
開啟nfs的RCP服務和查看rpcbind服務端口
[root@dev-huanqiu ~]# /etc/init.d/rpcbind start
Starting rpcbind: [ OK ]
[root@dev-huanqiu ~]# netstat -antlp|grep rpcbind
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 25416/rpcbind
tcp 0 0 :::111 :::* LISTEN 25416/rpcbind
開啟nfs服務
[root@dev-huanqiu ~]# /etc/init.d/nfs start
Starting NFS services: [ OK ]
Starting NFS mountd: [ OK ]
Starting NFS daemon: [ OK ]
Starting RPC idmapd: [ OK ]
設置兩個服務開機自啟動
[root@dev-huanqiu ~]# chkconfig rpcbind on
[root@dev-huanqiu ~]# chkconfig nfs on
客戶端的操作(這里列舉其中一台客戶機操作,另外一台客戶端操作類似):
客戶端只需要安裝rpcbind程序,並確認服務正常
[root@dev-new-test ~]# /etc/init.d/rpcbind start
正在啟動 rpcbind: [確定]
[root@dev-new-test ~]# /etc/init.d/rpcbind status
rpcbind (pid 28904) 正在運行...
掛載nfs服務端的共享目錄
[root@dev-new-test ~]# mount -t nfs 192.168.1.6:/usr/local/nginx/html/ssapp.test/weiloushu/video /data/video/
查看,發現已經共享成功了
[root@dev-new-test ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/VolGroup-lv_root 50G 12G 36G 26% /
tmpfs 32G 72K 32G 1% /dev/shm
/dev/sda1 485M 39M 421M 9% /boot
/dev/mapper/VolGroup-lv_home 844G 69G 733G 9% /home
192.168.1.6:/usr/local/nginx/html/ssapp.test/weiloushu/video 97G 64G 28G 70% /data/video
[root@dev-new-test ~]# showmount -a 192.168.1.6
All mount points on 192.168.1.6:
卸載(注意不能切換到掛載目錄里狀態下卸載,否則會報錯:umount.nfs:...: device is busy)
[root@dev-new-test ~]# umount /data/video
[root@dev-new-test ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/VolGroup-lv_root 50G 12G 36G 26% /
tmpfs 32G 72K 32G 1% /dev/shm
/dev/sda1 485M 39M 421M 9% /boot
/dev/mapper/VolGroup-lv_home 844G 69G 733G 9% /home
如果nfs在umount卸載時報錯如下:
[root@dev-new-test ~]# umount /data/video
/data/video was not found in /proc/mounts
解決:umount卸載時使用-l參數
[root@dev-new-test ~]# umount -l /data/video
umount.nfs: /data/video: not mounted
[root@dev-new-test ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/VolGroup-lv_root 50G 12G 36G 26% /
tmpfs 32G 72K 32G 1% /dev/shm
/dev/sda1 485M 39M 421M 9% /boot
/dev/mapper/VolGroup-lv_home 844G 69G 733G 9% /home
=================================================================================
遇到的一個問題:
目標機器通過nfs掛載后,在共享目錄下寫入文件時,權限強制變成nobod!(本來共享目錄的權限設置是app賬號)
經排查,是因為app賬號在原機器和目標機器的uid和gid不一致導致的!
解決辦法:將兩台機器的uid和gid設置成一樣的即可!
# usermod -u uid app
# groupmod -g gid app
------------------------------------------------------------------------------------------------------------------------------
補充一點:nfs服務端的防火牆問題
上面記錄中,已經提前在nfs的服務端將iptables防火牆關閉了。
如果不關閉服務端的iptables防火牆,那么要想讓客戶端成功掛載上nfs,就需要在服務端的iptables里開通nfs相關端口.
操作記錄:(centos6x系統下nfs服務照此配置均可,已經過實驗)
portmapp在nfs服務啟動的時候給每一個NFS服務分配了一個動態的端口,如這些服務MOUNTD_PORT、 STATD_PORT、 LOCKD_TCPPORT、 LOCKD_UDPPORT。
由於這些端口是動態隨機分配的,所以導致在iptables防火牆無法設置。
那么如何才能讓nfs client在使用iptables時可以正常使用NFS服務呢?
辦法就是指定將上述服務的運行端口,然后在iptables中發布。
相關的配置文件為 /etc/sysconfig/nfs 。
要使用iptables來控制nfs,需靜態指定端口號讓portmap調用。
nfs服務啟用時會檢查/etc/sysconfig/nfs文件。
在此文件下來指定mountd,statd,lockd,rquotad端口號,修改默認的端口號,這里我用的不是默認的端口號,而是自定義的端口號。如下:
[root@dev-huanqiu ~]# cat /etc/sysconfig/nfs|grep -v "^#"
RQUOTAD_PORT=10001
LOCKD_TCPPORT=10002
LOCKD_UDPPORT=10002
MOUNTD_PORT=10003
STATD_PORT=10004
重啟nfs服務
[root@dev-huanqiu ~]# /etc/init.d/nfs restart
Shutting down NFS daemon: [ OK ]
Shutting down NFS mountd: [ OK ]
Shutting down NFS services: [ OK ]
Shutting down RPC idmapd: [ OK ]
Starting NFS services: [ OK ]
Starting NFS mountd: [ OK ]
Starting NFS daemon: [ OK ]
Starting RPC idmapd: [ OK ]
再次通過下面命令查看nfs使用的端口,其中2049是nfs服務的固定端口
[root@dev-huanqiu ~]# 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 10001 rquotad
100011 2 udp 10001 rquotad
100011 1 tcp 10001 rquotad
100011 2 tcp 10001 rquotad
100005 1 udp 10003 mountd
100005 1 tcp 10003 mountd
100005 2 udp 10003 mountd
100005 2 tcp 10003 mountd
100005 3 udp 10003 mountd
100005 3 tcp 10003 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
100024 1 udp 10004 status
100024 1 tcp 10004 status
100021 1 udp 10002 nlockmgr
100021 3 udp 10002 nlockmgr
100021 4 udp 10002 nlockmgr
100021 1 tcp 10002 nlockmgr
100021 3 tcp 10002 nlockmgr
100021 4 tcp 10002 nlockmgr
端口111和2049分別是rpcbind和nfs服務端口
將上面命令結果中的端口分別在iptables里開通,注意tcp和udp均要開通!
[root@dev-huanqiu ~]# vim /etc/sysconfig/iptables
# Firewall configuration written by system-config-firewall
# Manual customization of this file is not recommended.
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -s 192.168.1.19/24 -p tcp --dport 111 -j ACCEPT
-A INPUT -s 192.168.1.19/24 -p udp --dport 111 -j ACCEPT
-A INPUT -s 192.168.1.19/24 -p tcp --dport 2049 -j ACCEPT
-A INPUT -s 192.168.1.19/24 -p udp --dport 2049 -j ACCEPT
-A INPUT -s 192.168.1.19/24 -p tcp --dport 10001:10004 -j ACCEPT
-A INPUT -s 192.168.1.19/24 -p udp --dport 10001:10004 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
重啟防火牆服務
[root@dev-huanqiu ~]# /etc/init.d/iptables restart
iptables: Setting chains to policy ACCEPT: filter [ OK ]
iptables: Flushing firewall rules: [ OK ]
iptables: Unloading modules: [ OK ]
iptables: Applying firewall rules: [ OK ]
[root@ctl ~]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT icmp -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh
ACCEPT tcp -- bogon/24 anywhere tcp dpt:nfs
ACCEPT udp -- bogon/24 anywhere udp dpt:nfs
ACCEPT tcp -- bogon/24 anywhere tcp dpts:scp-config:emcrmirccd
ACCEPT udp -- bogon/24 anywhere udp dpts:scp-config:10004
REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
Chain FORWARD (policy ACCEPT)
target prot opt source destination
REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
這樣,如上設置后,nfs在開啟iptables防火牆的情況下,也可以正常掛載使用了!
------------------------------------------------------------
如果客戶端在nfs掛載時報權限錯誤,如下:
mount.nfs: access denied by server while mounting.....
則可能原因有以下幾種:
1)防火牆原因
解決:關閉防火牆;如果防火牆開啟,需要打開相應的端口,並對相關客戶機開放;另確保/etc/hosts.allow和/etc/hosts.deny文件中有沒有nfs相關規則。
2)nfs服務端掛載的目標目錄權限
解決:嘗試設置777權限
3)insecure標識功能關閉
解決:insecure標識如果端口號大於1024,則需要將insecure 選項加入到配置文件(/etc/exports)相關選項中mount客戶端才能正常工作,默認情況下這個功能都是開啟的!
如果系統要是默認禁止這個選項,那么客戶端使用大於1024端口進行nfs掛載時就會報權限錯誤,則需要通過修改配置文件/etc/exports,加入insecure選項才能解決,如下:
/usr/local/nginx/html/ssapp.test/weiloushu/video 192.168.1.19(insecure,rw,sync,no_root_squash)