对每个人而言,真正的职责只有一个:找到自我。然后在心中坚守其一生,全心全意,永不停息。所有其它的路都是不完整的,是人的逃避方式,是对大众理想的懦弱回归,是随波逐流,是对内心的恐惧 ——赫尔曼·黑塞《德米安》
NFS
是 Network File System
的缩写,即 网络文件系统
。最早由Sun
公司开发,用来在UNIX&Linux系统间实现磁盘文件共享的一种方法。它的主要功能是通过网络让不同的主机系统之间可以共享文件或目录。发展迭代了多个版本:
NFSv1(1984年)
:最早的 NFS 版本由 Sun Microsystems 开发。它基于远程过程调用(RPC)和XDR(External Data Representation)协议,使客户端能够通过网络挂载远程服务器上的共享目录。NFSv1 使用不透明句柄标识文件,并使用无状态协议,其中服务器不保持有关客户端状态的信息。
NFSv2(1989年)
:NFSv2 在 NFSv1 的基础上进行了改进。它引入了更强大的操作,如文件和目录的读写操作,并提供了更可靠的错误处理和更高效的数据传输。NFSv2 仍然使用不透明句柄标识文件,并保持无状态的特性。
NFSv3(1995年)
:NFSv3 是一个重大的改进版本,引入了许多新特性和改进。它支持透明的文件句柄,提供更好的安全性、性能和可靠性。NFSv3 引入了基于文件路径的标识符(filehandle)来替代不透明句柄,并支持文件锁定、符号链接、读写一致性和服务器端写缓存等功能。
NFSv4(2000年)
:NFSv4 是目前最新和最全面的 NFS 版本。它经历了多个修订版本的迭代,以提供更强大的功能和性能改进。NFSv4 引入了许多重要特性,如全面的安全性(包括 Kerberos 身份验证和加密传输)、访问控制列表(ACL)、命名空间、客户端缓存控制等。它还引入了复杂的状态管理,使服务器能够跟踪客户端的状态。
NFS
客户端(一般为应用服务器,例如web) 可以通过挂载 (mount)
的方式将NFS服务端
共享的数据目录挂载到NFS客户端本地系统中(就是某一个挂载点下) 。从NFS客户端
的机器本地看,NFS服务端共享的目录就好像是客户自己的磁盘分区或者目录一样,而实际上确是远端的NFS服务端的目录。
在企业集群架构的工作场景中,NFS网络文件系统
一般被用来存储共享视频、图片、附件等静态资源文件。一般是把网站用户上传的文件都放在NFS共享里,例如,BBS产品的图片、附件、头像,特别是中小网站公司应用频率更高。
NFS的功能所使用的端口
并不是固定的,而是在服务器启动时动态分配
的,那么这样的话,客户端如何获得服务器端的相关端口呢?
NFS使用了一个称为rpcbind(或portmap)
的服务,它充当了一个端口映射程序
当服务器端启动NFS服务
时,它会向 rpcbind
服务注册其提供的NFS功能
及其对应的端口号
。客户端
在需要连接到服务器端
时,首先会向rpcbind
服务发送查询请求
,以获取服务器端所提供的NFS功能
及其相应的端口
号。
rpcbind
服务会返回服务器端注册
的NFS
功能及其端口号信息给客户端。客户端接收到这些信息后,就可以使用相应的端口号与服务器端建立连接,并进行NFS数据传输。
rpcbind服务
通常会使用固定的端口号 111
提供服务,因此客户端可以通过该固定端口号与服务器端进行通信,获取NFS功能及其端口号信息。
企业Linux 8
,默认使用NFS
版本4.2
,也可以使用NFSv4
或NFSv3
协议,但不再支持NFSv2
协议,NFS
版本4 (NFSv4)
仅使用TCP
传输。
NFS
服务由nfs-utils
软件包提供,RHEL8
默认安装了该软件包。
安装 nfs-utils
软件包。软件包可能已安装好。
[root@servera ~]# yum -y install nfs-utils
Red Hat Enterprise Linux 8.1 BaseOS (dvd) 83 kB/s | 2.8 kB 00:00
Red Hat Enterprise Linux 8.1 AppStream (dvd) 484 kB/s | 3.2 kB 00:00
Package nfs-utils-1:2.3.3-26.el8.x86_64 is already installed.
Dependencies resolved.
Nothing to do.
Complete!
配置开机自启动,同时需要开放对应的防火墙服务
[root@servera ~]# systemctl enable --now nfs-server.service
Created symlink /etc/systemd/system/multi-user.target.wants/nfs-server.service → /usr/lib/systemd/system/nfs-server.service.
[root@servera ~]# firewall-cmd --permanent --add-service=nfs
success
[root@servera ~]# firewall-cmd --reload
success
[root@servera ~]#
通过 man -k
命令查帮助文档, nfs 的使用关键字 exports
来进行一些常用配置,可以通过 man exports
查看具体的帮助信息
[root@servera ~]# man -k exports
exports (5) - NFS server export table
[root@servera ~]# man exports
[root@servera ~]# cat /etc/exports
[root@servera ~]# ls /etc/exports.d/
[root@servera ~]#
一般配置文件的编写有两个位置,一个是 /etc/exports
文件 ,另一个是 /etc/exports.d/
目录下
创建 /nfsshare
⽬录并对其进⾏保护,以便只有 student
用户具有写⼊权限。
其他的配置要求:
student
⽤用户具有读/写
访问权限,并且所有其他用户仅具有读取访问权限/nfsshare
⽬录,以便只有servera.lab.example.com
可以在读/写模式
下挂载它。lab.example.com
DNS 域中的所有其他系统都可以在只读
模式下挂载该共享导出。/etc/exports.d/exercise.exports
⽂件。注意不要在服务器名称和选项之间添加空格((rw) 和 (ro))
。[root@servera ~]# mkdir /nfsshare
[root@servera ~]# chown student /nfsshare
[root@servera ~]# ls -ld /nfsshare
drwxr-xr-x. 2 student root 6 Aug 1 00:07 /nfsshare
[root@servera ~]# cat /etc/exports.d/shar.exports
/nfsshare serverb.lab.example.com(rw) *.lab.example.com(ro)
修改完共享的配置之后,需要重新 reload
配置文件
[root@servera ~]# systemctl reload nfs-server
使⽤ exportfs
命令,确认 NFS
服务器正在导出 /nfsshare
⽬录。
[root@servera ~]# exportfs
/nfsshare servera.lab.example.com
/nfsshare *.lab.example.com
添加 -v
选项以显⽰导出选项的详细信息
[root@servera ~]# exportfs -v
/nfsshare servera.lab.example.com(sync,wdelay,hide,no_subtree_check,sec=sys,rw,secure,root_squash,no_all_squash)
/nfsshare *.lab.example.com(sync,wdelay,hide,no_subtree_check,sec=sys,ro,secure,root_squash,no_all_squash)
[root@servera ~]#
sync
:表示同步写入,NFS服务器会在数据写入到磁盘之前等待确认,确保数据的持久性。这可以提供更高的数据一致性,但可能会对性能产生一定影响。wdelay
:表示写入延迟,NFS服务器可能会在写入数据时进行延迟,以缓冲多个写入请求并进行批量处理。这可以提高写入性能,但可能会增加数据的丢失风险。hide
:表示隐藏共享,NFS服务器会隐藏共享的文件或目录,使其对客户端不可见。这可以用于限制特定目录的访问权限。no_subtree_check
:表示禁用子树检查,NFS服务器不会检查客户端是否具有访问整个共享树的权限。这可以提高性能,但可能会降低安全性。sec=sys
:表示使用系统身份验证,NFS服务器使用本地系统的身份验证机制进行客户端身份验证。rw
:表示读写权限,客户端具有对NFS共享的读写权限。secure
:表示使用安全连接,NFS服务器和客户端之间的通信将通过安全的加密连接进行。root_squash
:表示Root映射,NFS服务器会将来自客户端的Root用户的访问权限限制为一个非特权用户,以增加安全性。no_all_squash
:表示禁用全部映射,NFS服务器会保留来自客户端的所有用户和组的身份,而不进行任何映射。查看服务状态
[root@servera ~]# systemctl status rpcbind.service
创建 /share
挂载点,并且挂载 servera 根目录 到 /mnt 下面
创建 /share 挂载点。
[root@serverb ~]# mkdir /share
[root@serverb /]# mount servera:/ /mnt
[root@serverb /]# ls /mnt/
nfsshare
确认连通性OK,然后卸载之后,重新挂载访问
[root@serverb /]# umount /mnt
[root@serverb /]# mount -t nfs servera:/nfsshare /share
[root@serverb share]# cd /share/;touch temp
touch: cannot touch 'temp': Permission denied
创建文件失败,提示没有权限,这是因为我们在服务端只给了 student 的权限,所以这里会这样,而root 用户也没有权限,是因为默认开启了 root_squash
,root 被映射为一个非特权用户
[root@serverb share]# df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 880M 0 880M 0% /dev
tmpfs 915M 0 915M 0% /dev/shm
tmpfs 915M 17M 899M 2% /run
tmpfs 915M 0 915M 0% /sys/fs/cgroup
/dev/vda1 10G 2.2G 7.9G 22% /
tmpfs 183M 0 183M 0% /run/user/1000
servera:/nfsshare 10G 2.3G 7.8G 23% /share
[root@serverb share]#
[root@serverb share]# su student
[student@serverb share]$ touch temp
[student@serverb share]$ ls
temp
切换到 student 用户,文件创建成功,可以通过 mount 来查看映射信息
[student@serverb share]$
[student@serverb share]$ mount | grep sha
servera:/nfsshare on /share type nfs4 (rw,relatime,vers=4.2,rsize=262144,wsize=262144,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=172.25.250.11,local_lock=none,addr=172.25.250.10)
[student@serverb share]$
如果希望开机自动挂载,编辑 /etc/fstab
⽂件,再为 NFS
导出添加⼀⾏,配置完成,需要使用 mount -a
来重新加载配置
servera.lab.example.com:/nfsshare /share nfs defaults 0 0
挂载⽂件系统,然后验证挂载是否成功
[root@serverb ~]# mount /share
[root@serverb share]# df /share/
Filesystem 1K-blocks Used Available Use% Mounted on
servera:/nfsshare 10474496 2319360 8155136 23% /share
确认 student 用户可以在⽬录中创建⽂件。
[root@serverb ~]# su - student -c "echo Hello World > /share/test.txt"
[root@serverb ~]# ls /share
test.txt
确认 serverb 上的 root 用户⽆法写⼊到导出。
[root@serverb ~]# echo Hello World > /share/root_test.txt
-bash: /share/root_test.txt: Permission denied
在 serverd
上,创建要使⽤ NFS
导出的⽬录 /srv/operators
。它应归用户 root 和 operators 所有。
读/写
访问权限,并且所有其他用户都不应具有访问权限setgid
权限集,因此在该⽬录中创建的⽂件将⾃动归该组
所有服务端配置:
[root@serverd ~]# mkdir /srv/operators
[root@serverd ~]# chgrp operators /srv/operators
[root@serverd ~]# chmod 2770 /srv/operators
[root@serverd ~]# ls -ld /srv/operators
drwxrws---. 2 root operators 6 Jul 6 22:19 /srv/operators
[root@serverd ~]#
在 serverd
上,根据以下要求使⽤ NFS 导出 /srv/operators
⽬录:
servera.lab.example.com
可以访问该共享servera
具有对共享的读/写访问权限root squash
设置,servera
上的 root
用户不能读取或写⼊该共享安装工具包,配置编写导出文件,客户端主机名为 servera,访问权限为 rw
.
[root@serverd ~]# yum install nfs-utils
[root@serverd exports.d]# cat share.exports
/srv/operators servera.lab.example.com(rw)
[root@serverd exports.d]#
配置开启自启动
[root@serverd exports.d]# systemctl enable nfs-server.service --now
Created symlink /etc/systemd/system/multi-user.target.wants/nfs-server.service → /usr/lib/systemd/system/nfs-server.service.
[root@serverd exports.d]# firewall-cmd --permanent --add-service=nfs
success
[root@serverd exports.d]# firewall-cmd --reload
success
[root@serverd exports.d]#
检索配置情况
[root@serverd exports.d]# exportfs -v
/srv/operators servera.lab.example.com(sync,wdelay,hide,no_subtree_check,sec=sys,rw,secure,root_squash,no_all_squash)
[root@serverd exports.d]#
[root@serverd exports.d]# logout
Connection to serverd closed.
[root@servera ~]# mkdir /operators_data
[root@servera ~]# vim /etc/fstab
serverd:/srv/operators nfs defaults 0 0
[root@servera ~]# mount /operators_data
[root@servera ~]# df -h /operators_data
Filesystem Size Used Avail Use% Mounted on
serverd.lab.example.com:/srv/operators 10G 2.2G 7.9G 22% /operators_data
[root@servera ~]#
[root@servera ~]# cd /operators_data/
-bash: cd: /operators_data/: Permission denied
[root@servera ~]# su - operator1
[operator1@servera ~]$ cd /operators_data/
[operator1@servera operators_data]$
在servera
配置NFS服务,要求如下:
/public
同时只能被example.com
域中的系统访问/protected
能被example.com
域中的系统访问/protected
应该包含名为project
拥有人为student
的子目录student
能以读写方式访问/protected/project
servera 上面配置 nfs 导出。创建对应的目录,同时修改 project
的所有人为 student
[root@servera]
#-p, --parents
mkdir -p /public /protected/project
chown student /protected/project
查看帮助文档,exports
配置文件编写
# mandb && man -k nfs | grep 5
# man exports
# vim /etc/exports
需要注意读写权限
/public *.example.com(ro)
/protected *.example.com(rw)
配置服务开机自启动,开启队对应的防火墙
# systemctl list-unit-files | grep nfs
# systemctl enable --now nfs-server
# firewall-cmd --permanent --add-service=nfs
# firewall-cmd --reload
到这一步,服务端已经配置完成,可以通过 exportfs -v
查看配置信息
客户端操作
[root@serverb]
showmount -e servera
,用于显示远程主机(servera)上共享的文件系统。
客户端报错
# showmount -e servera
clnt_create: `RPC`: Unable to receive
报错信息提示我们没办法获取,RPC
的响应,前面我们讲过,nfs
客户端和服务端建立连接,使用 RPC
协议的 rpcbind
服务传递端口映射,所以我们需要放行 rpcbind
服务
所以需要在 servera 上面 做简单配置,开发对应的防火墙,通过 rpcinfo
命令可以查看当前机器的 rpcbind
服务,这里我们需要放行 111 端口
[root@servera]
# rpc<Tab><Tab>
# rpcinfo
program version netid address service owner
100000 4 tcp6 ::.0.111 `portmapper` superuser
100005 3 tcp6 ::.78.80 `mountd` superuser
...输出省略...
grep port.*mapper /etc/services
sunrpc 111/tcp `portmapper` `rpcbind` # RPC 4.0 portmapper TCP
sunrpc 111/udp `portmapper` `rpcbind` # RPC 4.0 portmapper UDP
当然也可以通过服务的方式,防火墙开放 rpc-bind
服务相关端口
# firewall-cmd --permanent --add-service=rpc-bind
# firewall-cmd --reload
[root@serverb ~]
开放之后回到客户机,任然提示报错
# showmount -e servera
rpc `mount` export: RPC: Unable to receive; errno = No route to host
这是因为我们同时需要开放 mountd
服务,回到服务端,添加 mountd
防火墙规则
mountd 是 NFS(Network File System)服务器上的一个守护进程,它在 NFS 的挂载过程中起着关键的作用,
处理挂载请求
:当客户端尝试挂载 NFS 共享时,它会向服务器上的 mountd 发送挂载请求。mountd 负责接收和处理这些请求,验证客户端的权限,并确保客户端有权访问所请求的共享目录。导出共享目录
:mountd 通过导出(export)共享目录的方式,将其可用于其他主机挂载。在服务器上配置的共享目录需要在 mountd 的管理下,以便客户端能够访问和挂载这些共享。管理挂载点
:mountd 跟踪服务器上已经挂载的共享,并提供有关挂载点的信息。这包括已经挂载的共享目录路径、客户端的 IP 地址等。挂载选项处理
:mountd 处理挂载选项,如权限控制、访问控制列表(ACL)、并发访问控制等。它根据客户端请求中的选项参数,按照事先配置的规则进行处理,以确保挂载操作按照预期进行。[root@servera]# firewall-cmd --permanent --add-service=mountd
# firewall-cmd --reload
[root@serverb ~]
# showmount -e servera
Export list for servera:
/protected *.example.com
/public *.example.com
在serverb
上挂载一个来自servera
的NFS共享,并符合下列要求:
/public
挂载在下面的目录上/mnt/nfsmount
/protected
挂载在下面的目录上/mnt/nfssecure
student
能够在/mnt/nfssecure/project
上创建文件[root@serverb]
# showmount -e servera
Export list for servera:
/protected *.example.com
/public *.example.com
# mkdir /mnt/nfs{mount,secure}
# man fstab
# vim /etc/fstab
在 fstab
中编写挂载配置,这里需要注意读写权限要和上面的匹配
...输出省略...
servera:/public /mnt/nfsmount nfs ro 0 0
servera:/protected /mnt/nfssecure nfs rw 0 0
刷新配置
# mount –a
确认挂载信息,做读写测试
# df -h | grep nfs
servera:/public 10G 2.1G 7.9G 22% /mnt/nfsmount
servera:/protected 10G 2.1G 7.9G 22% /mnt/nfssecure
# ls /mnt/nfsmount
# su - student -c "touch /mnt/nfssecure/project/s.txt"
# NFS Server Configuration
RPCNFSDCOUNT=16 # 设置 rpc.nfsd 的线程数为 16
RPCMOUNTDOPTS="-N 8" # 设置 rpc.mountd 的线程数为 8
# NFS Client Configuration
rsize=8192 # 设置读取缓存大小为 8 KB
wsize=8192 # 设置写入缓存大小为 8 KB
nfsiodthreads=8 # 设置 nfsiod 线程数为 8
actimeo=300 # 设置客户端缓存的有效期为 300 秒
async或sync参数
来配置写入策略。# NFS Server Configuration
RPCNFSDCOUNT=16 # 设置 rpc.nfsd 的线程数为 16
RPCMOUNTDOPTS="-N 8" # 设置 rpc.mountd 的线程数为 8
# 启用服务器端的写缓存
RPCNFSDARGS="-N 16 -H 256" # 设置 rpc.nfsd 的线程数为 16,并设置文件句柄缓存的大小为 256
# 配置文件句柄缓存的大小
MOUNTD_NFS_ARGS="-F -n 8 -N 16 -H 256" # 设置 rpc.mountd 的线程数为 8,文件句柄缓存的大小为 256