Cpt*_*rkt 5 filesystems remote nfs mount
我想了解网络安装软件的工作原理。例如,在我工作的地方,我们有一个软件服务器。每台客户端机器(数百台)在启动时自动从软件服务器挂载目录。例如,像 Matlab 这样的程序在软件服务器上只安装一次,但每个客户端机器都可以启动一个 Matlab 实例。
引擎盖下发生了什么?
假设我运行/opt/bin/matlab并/opt/从软件服务器安装,当我在客户端机器上按 Enter 执行 Matlab 时会发生什么?这个过程在客户端机器上,我已经通过在几乎为零磁盘空间的计算机上运行 Matlab 来缩小范围,没有任何隐式或隐藏的文件传输(即临时将 Matlab 复制到我的机器以进行该会话)即没有足够的空间转移)。
他们用来实现这一目标的技术称为NFS - 网络文件系统。他们可能还使用另一种称为 automounts 的 NFS 技术,如果是 Linux ,则特别是Autofs。
NFS 允许另一台机器访问来自一台机器的文件夹。这没有什么神奇之处。有一个客户端和服务器正在促进这种连接。当您访问通过 NFS 客户端安装在系统上的这些目录之一时,系统会调用以中继有关目录及其内容的信息。
如果其中一个客户端访问目录中的文件,NFS 服务器也会将此文件的内容中继到 NFS 客户端。
自动挂载是一种允许客户端系统临时访问共享远程资源(例如 NFS)的技术。也就是说,NFS 客户端系统可以访问这个远程 NFS 共享。但在有人尝试访问共享目录之前,它不会主动“使用”它。只有这样 NFS 客户端才会尝试“挂载”这个远程目录及其内容。
在任何一种情况下,都不会将文件隐式传输到 NFS 客户端。也就是说,它们不会以任何长期的方式物理复制到客户端。当客户端尝试访问它们时,这些文件会被流式传输到客户端。使用后它们就消失了;他们不会以任何长期的形式坚持在客户身上。
只是为了给您一个粗略的想法,您可以使用该程序strace查看在程序运行时进行的一些系统调用。因此,例如使用此命令:
$ strace echo "hello world" > afile
Run Code Online (Sandbox Code Playgroud)
我们可以看到文件是如何写入系统的。我们也可以使用这种形式写入 NFS 挂载目录:
$ strace echo "hello world" > /home/sam/afile
Run Code Online (Sandbox Code Playgroud)
这两个痕迹几乎相同。
###本地写入
$ cat strace_wr_local.log
execve("/bin/echo", ["echo", "hello world"], [/* 33 vars */]) = 0
...
fstat64(1, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f80000
write(1, "hello world\n", 12) = 12
close(1) = 0
Run Code Online (Sandbox Code Playgroud)
### NFS 写入
$ cat strace_wr_remote.log
execve("/bin/echo", ["echo", "hello world"], [/* 33 vars */]) = 0
...
fstat64(1, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7fbe000
write(1, "hello world\n", 12) = 12
close(1) = 0
Run Code Online (Sandbox Code Playgroud)
阅读只是稍微有趣一点,但仍然基本相同。
###本地读取
$ cat strace_rd_local.log
execve("/bin/cat", ["cat", "afile"], [/* 33 vars */]) = 0
...
fstat64(1, {st_mode=S_IFREG|0644, st_size=1761, ...}) = 0
open("afile", O_RDONLY|O_LARGEFILE) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=12, ...}) = 0
read(3, "hello world\n", 4096) = 12
write(1, "hello world\n", 12hello world
) = 12
read(3, "", 4096) = 0
close(3) = 0
Run Code Online (Sandbox Code Playgroud)
### NFS 读取
$ cat strace_rd_remote.log
execve("/bin/cat", ["cat", "/home/sam/afile"], [/* 33 vars */]) = 0
...
fstat64(1, {st_mode=S_IFREG|0644, st_size=1771, ...}) = 0
open("/home/sam/afile", O_RDONLY|O_LARGEFILE) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=12, ...}) = 0
read(3, "hello world\n", 4096) = 12
write(1, "hello world\n", 12hello world
) = 12
read(3, "", 4096) = 0
close(3) = 0
Run Code Online (Sandbox Code Playgroud)
如果您只是一般对 NFS 协议感到好奇,您可以在标题为NFS 协议基础知识的部分中阅读有关它如何工作的更多信息。通常很容易获得它如何工作的基本概念,并且有一个 NFS 请求示例,只是为了让您大致了解事情是如何工作的。
如果您真的想窥探幕后情况,您可能需要引入一组用于收集网络流量的工具,以便您可以看到 NFS 服务器与其一个客户端之间来回传输的比特流。此类工具已经tcpdump或wireshark可能成为您进行更深入探索的朋友。
我会告诫你不要浪费你的时间,除非你真的是好奇的人,因为像这样的深入研究需要很多技巧和熟悉一套 Unix 工具,我只会考虑那些已经使用 Unix 十几年的人年。
如果您真的很好奇,这个网站将帮助您完成这项工作: