如何在Debian 9上安装NFS共享
什么是网络文件系统(NFS)
网络文件系统(NFS)是一种文件系统协议,允许类Unix系统的用户通过网络访问文件,就像使用本地存储一样。这对于跨Internet上的多个腾讯云CVM服务器或其他计算机共享文件很有用。例如,您可以通过NFS共享用户或系统配置文件的主目录。
但是,请注意NFS(版本3及更早版本)的一个限制是服务器和客户端必须限制为本地或受信任的专用网络,因为数据从一台计算机未加密传输到另一台计算机。NFS版本4解决了这个缺点,它依赖于Kerberos进行身份验证和加密。然而,设置用于NFS的Kerberos相当复杂,并且需要密钥分发中心,这超出了本教程的范围。
本教程将指导您完成两个腾讯云CVM服务器的设置; 一个是NFS服务器,另一个是客户端。在此示例中,两个腾讯云CVM服务器都位于同一数据中心,并将使用其专用IP地址进行通信,因此您的数据永远不会离开腾讯云CVM服务器的网络。警告:其他NFS设置可能会通过公共Internet发送流量。
注意 本教程是为非root用户编写的。需要提升权限的命令带有
sudo
前缀。
准备
- 将两个Debian 9腾讯云CVM服务器部署在同一个数据中心。没有服务器的同学可以在这里购买,不过我个人更推荐您使用免费的腾讯云开发者实验室进行试验,学会安装后再购买服务器。
- 将腾讯云CVM服务器配置为使用私有IP。
NFS服务器设置
选择一个腾讯云CVM服务器作为您的NFS服务器。并按照以下说明进行配置。
- 更新软件包来源:
sudo apt update
- 安装NFS服务器包
nfs-kernel-server
:
sudo apt install nfs-kernel-server
- 安装Portmapper软件包
portmap
:
sudo apt-get install portmap
- 默认情况下,通过将以下行添加到
hosts.deny
文件中来阻止访问NFS使用的服务。
rpcbind mountd nfsd statd lockd rquotad : ALL
- 允许访问NFS用于客户端和localhost的服务。将以下行添加到您的
hosts.allow
文件中,替换example_IP
为客户端腾讯云CVM服务器的私有IPv4地址。
rpcbind mountd nfsd statd lockd rquotad : 127.0.0.1 : allow
rpcbind mountd nfsd statd lockd rquotad : example_IP : allow
rpcbind mountd nfsd statd lockd rquotad : ALL : deny
- 在本地文件系统中创建一个目录,以用作NFS共享的root位置:
sudo mkdir /var/nfsroot
- 为NFS共享的root分配适当的所有权:
sudo chown nobody:nogroup /var/nfsroot/
- 将以下行添加到
/etc/exports
文件中,替换example_IP
为客户端腾讯云CVM服务器的私有IPv4地址。确保/ 17和左括号之间没有空格,并且文件末尾有一个空行。
/var/nfsroot example_IP/17(rw,root_squash,subtree_check)
- 使用以下命令更新导出的文件系统表:
sudo exportfs -ra
- 在服务器腾讯云CVM服务器上重新启动NFS服务以使更改生效:
sudo systemctl restart nfs-kernel-server
完成!现在,您在其中一个腾讯云CVM服务器上已经有了一个基本NFS服务器,并配置为将/ var / nfsroot
目录提供给第二个腾讯云CVM服务器。
NFS客户端设置
第二个腾讯云CVM服务器将是您的NFS客户端。请按照以下说明进行配置。
- 更新软件包来源:
sudo apt update
- 安装NFS客户端软件包
nfs-common
:
sudo apt install nfs-common
- 在客户端腾讯云CVM服务器的本地文件系统中创建一个目录,作为远程文件系统的挂载点:
sudo mkdir /mnt/remotenfs
- 使用您喜欢的编辑器将以下行添加到客户端的
fstab
文件中,替换example_IP
为服务器腾讯云CVM服务器的私有IPv4地址。
1 example_IP:/var/nfsroot /mnt/remotenfs nfs rw,async,hard,intr,noexec 0 0
- 通过运行以下命令挂载文件系统:
sudo mount /mnt/remotenfs
你已经完成了!现在,从客户端腾讯云CVM服务器,您可以访问腾讯云CVM服务器 NFS服务器上托管的远程文件系统。您可以通过将更多客户端添加到服务器的/etc/exports
文件来添加更多客户端,然后为每个客户端重复客户端设置。
高级配置
NFS提供各种挂载选项。在本教程中,我们使用了读写访问,异步文件传输和可中断硬等待的标准行为,但您可以使用以下选项在NFS共享上配置其他行为。
客户端选项
这些选项可以在fstab
中指定,也可以使用带有-o
开关的mount
命令手动指定,后跟逗号分隔的挂载选项列表。
- rw:读/写文件系统。
- ro:只读文件系统。远程NFS客户端无法修改文件系统。
-
hard:如果服务器出现故障,使用存储在NFS上的文件的应用程序将始终等待。除非设置了选项
intr
,否则用户无法终止该过程。 -
soft:如果服务器出现故障,使用存储在NFS上的文件的应用程序将等待指定的时间(使用
timeo
选项),之后将抛出错误。 - intr:允许用户中断等待NFS请求的进程。
- timeo = <num>:用于soft选项。指定NFS请求的超时。
- nolock:禁用文件锁。适用于较旧的NFS服务器。
- noexec:禁用NFS共享上的二进制文件或脚本的执行。
- nosuid:阻止用户获得NFS共享上文件的所有权。
- rsize = <num>:设置读取块数据大小。在NFSv2和NFSv3上默认为8192,在NFSv4上默认为32768。
- wsize = <num>:设置写入块数据大小。在NFSv2和NFSv3上默认为8192,在NFSv4上默认为32768。
服务器选项
可以在/etc/exports
条目中指定这些选项:
- rw:读/写文件系统。
- ro:强制客户端仅以只读文件系统模式进行连接。
- no_root_squash:客户端计算机上的root帐户将具有与服务器计算机上的root相同的权限级别。该选项有安全隐患; 除非你确定需要,否则不要使用它。另一方面,root_squash导致客户端上的root与服务器上的nobody具有相同的访问类型 - 从而阻止客户端上的root将不需要的文件传播到其他文件。
- no_subtree_check:禁用部分卷导出的文件位置检查。此选项将加快全量导出的传输速度。
- 同步:强制所有传输在同步模式下运行,因此所有客户端都将等待,直到其操作完成。这可以避免在服务器崩溃时数据损坏。
示例
在客户端的/ mnt / remotenfs
中创建一个名为testfile.txt
的测试文件::
sudo echo "Hello World" > /mnt/remotenfs/testfile.txt
如果一切按预期进行,则/mnt/remotenfs/testfile.txt
由nobody:nogroup
拥有。 你可以使用以下命令查看
ls -l /mnt/remotenfs/testfile.txt
同样,如果您这样做,则应在服务器中显示相同的权限
ls -l /var/nfsroot/testfile.txt
现在让我们用服务器上的/ etc / exports
中的no_root_squash替换root_squash,并更新导出共享表,如上面NFS Server Setup 中的替换example_IP
为客户端腾讯云CVM服务器的私有IPv4地址步骤中所述。 最后,我们将通过在同一目录(/ mnt / remotenfs
)中创建另一个测试文件(testfile2.txt
)来重复上述操作:
sudo echo "Hi everyone" > /mnt/remotenfs/testfile2.txt
如果您在客户端或服务器上检查testfile2.txt
的所有权,您将看到它现在由root:root
拥有。 这些简单的例子说明了root_squash和no_root_squash的用法和含义。 为了您的安全,请不要忘记删除后者并尽快在/ etc / exports
中重新添加前者。
了解更多
想要了解更多关于NFS的内容请前往腾讯云+社区学习。
参考文献:《How to Mount NFS Shares on Debian 9》
- Android 高级自定义Toast及源码解析
- 环境配置:React Native 开发环境配置 For Android
- 美团多渠道打包方案详解,速度快到白驹过隙
- 下一代Android渠道打包工具
- 01 整合IDEA+Maven+SSM框架的高并发的商品秒杀项目之业务分析与DAO层
- 通俗易懂的分析如何用Python实现一只小爬虫,爬取拉勾网的职位信息
- 我的第一个小程序(Discuz! + 微信小程序)
- 微信小程序 wx.request 的封装
- 如何用Python爬虫实现百度图片自动下载?
- 以太坊智能合约开发入门
- lodash源码分析之baseFindIndex中的运算符优先级
- 分子对接简明教程 (一)
- 分子对接简明教程 (二)
- 分子对接简明教程 (三)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- laravel 中某一字段自增、自减的例子
- php统计数组不同元素的个数的实例方法
- PHP实现单条sql执行多个数据的insert语句方法
- PHP的JSON封装、转变及输出操作示例
- php 策略模式原理与应用深入理解
- 解决在Laravel 中处理OPTIONS请求的问题
- PHP使用观察者模式处理异常信息的方法详解
- php判断目录存在的简单方法
- 怎么优雅的使用 laravel 的 validator验证办法
- Thinkphp5.0框架的Db操作实例分析【连接、增删改查、链式操作等】
- php设计模式之适配器模式原理、用法及注意事项详解
- php基于Redis消息队列实现的消息推送的办法
- tp5框架无刷新分页实现方法分析
- PHP与SQL语句写一句话木马总结
- golang实现php里的serialize()和unserialize()序列和反序列办法详解