6.10 - Ch17 NFS服务器出自Ubuntu's BookNFS(Network File
System)是由升阳(Sun)最先开发,它的目标是让不同机器能够跨平台共享相同的档案资源。简单来说,可以看成是一种远端的档案系统。也因为跨平台
的目标,所以几乎所有的Unix Like平台都支援NFS,如IBM AIX、Sun Solaris、HP
Unix、GNU/Linux和FreeBSD等,都可以透过NFS来共享档案和目录资源。目前在MS Windows上虽然有NFS
Client可以安装,但几乎是商业软件。
NFS运作理论
|
功能 | 设定档 |
设定NFS Server要分享的目录与权限 | /etc/exports |
nfs-common的启动设定值 (NFSv4需启用IDMAPD) | /etc/default/nfs-common |
nfs-kernel-server的启动设定值 | /etc/default/nfs-kernel-server |
设定client端可以自动挂载NFS Filesystem | /etc/fstab |
idmapd设定档 (NFSv4 Only) | /etc/idmapd.conf |
功能 | 指令 |
控制NFS Server启动或关闭的script档 | /etc/init.d/nfs-kernel-server |
控制NFS Client和Server共同的相关服务启动或关闭的script档 | /etc/init.d/nfs-common |
控制portmapper启动或关闭的script档。(NFSv4可以不使用,但是showmount依然走NFSv3协定,所以建议打开吧) | /etc/init.d/portmap |
修改 /etc/exports后需重新更新分享目录 | exportfs -rv |
察看本机目前分享的目录 | exportfs -v |
查询该主机有哪些目录被分享出来 | showmount -e <主机IP> |
查询该主机有哪些Client端连上和主机分享资讯 | showmount -r <主机IP |
设定NFSv3 Server最重要的就是 /etc/exports这个设定档,我们先弄个简单的范例来看看吧!
Server设定档 /etc/exports范例:
/home 192.168.0.0/24(rw,async,root_squash,no_subtree_check,insecure)
/tmp 192.168.0.0/24(rw,async,root_squash,no_subtree_check,insecure)
/opt 192.168.0.183(ro,root_squash,no_subtree_check,insecure)
如以上范例,exports的格式是第一栏为要分享的目录,第二栏是开放使用的Client主机,最后(rw,async,.....)里面写一些
参数。在表17-3-1-1有NFS
Server上使用的额外参数详细说明,此范例中的参数是笔者最常用的。在这个例子中,Server分享出3个目录,前两个让192.168.0.0网段
所有的电脑都可连进来,且都有读写的权限。最后一个只能由192.168.0.183那台机器连进来,并只能读取。
当设定好后,让它生效不需要重开服务,只要用以下指令即可!
重设Server分享目录:
username@ubuntu:~ $ sudo exportfs -rv # 重設分享目錄清單
exporting 192.168.0.0/24:/home
exporting 192.168.0.0/24:/tmp
exporting 192.168.0.183:/opt
username@ubuntu:~ $ exportfs # 察看目前分享目錄,可加 -v獲得更詳細資訊
/home 192.168.0.0/24
/tmp 192.168.0.0/24
/opt 192.168.0.183
Client挂载 /home范例:
# mount -t -o <掛載參數> nfs <Server IP>:<分享目錄> <mount point>
sudo mount -t nfs 192.168.0.180:/home /NFS/home
# 讀者也可以依照以下範例使用soft mode且改變讀取區塊大小為8192。
sudo mount -t nfs -o soft,rsize=8192 192.168.0.180:/home /NFS/home
如Client挂载范例,我们只需要用以上指令就可以挂载上Server的远端目录到本机的mount
point上,读者可以自己用同样的方式来挂载tmp和opt。挂载时,也可以加上一些挂载参数,参数可以参考表17-3-1-2,这些参数会在
fstab那里给出笔者最长用的设定,读者可以参考看看。
若要看远端有开放哪些资源可以提供挂载,可以使用以下方式。
察看远端可分享的目录资源:
username@ubuntu:~ $ showmount -e 192.168.0.183 # 可用 -a來得知有多少Client連上
Export list for 192.168.0.183:
/export 192.168.0.0/24
/export/home 192.168.0.0/24
/export/tmp 192.168.0.0/24
参数 |
功能 |
rw | 该分享目录可以读写 |
ro | 该分享目录只能读取 |
secure | 不允许Client使用大于1024的Client端port,也就是从Server传递资料到Client端的目地port要小于1024,此时Client端一定要使用root账号才能mount远端NFS Server。通常会建议使用insecure。 |
insecure | 允许Client端自行决定自己机器使用的port,笔者通常都会设这个,如此非使用root账号的clinet端才能mount NFS Server。 |
async | 允许异步写入资料,所以效能会比同步写入好。写入时会先放到内存,等硬盘有空档再写入!风险为若Server当机或不正常关机,会损失资料,但通常Server都很稳定,所以建议打开获得更好的效能! |
sync | 同步写入,效能比较不好。 |
nohide | 当export出两个目录,而其中一个目录是另外一个目录的子目录,例如我们使用虚拟目录的例子,此时我们mount根目录时,会自动把所有子目录mount起来。建议使用这个选项比较方便,尤其在NFSv4有虚拟目录的情形。 |
hide | 当mount根目录时,export出的子目录需要自己明确的再挂载。 |
subtree_check | 当分享的目录是某个档案系统的子目录,选用这个可以确定父目录的权限可以让NFS Server分享使用。 |
no_subtree_check | 刚好和上面的相反,因为不做权限测试,效能比较好。 |
fsid=0 | 定义NFSv4中的根目录,只能有一个! |
root_squash | 在权限的地方有详细解释,代表当client用root会变成匿名权限 |
no_root_squash | 关掉root_squash功能。 |
all_squash | 在Client所有的使用者都是变成匿名身份 |
anonuid | 指定在Client中操作该目录的权限账号,如使用anouid=0,那在Client端不管是谁都有着root的权限操作该目录。 |
anongid | 同上,不过这是指定使用者群组。 |
参数 | 功能 |
rsize | 每次读取的大小,默认是1024 byte,在区网内设大一点会有比较好的效能。但是若网络状况不好时,设太大反而会导致丢包重传而效能低下。在区网下,笔者建议使用rsize=8192。(在NFSv4最大建议到32768 byte) |
wsize | 每次写入的大小,默认也是1024 byte。在区网下笔者建议用wsize=8192。(NFSv4最大建议到32768 byte) |
proto=udp | 使用UDP协定来传输资料,在区网中会有比较好的效能。若要跨越Internet的话,使用proto=tcp会有比较好的侦错能力。 |
bg | 挂载的时候使用背景模式,也就是第一次挂不上去时,丢到背景慢慢试。所以当client端挂载写在fstab里面,一定要用bg,否则会拖慢开机速度。 |
fg | 挂载的时候用前景模式,直到挂载上了才继续跑别的程式。刚好和bg模式是相反的,这是默认值。 |
soft | 当NFS Client以soft挂载Server后,若网络或Server出现问题,造成Client和Server无法传输资料时,Client会一直尝试到 timeout后显示错误并且停止尝试。若使用soft mount的话,可能会在timeout出现时造成资料丢失,故一般不建议使用。 |
hard | 这是默认值。若用hard挂载硬盘时,刚好和soft相反,此时Client会一直尝试连线到Server,若Server有回应就继续刚才的操作,若没有回应NFS Client会一直尝试,此时无法umount或kill,所以常常会配合intr使用。 |
intr | 当使用hard挂载的资源timeout后,若有指定intr可以在timeout后把它中断掉,这避免出问题时系统整个被NFS锁死,建议使用。 |
虽然NFSv4有很多新的功能,但是在kernel中还是被标记为实验用,所以你有可能会遇到一些莫名其妙的bug,例如笔者更新核心到
2.6.17后,发现NFSv4
Client会莫名的当掉,最后再更新到2.6.18rc4就正常了!而kernel里面关于NFSv4的程式码又会比原始研发单位还要慢一点,若你想要
用最新的NFSv4程式码,可以到http://www.citi./projects/nfsv4/linux/ 抓最新的patch。若读者希望一切都没问题,不想再做一些hack,可以考虑用稳定的NFSv3。但若要在Internet传输,那么NFSv4的容易设定防火墙与加密的特性可以考虑一下!
由
于NFSv4使用rpc.idmapd这个daemon来处理User ID、Group
ID和权限的对应,所以这个daemon在Client端和Server端都要启动,并且需要自己手动建立通讯pipe给svc gssd
subsystem用,这些在Ubuntu都需要手动设定。记得这些设定一定要在Server和Client分别做过一次唷,设定好了就不需要再做了!
建立pipe目录给NFSv4使用:
sudo mkdir /var/lib/nfs/rpc_pipefs
加入以下两行到 /etc/fstab让rpc_pipefs和nfsd fs在开机自动mount起来:
rpc_pipefs /var/lib/nfs/rpc_pipefs rpc_pipefs defaults 0 0
nfsd /proc/fs/nfsd nfsd defaults 0 0
由于我们不重新开机,为了让刚刚加入的两行生效,执行以下指令吧!:
sudo mount rpc_pipefs
sudo mount nfsd
编辑 /etc/default/nfs-common,把NEED_IDMAPD改成yes:
NEED_IDMAPD=yes
接下来重新启动portmap,nfs-kernel-server和nfs-common,要依照笔者下面列出来的顺序操作喔!
对于Server需要重新启动这三个服务:
sudo /etc/init.d/portmap restart
sudo /etc/init.d/nfs-kernel-server restart
sudo /etc/init.d/nfs-common restart
对于Client需要重新启动这两个服务:
sudo /etc/init.d/portmap restart
sudo /etc/init.d/nfs-common restart
这时候可以开始设定 /etc/exports。基本上和NFSv3差不多,只不过多了虚拟根目录的概念。NFSv4为了安全性问题,引入了Pseudo Filesystem的机制,这类似HTTP Server是从系统上的某个子目录当成网页的起始目录(虚拟根目录)。
设定档 /etc/exports范例一 (不正确的设定):
/home 192.168.0.0/24(rw,fsid=0,async,no_root_squash)
/tmp 192.168.0.0/24(rw,async,no_root_squash)
如以上范例,笔者把home和tmp分享出来,先注意到fsid=0的参数,这个参数在NFSv4是有意义的!这宣告该分享目录是根目录,所以在
NFSv4 Client端要mount时,需要mount -t nfs4 IP:/ /mnt/nfs,而不是传统的mount -t nfs
IP:/home
/mnt/nfs。所以在NFSv4和NFSv3最大的不同是,在v4要先用fsid=0定义出一个根目录,也只有那个根目录以下的子目录才能被挂载,笔
者会在接下来用范例来解释。而虚拟根目录只能定义一个,若定义多个的话,会造成不可预期的问题。
Server重设分享目录:
username@ubuntu:~ $ sudo exportfs -rv
Client挂载 /home范例:
sudo mount -t nfs4 192.168.0.183:/ /NFS # 用NFSv4協定掛載
sudo mount -t nfs 192.168.0.183:/home /NFS # 用NFSv3協定掛載
读者应该有注意到吧!挂载同一个Server上的 /home目录,因为在Server上的exports有指定 /home是虚拟根目录(fsid=0),所以NFSv4远端挂载点是和NFSv3不一样的喔!在我们这个范例中被exports出来的tmp将无法在 NFSv4中被挂载,因为它不在虚拟根目录底下阿!所以使用NFSv4时,我们常常会建立一个根目录,然后把其它要分享的目录资源用mount --bind挂载进来,如以下范例。当然大家不会希望每次都要做bind的动作,所以请参考17-3-3小节把设定写到fstab吧!
使用bind来建立虚拟根目录范例:
sudo mkdir /export # 建立NFSv4分享的虛擬根目錄
sudo mkdir /export/home # 由於所有NFSv4分享目錄都要在虛擬根目錄底下,
sudo mkdir /export/tmp # 所以建立 /home和 /tmp來給bind用!
sudo mount --bind /home /export/home
sudo mount --bind /tmp /export/tmp
设定档 /etc/exports范例二 (正确的设定):
/export 192.168.0.0/24(rw,fsid=0,nohide,insecure,no_subtree_check,async,root_squash)
/export/home 192.168.0.0/24(rw,nohide,insecure,no_subtree_check,async,root_squash)
/export/tmp 192.168.0.0/24(rw,nohide,insecure,no_subtree_check,async,root_squash)
改成这样后,我们先sudo exportfs -rv让新的exports生效,这已经解决虚拟根目录的问题,因为我们使用bind来连接
/home到 /export/home,也就是这两个目录是等义的,这样规划符合NFSv4的单一虚拟根目录的原则,同时也可以在NFSv3中被挂载!
不论Client是NFSv3或NFSv4,在参数加上nohide,这样Client端挂载一个目录时,会自动挂载该目录下其他可挂载资源,而不需要明确的指定并一个一个挂上。
Client挂载 /export范例:
sudo mount -t nfs4 192.168.0.183:/ /NFS # 用NFSv4協定掛載
sudo mount -t nfs 192.168.0.183:/export /NFS # 用NFSv3協定掛載
如以上范例,当Server端有设nohide时,Client在NFSv4会自动挂载 /tmp和 /home或在NFSv3会自动挂载 /export/home和 /export/tmp,不需要再另外设定。
当然也可以直接挂载子目录,如以下范例。
Client挂载 /export/home范例:
sudo mount -t nfs4 192.168.0.183:/home /NFS # 用NFSv4協定掛載
sudo mount -t nfs 192.168.0.183:/export/home /NFS # 用NFSv3協定掛載
若读者使用showmount去看Server分享的资源时,要注意的是这个方式显示的目录是走NFSv3旧的协定,所以没有考虑到虚拟根目录。故使用NFSv4挂载法需要自己把 /export去掉喔!
察看远端可分享的目录资源:
username@ubuntu:~ $ showmount -e 192.168.0.183 # 可用 -a來得知有多少Client連上
Export list for 192.168.0.183:
/export 192.168.0.0/24
/export/home 192.168.0.0/24
/export/tmp 192.168.0.0/24
或许读者会觉得奇怪,不是说NFSv4不需要portmap了嘛?那我们怎还把它启动呢?的确是不需要,若你把它关了是可以正常连线,但
showmount是走旧的协定,所以就没办法看Server分享的资源啦!所以若你用不到showmount且不用NFSv3,可以把portmap关
了。
在Client中把挂载设定写到 /etc/fstab里面,让每次开机都可以自动挂载远端的NFS
Server是很方便的。在Server中若使用到NFSv4,常常用bind的技巧制造一个虚拟根目录,这些bind的规则也经常写到
/etc/fstab里面。这里的讨论继续沿用前两小节的范例,所以读者要视需求修改唷!
笔者先讨论如何在Server上开机后自动把虚拟目录和真正的分享目录bind起来。首先编辑Server上的fstab吧!
Server上的 /etc/fstab范例:
# <來源目錄> <目地目錄> none bind 0 0
/home /export/home none bind 0 0
/tmp /export/tmp none bind 0 0
如以上范例,在Server上的fstab最后面加上这两行,开机后就会自动把你真正要分享的目录bind到虚拟路径底下唷!
在Client端要设定自动挂载也是加到fstab里面,如以下范例。
Client设定 /etc/fstab来自动挂载NFS Server:
# <Server IP>:<分享目錄> <掛載點> nfs4或nfs <參數> 0 0
# 使用NFSv4協定掛載
192.168.0.183:/ /NFSA nfs4 proto=udp,rsize=32768,wsize=32768,intr 0 0
# 使用NFSv3協定掛載
192.168.0.183:/export /NFSB nfs proto=udp,rsize=8192,wsize=8192,intr 0 0
这个范例中,Client在开机后会自动mount Server上的
/export。不过一个是用传统的NFSv3,另外一个是NFSv4,它们可以同时使用。再次提醒,它们挂载的分享目录不同是因为NFSv4有虚拟根目
录的概念。后面的参数读者可以参考使用,笔者测试这样的参数在区网效能会比较好,参数详细说明在表17-3-1-2。
若你修改过fstab后,不想要重新开机,可以透过以下指令重新依照fstab的内容挂载。
依照fstab的内容重新挂载:
sudo mount –a
若你要看目前系统上有哪些File system被挂载上来,可以透过mount,它也会列出本地硬盘的挂载情形。
了解目前有哪些档案系统被挂载:
username@ubuntu:~ $ mount
(略)???
nfsd on /proc/fs/nfsd type nfsd (rw)
rpc_pipefs on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw)
192.168.0.183:/ on /NFS type nfs4 (rw,proto=udp,intr,addr=192.168.0.183)
若当你要卸载NFS Filesystem,遇到系统资源忙碌而无法umount,这时候用Lazy unmount很有用。它会侦测该装置是否忙碌,等到有空档就自动帮你umount,通常笔者会配合force umount使用。
卸载NFS Filesystem:
sudo umount -l -f /NFS # umount /NFS這個NFS Filesystem
看到这里,读者的NFS系统应该也架起来了吧!若有问题,可以先检查一下防火墙设定是不是把它挡掉了,若真的找不到原因,也欢迎和笔者联络,在能力所及的范围下可以互相讨论。
|