Linux服务 NFS
    NFS:Network File System,由Sun公司研发;
        NFSv1,NFSv2,NFSv3,NFSv4.0,NFSv4.1:并行存储,NFSv4.2:pNFS(并行存储,可以将数据分类存储,比如:将文件系统中的元数据(inode)和真正的数据内容(block)分开存储)
        文件系统一般都是在内核中实现的,NFS就是;
        NFS是将平时我们使用的本地对本地的文件系统接口的调用,映射到网络上的另外一台主机上(RPC,远程过程调用),对它进行调用,从而实现共享文件的目的,就像客户端去服务器请求数据一样;
        既然文件系统一般是在内核中实现的,那么也就意味着我们在硬件之上的内核中实现了多种所谓的系统调用(system call),这些系统调用就是为了当运行在用户空间的程序需要执行更高权限的操作时,可以有方法实现.因为操作系统的作用就是为了管理硬件资源,避免用户直接操作底层资源,从而造成无法挽回的损失(通过一个进程修改另一个进程的内存空间,而导致其崩溃,无法运行),所以提供了被操作系统严格管理的各种系统调用函数(read(),open(),write(),close()等)来给用户空间,当用户空间需要执行一些特权指令时,直接让cpu陷入内核,等执行完毕后再将结果返回给用户空间程序;→ 以为都是在一台主机实现的,所以属于本地系统调用;
        NFS使用RPC协议通信过程:
            首先是客户端程序发起一个系统调用(也就是请求运行某个或某些函数,会附带函数的参数一起发送),而这个系统调用却不是本地的,而是通过PRC协议借助于tcp/udp,将这个请求发送给另一台主机,另外那台主机会运行一个监听在某个套接字上的服务,当接收到发送来的请求后,会根据请求的信息,执行其请求的系统调用(函数),执行结束将结果返回给本地的服务进程,最后服务进程通过RPC协议将结果返回给请求的主机;也就是说客户端只是发起了一个系统调用请求然后就撒手不管了,知道服务器将结果返回给自己,坐享其成;←因为函数的执行过程是在其他主机上运行的而非本机,所以属于远程过程调用;
        RPC,Remte Procedure Protocol:远程过程调用(远程主机上的函数)
            一部分功能由本地程序完成;
            另一部分功能由远程主机上的函数完成;
        NFS中一个不人性化的地方:
            上面说了,NFS文件系统可以看成是由客户端和服务器端组成的,当我们在本机挂载了远端服务器上的某个NFS文件系统目录后,我们需要向其中存储数据时,就当是使用guowei这个用户吧且UID为1000,当我们已经存储了某个文件,那么这个文件在远端NFS文件系统中的属主,属组是谁那?
                为什么这么问那,这是因为NFS本身的服务并没有通过用户名进行用户身份验证的机制,
而是以客户端的UID和GID来区分用户的,所以当我们使用guowei这个用户向NFS文件系统中存储一些数据时,如果客户端与服务器端的用户不一致,怎么办?
                1.客户端与服务器刚好有相同的用户名和组名;
                    此时用户可以直接以guowei的身份访问服务器所提供的共享文件系统;
                2.服务器端没有guowei这个帐号,但是有一个帐号GW的UID与guowei的UID相同;
                    此时客户端的guowei可以访问服务器端GW这个帐号的资源,因为服务器端只识别UID,所以会造成安全隐患;
                3.服务器端没有guowei这个帐号,也没有与之相同的UID;
                    此时服务器端会将客户端的guowei的身份挤压成匿名用户,一般NFS的匿名用户的帐号为nobody(Centos为nfsnobody)权限非常小;
                4.比较特殊的一种情况:如果客户端使用的是root用户挂载NFS文件系统存储数据;
                    因为root的UID为0且NFS文件系统中一定会存在,则客户端挂载文件系统后就会具有至高无上的权限,可以任意删除,创建任何数据;这是我们不允许的,所以默认情况況下,root的身份也会被挤压成匿名用户,从而保护数据不会被任何人随便破坏;
                所以经过上面的描述,我们意识到两台主机帐号的统一是刻不容缓的,这种连我们都能想到问题,Sun一定也想到了,所以他们就有研发了一个NIS(Netowrk Information System)的系统,将认证的步骤放到了一个专门的服务器上,这样就可以实现二者帐号的统一管理,避免以上的各种麻烦,但是NIS的传输是明文的,所以一般不建议在互联网上搭建,都是在内网中给自己公司内部用;
                    关于NIS的信息以后会更新;
                其实在NFSv4中已经提出了解决办法:方法就是在服务器端运行一个叫idmapd的进程,实现了用户帐号的集中映射(都映射为nfsnobody);但实际访问时却可以以客户端使用的本地身份去访问,也就是说当你挂载NFS后,使用ls查看数据的属性时,会看到属主,属组都是nfsnobody;
        NFS文件系统关于使用文件的权限:
            NFS文件系统自身提供了一个管理机制,可以实现只让自己信任的用户(主机名/IP地址)来挂载访问自己的目录,但是你懂的,我们linux系统自身还有一个防护措施,就是rwx这三个权限,所以,一个用户挂载NFS文件系统后想访问数据还要看这个自带属性是否允许你通过;
        NFS的认证:
            仅支持基于IP的认证,支持通过本地/etc/hosts文件和DNS解析成IP地址后认证;但是基于IP地址的认证是非常不灵活的,但是也没有办法啊!因为NFS不是那种有类似http的有请求和响应的服务,它只是实现了调用远端函数,从而实现一些功能,无法像http一样做关于用户名密码的认证;那怎么办呢?自己不行不代表别人不行啊!NFS服务启动以后会有一个rpc.mountd的服务随之启动,当用户请求来了以后,首先会将请求交给mountd这个服务,由它来帮助验证客户端的用户是否在我们所允许的访问文件系统的客户端列表中,如果在mountd就会给客户端分发一个类似令牌的东西,并且告诉客户端一会儿自行来访问我nfsd(nfsd服务本身并不负责进行文件的存储,真正负责文件存储的是内核,它只是用来理解客户端发来的请求的服务而已,然后代为转交给本地内核,从而实现存储功能)所监听的接口(tcp|udp/2049),然后客户端就可以通过这个令牌去找NFS,从而访问NFS服务;
        一直以来我们都是再说服务器端,那么客户端有没有什么需要注意的那?或者需要启动什么服务吗?
            当我们正在访问NFS服务中的数据时,突然出现网络抖动或者断线了怎么办呢?我们知道,当用户操作一个文件时系统会对文件进行加锁,其他进程是无法访问的;所以当断线以后这个锁是否要存在?如果存在是否有超时时间?当重新连线时,是否可以继续访问啊?还有连接状态的管理啊!这些都需要客户端来管理;所以在客户端也需要运行一些服务来维持这些状态;
        RPC在NFS中的作用:
            其实RPC可以支持很多的服务,NFS只是RPC server中的一种;前面我们提到了一个rpc.mountd服务,既然客户端会去找它索要令牌,那么就说明它也是监听在某个端口的,并且这个端口还是不固定的,因为是由RPC随机分配的;在Centos6中运行RPC服务的服务名为portmapper,监听在111这个端口上;
            所以我们要补充一下上面关于NFS服务器端验证客户端的步骤:因为mountd的端口是有RPC(portmapper进程)随机分配的,所以客户端本应该是不知道mountd监听的端口的,但是他就是知道啊!其实客户端首先访问的是PRC这个服务,因为就是它负责给mountd分配端口嘛,它一定知道mountd监听在哪个端口啊,并且它还有固定的监听端口,很好找嘛;
            rpcinfo:用于报告rpc相关的信息的;
                rpcinfo -p [IP_ADDRESS]可以查看本机[远端]rpc所监听的端口,有哪些服务已经注册了rpc服务,以及portmapper是否正常工作;
            RPC会将本地未使用的端口分配给自己所管理的各种服务,所以如果httpd的80端口没有被使用时,就会被rpc分配出去;所以RPC提供了一个功能可以让rpc只分配固定范围内的端口;
        安装服务:
            yum install rpcbind
            yum install nfs-util
        NFS配置文件:/etc/exports
            exportfs:维护exports文件导出的文件系统表的专用工具;
                exportfs -ar:重新导出所有的文件系统;
                exportfs -au:关闭导出的所有文件系统;
                exportfs -u FS :关闭导出的指定的文件系统;
            格式:
                目录/文件系统        客户端(选项) 客户端(选项)
                客户端:
                    IP地址
                    NETWORK
                    FQDN
                    DOMAIN
                选项:
                    rw:读写
                    ro:只读
                    root_squash:默认情况下,客户端以root身份连接NFS服务会由root_squash的设置将root挤压成nfsnobody身份;
                    no_root_squash:开放客户端使用root身份连接NFS服务;
                    all_squash:不论登陆NFS的用户身份为何,搜会被挤压为匿名用户,也就是nfsnobody;
                    anonuid:自行设置客户端登陆NFS后映射的匿名用户的UID
                    anongid:自行设置客户端登陆NFS后映射的匿名用户的GID
                    更多信息请查看:man exports
            例子:/shared/guowei          192.168.102.1(rw) 192.168.200.0/24(ro)
                  /shared/nfs                192.168.103.1(rw) 192.168.210.0/24(ro)
        共享资源的日志文件:/var/lib/nfs/*tab
            /var/lib/nfs/etab:主要记录了NFS所共享出来的目录的完整权限设置值;
            /varlib/nfs/xtab:主要记录了曾经连接到此NFS服务器的相关客户端的数据;
        挂载NFS文件系统:
            mount -t nfs SERVER_IP:/path/to/sharednfs  /path/to/mount_point
        开机自动挂载NFS文件系统:
            将上一条写在/etc/rc.d/rc.local中,开机即可挂载;
            注:不能写在/etc/fstab中,因为linxu在开机启动时会检查这个文件,当其中的文件无法挂载时就会出错,至于为什么会无法挂载呢?那是因为网卡启动是在本机的各种文件系统挂载之后,所以会出错;
        注:启动nfs和rpc服务时,要先启动rpcbind再启动nfs,因为nfs需要依赖的某些服务是需要rpc分配端口的,所以要先启动;
 

      注:根据马哥视频做的学习笔记,如有错胡,欢迎指正;侵删;