暑期实习两周,负责老师终于给我派了任务。闲来无事,遂写下这篇博客记录所学内容和踩过的坑。
# 概述
网络文件系统(NFS)最早是由 Sun 公司发展出来的,也是 FreeBSD 支持的文件系统中的一个,它允许网络中的计算机之间通过 TCP/IP 网络共享资源。通过 NFS,我们本地 NFS 的客户端应用可以透明地读写位于服务端 NFS 服务器上的文件,就像访问本地文件一样方便。简单的理解,NFS 就是可以透过网络,让不同的主机、不同的操作系统可以共享存储的服务。
通用 Internet 文件系统(CIFS)最初由微软于 1990 年代中期发布,是服务器消息块(SMB)文件访问协议的扩展。CIFS 在 Windows 操作系统的网络环境中被广泛使用,但在现代系统实施中,更新版本的 SMB 已经取代了 CIFS。
二者之间的一些对比和区别如下:
- CIFS 面向网络连接的共享协议,对网络传输的可靠性要求高,常使用 TCP/IP;NFS 是独立于传输的,可使用 TCP 或 UDP。
- NFS 共享资源的能力仅限于文件和目录。相比之下,CIFS 还可以提供与其他网络设备(例如打印机)的共享资源通信。
- NFS 和 CIFS 最初是针对不同的操作系统设计的。CIFS 针对的是 Windows 操作系统,NFS 则针对 Unix。这意味着这两种协议是为了利用各自的操作系统内核来实施最佳操作而构建的。虽然可以在基于 Linux 的操作系统中使用 CIFS(通过 Samba),在 Windows 操作系统上使用 NFS(通过第三方软件包),但这些不是原生支持的做法。
- NFS 传统上依赖于基于主机的身份验证,在这种身份验证中,对共享文件的访问是根据客户端计算机的 IP 地址或主机名来控制的。它的内置安全机制有限,这在开放网络中可能是一个问题。而 CIFS 提供了更高级的身份验证和安全功能。它支持基于用户的身份验证,因此个人用户可以使用其凭证访问共享资源。CIFS 还支持加密和其他安全机制,这使其更适合安全环境。
- NFS 采用无状态设计,这意味着它不会跟踪服务器上打开的文件。因此,文件锁定由客户端处理,当多个客户端尝试同时写入同一个文件时,就会发生冲突。CIFS 支持服务器端的文件锁定,当多个客户端访问同一个文件时,它可以更好地进行协调并避免冲突。
- 在性能方面,NFS 使用开销更少的轻量级协议,从而加快文件访问和传输速度。相反,CIFS 支持各种特定于 Windows 的功能,因此协议开销更大。
整理成表格如下:
对比 | NFS | CIFS |
---|---|---|
当前版本 | NFS 4 | 已被 SMB 版本 3.1.1 所取代 |
适合的操作系统 | 基于 Linux 的网络架构 | 需要时可用于基于 Windows 的传统架构 |
共享资源 | 文件或目录 | 文件、目录和网络资源 |
身份验证 | 基于 IP | 基于用户 |
文件锁定 | 由客户处理 | 由服务器处理 |
性能 | 协议开销低,性能较快 | 协议开销高,性能较低 |
当前,有个开发需求:由一台服务器提供磁盘,共享给另一台服务器使用。这篇博客就分别介绍使用 NFS 和 CIFS 如何进行配置。该需求用于两个 Linux/Unix 系统,因此在配置 CIFS 时需要使用到 Samba 服务。
# 准备工作
当前需求中的两台机器,提供磁盘存储的称为服务端,使用共享存储空间的称为客户端。整个流程梳理下来就是将服务端中的某一目录共享给客户端使用。
如果当前服务端只有磁盘设备或文件系统,那么需要先挂在到某一目录下,这个目录就是需要共享的目录,这里设为 /share
。
将文件系统挂在到目录的方法如下:
使用 fdisk -l
命令可以查看未挂载的磁盘或文件系统。
一般来说,磁盘设备都会放到 /dev
目录下,在找到需要挂在的磁盘名后,可以到该目录下进行查找,找到对应的路径。这里比如设为 /dev/sdg
。这样就可以用下面的命令将磁盘挂在到需要共享的目录下:
mount /dev/sdg /share |
再用 mount
命令查看是否已经挂在成功。磁盘被手动挂载之后都必须把挂载信息写入 /etc/fstab
这个文件中,否则下次开机启动时仍然需要重新挂载。系统开机时会主动读取 /etc/fstab
这个文件中的内容,根据文件里面的配置挂载磁盘。这样只需要将磁盘的挂载信息写入这个文件中就可完成自动挂载。
以一个已经挂载好的例子作展示:
-
首先通过
blkid
命令将需要挂在的设备 uuid 查询出来并复制(往/etc/fstab
中追加挂载信息时建议使用 uuid)。 -
vim /etc/fstab
进入该文件进行修改,添加挂载信息。关于
/etc/fstab
中的内容,可以分成六列参数:Device Mount point fileSystem params dump fsck
label 或 uuid 挂载的目录 文件系统格式 文件系统参数 0、1、2 0、1、2
一般使用该设备 uuid,因为一旦磁盘插槽顺序发生变化,label 可能会改变,uuid 是不会变化的。
文件系统格式可以用
mount
命令查看。文件系统参数可以查看参考资料,不清楚的情况下可以写
defaults
。最后两个参数分别表示 "能否被 dump 备份命令作用" 和 "是否检验扇区",不清楚的情况下可以写
0 0
。
对于需要共享的目录,为了防止出现权限问题,可以设置最大权限:
chmod -R 777 /share |
共享文件设置完成后,客户端也要创建一个用于挂在共享目录的目录,这里设为 /mnt/nfsmount
和 /mnt/smbmount
,分别对于接下来要介绍的两种方法。
注意,本博客的 Linux 环境是基于 Red Hat 的系统(如 CentOS 和 Fedora),而基于 Debian 的系统(如 Ubuntu)它们的命令语法和软件包更新方式有所不同,所以后续配置过程用到的部分命令,不同系统会有不一样的实现,甚至软件包都有的不一样,因此 Debian 系统的配置建议重新查阅专门的教程。
# NFS/CIFS 配置
这一节将分别对 NFS 和 CIFS (Samba) 的配置进行介绍。
# NFS 配置
NFS 服务端需要安装 rpcbind
和 nfs-utils
,客户端需要安装 nfs-utils
。
首先在服务端系统确认是否已经安装 NFS(客户端相同):
$ rpm -qa nfs-utils rpcbind | |
nfs-utils-1.3.0-0.54.el7.x86_64 | |
rpcbind-0.2.0-38.el7.x86_64 |
如果没有输出,则分别在服务端和客户端进行安装:
yum install -y nfs-utils rpcbind # 服务端 | |
yum install -y nfs-utils # 客户端 |
接着修改 NFS 配置文件 /etc/exports
,配置像哪些主机共享自己的文件目录。
使用 vim
命令进入配置文件,然后添加如下内容:
/share 192.168.1.0/24(rw,sync,insecure,no_subtree_check,no_root_squash) |
该配置中第一个字段就是服务端需要被共享的文件的绝对路径,之后 192.168.1.0/24
表明哪些 IP 区间的主机可以使用共享目录。括号里的字段是对共享文件管理的参数配置,详细可见下表(只列出了常用的一些配置):
参数 | 说明 |
---|---|
ro |
只读访问 |
rw |
读写访问 |
sync |
所有数据在请求时写入共享 |
async |
nfs 在写入数据前可以响应请求 |
secure |
nfs 通过 1024 以下的安全 TCP/IP 端口发送 |
insecure |
nfs 通过 1024 以上的端口发送 |
wdelay |
如果多个用户要写入 nfs 目录,则归组写入(默认) |
no_wdelay |
如果多个用户要写入 nfs 目录,则立即写入,当使用 async 时,无需此设置 |
hide |
在 nfs 共享目录中不共享其子目录 |
no_hide |
共享 nfs 目录的子目录 |
subtree_check |
如果共享 /usr/bin 之类的子目录时,强制 nfs 检查父目录的权限(默认) |
no_subtree_check |
不检查父目录权限 |
root_squash |
root 用户的所有请求映射成如 anonymous 用户一样的权限(默认) |
no_root_squash |
root 用户具有根目录的完全管理访问权限 |
接着依次执行如下命令,启动 NFS 服务端功能:
service rpcbind start # 启动 RPC 服务 | |
service nfs start # 启动 NFS 服务 |
可以使用如下命令检查是否启用了对 NFS 的端口映射列表:
rpcinfo -p localhost |
接着执行下述命令查看服务端是否正确加载了 /etc/exports
配置:
$ showmount -e localhost | |
/share 192.168.1.10/24 |
看到正确输出共享目录信息后则表明服务端已经配置完成,接下来继续配置 NFS 客户端。
在客户端机器上执行如下命令测试共享目录是否可用:
showmount -e 服务端ip |
如果正确输出共享目录的信息,就可以继续下一步:挂载共享目录到本地目录(这里是 /mnt/nfsmount
)。
mount 服务端ip:/share /mnt/nfsmount | |
df -h |
至此,可以看到,已经正确地将远端 NFS 共享目录( /share
)挂载到本地( /mnt/nfsmount
)上了。
最后别忘了实现自动化挂载,方法同第二节相同,其中 Device 写成 服务器ip:/share
,文件系统格式一般为 nfs
,比如:
192.168.1.100:/share /mnt/nfsmount nfs defaults 0 0 |
# CIFS 配置
在 Linux 系统下配置 CIFS 需要使用 Samba 服务。Samba 是在 Linux 系统上实现 SMB 协议的一个免费软件,以实现文件共享和打印机服务共享。
首先用下面命令确认一下当前系统是否安装了 Samba,使用命令:
rpm -qa | grep samba |
其中,samba、samba-common、samba-client 三个程序是必须的。
如果没有,则需要安装:
yum install -y samba |
接着需要添加用于 Samba 服务的用户,该用户必须已经在系统中存在。也可以现在创建一个新的用户,比如命名为 smbuser
。使用到的命令如下:
useradd smbuser | |
smbpasswd -a smbuser |
接着按照提示为 Samba 用户设置密码,该用户将用于登录 Samba 服务器。之后修改配置文件 /etc/samba/smb.conf
,在文件最后添加如下内容:
[share] | |
comment = samba share folder | |
browseable = yes | |
path = /share | |
create mask = 0700 | |
directory mask = 0700 | |
valid users = smbuser | |
force user = smbuser | |
force group = smbuser | |
public = yes | |
available = yes | |
writable = yes |
其中方括号内是给共享目录起的别名, path
是共享目录的绝对路径。
配置完后重启 / 启动 Samba 服务,命令如下:
service smbd restart # 重启 | |
service smbd start # 启动 |
此时服务端的配置基本已经完成。不出意外,到这一步已经可以用 windows 设备访问该服务端的共享目录了。由于我做的是 Linux 客户端,这部分内容详见参考资料,此处不再记录。
接着为客户端进行配置。
客户端需要安装 smbclient,安装后测试访问 Samba 共享目录是否可用。
sudo yum install samba-client | |
smbclient //服务端ip/share_name -U username |
** 这里注意 share_name
是 smb.conf
配置文件中方括号里起的别名。** 如果看到如下提示符,就证明共享目录可以正常工作:
smb: \> |
接着需要将共享目录挂在到本地(此处为 /mnt/smbmount
),需要用到软件包 cifs-utils,使用如下命令可以下载:
sudo yum install cifs-utils |
挂载共享目录用到如下命令:
sudo mount -t cifs //服务端ip/share /mnt/smbmount -o username=smbuser,password= # 我没设置 smbuser 密码 |
此处我执行该命令的时候报了 Unable to apply new capability set 的错误,通过查阅资料发现是 cifs-utils 版本的问题。我用 yum 下载的版本为 6.10,需要手动升级版本,经查阅资料 6.15 版本可以解决该报错。其源码仓库位于 https://github.com/piastry/cifs-utils/tree/cifs-utils-6.15 。依据提示,下载源码到客户端,进入顶级目录,依次执行如下命令:
autoreconf -i | |
./configure | |
make | |
make install |
之后再次运行挂载命令就成功了。可以使用 df -h
或 mount
命令检测是否已经将服务端共享目录挂在到本地。
最后一步别忘了做持久化挂载,往 /etc/fstab
添加如下内容:
//服务端ip/share /mnt/smbmount cifs username=smbuser,password=,defaults 0 0 |
# 参考资料
NFS 与 CIFS - 文件系统之间的区别 - AWS (amazon.com)
Linux 上的 Yum 和 Apt 指南 (linux-console.net)