Loading... # NFS 部分 ## NFS 工作原理 NFS 就是 Network File System 的缩写,作用就是可以通过网络,让不同的机器、不同的操作系统可以共享彼此的文件。NFS 服务器的端口默认会开在 `2049` 上,但由于文件系统比较复杂, NFS 还需要其他服务辅助,这些额外的用来传输数据的端口是随机选择的 *(注:后有固定这些端口的方法)* 。NFS 使用 RPC 进行通信,在部署 NFS 服务端的同时还要部署 `rpcbind` 。 一个完整的 NFS 客户端连接 NFS 服务端过程如下: 1. 服务器端启动 RPC (rpcbind)服务,并开启 `111` 端口 2. 服务器端启动 NFS 服务,并向 RPC 注册随机的端口信息 3. 客户端启动 RPC,向服务端的 RPC 服务(`111`端口)请求服务端的 NFS 端口 4. 服务端的 RPC 服务反馈 NFS 端口信息给客户端 5. 客户端通过获取的 NFS 端口来建立和服务端的 NFS 连接并进行数据的传输  ## 部署 NFS 服务端 ```shell # 安装 NFS 和 rpcbind $ yum install -y nfs-utils rpcbind # 配置NFS服务端,创建数据目录(也可以使用已存在的文件) $ mkdir -p /data/nfs/k8s/ # NFS配置文件设置目录信息 # 后有 exports 文件编写的详细说明 $ vi /etc/exports /data/nfs/k8s/ *(async,insecure,no_root_squash,no_subtree_check,rw) # 按顺序启动服务 $ systemctl restart rpcbind nfs-server nfs-lock nfs-idmap ``` ## exports 编写及重要参数说明 ```shell $ vi /etc/exports # [共享目录] [允许的客户端地址1(权限参数)] [允许的客户端地址2(权限参数)] /data/nfs/k8s 192.168.1.0/24(ro,sync) client.host.something(rw,sync) # 修改后使用该命令重新挂载,无需重启 nfs $ exportfs -r ``` 1. 主机名和配置的括号中间不能有空格 2. 共享目录可以同时拥有 n 个客户端规则 3. 客户端地址可以是 ip,网域或者网址 ### exports 权限参数 | 参数名 | 说明 | | -------------------------------------------- | -------------------------------------------------------------------------------------------------- | | `rw`, `ro` | 读写权限,只读权限 | | `sync`, `async` | `sync` 代表数据会同步写入到内存与硬盘中,`async` 则代表数据会先暂存于内存当中,而非直接写入硬盘 | | `no_root_squash`,`root_squash`(默认) | `root_squash` 代表客户端以 root 身份登录 nfs,则在服务端会转变为 nfsnobody。`no_root_squash`则反 | | `all_squash` | 不论登入 NFS 的使用者身份为何, 他的身份都会被压缩成为匿名用户,通常也就是 nobody(nfsnobody) | | `subtree_check`(默认), `no_subtree_check` | 如果共享/usr/bin之类的子目录时,是否强制NFS检查父目录的权限 | | `secure`(默认),`insecure` | `secure` NFS通过1024以下的安全TCP/IP端口发送,`insecure` NFS通过1024以上的安全TCP/IP端口发送 | ### 其他 - NFS 配置保存位置 ```shell # NFS 相关配置保存在 /var/lib/nfs 下 $ ls /var/lib/nfs etab export-lock nfsdcltrack rmtab rpc_pipefs statd state v4recovery xtab # 根据 /etc/exports 生成的具体配置在 /var/lib/nfs/etab 中 $ cat /var/lib/nfs/etab /data/nfs/k8s *(rw,async,wdelay,hide,nocrossmnt,insecure,no_root_squash,no_all_squash,no_subtree_check,secure_locks,acl,no_pnfs,anonuid=65534,anongid=65534,sec=sys,rw,insecure,no_root_squash,no_all_squash) ``` ## 固定 NFS 相关服务端口 1. `rpcinfo -p` 查询 NFS 服务向 rpc 注册了哪些端口 2. `vi /etc/sysconfig/nfs` 修改 nfs 服务端口 ```shell $ vi /etc/sysconfig/nfs RQUOTAD_PORT=30001 LOCKD_TCPPORT=30002 LOCKD_UDPPORT=30002 MOUNTD_PORT=30003 STATD_PORT=30004 ``` 4. `systemctl restart rpcbind nfs-server nfs-lock nfs-idmap` 重启服务 5. `netstat -tulnp |grep -E '(rpc|nfs)'` 复查相关服务端口占用情况 ## iptables 控制 NFS 访问规则 由于 NFS 本身不提供账号密码服务,单纯在 `/etc/exports` 文件中限制挂载也不太安全,所以需要再用 iptables 加固一层。 ```shell $ iptables -P INPUT DROP $ iptables -N CLUSTER-INPUT $ iptables -N MANAGE-INPUT $ iptables -A INPUT -i lo -j ACCEPT $ iptables -A INPUT -i eth0 -j MANAGE-INPUT $ iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT $ iptables -A CLUSTER-INPUT -s {需要挂载 nfs 的客户端 ip} -j ACCEPT $ iptables -A MANAGE-INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT $ iptables -A MANAGE-INPUT -p tcp -m state --state NEW -m tcp --dport 30001:30004 -j CLUSTER-INPUT $ iptables -A MANAGE-INPUT -p udp -m state --state NEW -m udp --dport 30001:30004 -j CLUSTER-INPUT $ iptables -A MANAGE-INPUT -p tcp -m state --state NEW -m tcp --dport 111 -j CLUSTER-INPUT $ iptables -A MANAGE-INPUT -p udp -m state --state NEW -m udp --dport 111 -j CLUSTER-INPUT $ iptables -A MANAGE-INPUT -p tcp -m state --state NEW -m tcp --dport 2049 -j CLUSTER-INPUT $ iptables -A MANAGE-INPUT -p udp -m state --state NEW -m udp --dport 2049 -j CLUSTER-INPUT ``` ## NFS 客户端 > 如果仅在 K8S 集群上使用 NFS 则可以不进行此步骤,此步骤仅作测试使用。 ```shell # 安装 NFS 和 rpcbind $ yum install -y nfs-utils rpcbind # 启动 NFS 服务 $ systemctl start rpcbind nfs-server nfs-lock nfs-idmap # 创建需要挂载的目录 $ mkdir /data # 查看 NFS 服务端是否共享成功 $ showmount -e {NFS 服务端 IP} # 挂载 NFS $ mount -t nfs {NFS 服务端 IP}:/data/nfs/k8s /data # 卸载 NFS $ umount -f -l /data ``` # K8S 部分 如果还不知道什么是 PV 和 PVC 可以看看这篇文章 <div class="preview"> <div class="post-inser post box-shadow-wrap-normal"> <a href="http://gvoidy.cn/index.php/archives/380/" target="_blank" class="post_inser_a no-external-link no-underline-link"> <div class="inner-image bg" style="background-image: url(https://gvoidy.cn/usr/uploads/2021/10/1611661585.png);background-size: cover;"></div> <div class="inner-content" > <p class="inser-title">PV、PVC、VC、SC 都是些什么鬼</p> <div class="inster-summary text-muted"> 0x01k8s 是一个极其复杂的系统,所以用了很多高度抽象的概念来简化技术细节。这也导致了我这种刚学的 dd 对这... </div> </div> </a> <!-- .inner-content #####--> </div> <!-- .post-inser ####--> </div> ## 创建 PV ```yaml apiVersion: v1 kind: PersistentVolume metadata: name: nfs-test-pv spec: accessModes: # ReadWriteOnce 可读可写,但只支持被单个节点挂载 # ReadOnlyMany 以只读的方式被多个节点挂载 # ReadWriteMany 以读写的方式被多个节点共享 - ReadOnlyMany storageClassName: test-sc-name # 用于让 controller 强制将对应的 PVC 绑定到当前 PV capacity: storage: 20Gi # PV 容量 nfs: server: {NFS 服务端 IP} path: /data/nfs/k8s # NFS 挂载目录 readOnly: true mountOptions: - ro # PV 的读写权限 volumeMode: Filesystem ``` ## 创建 PVC ```yaml apiVersion: v1 kind: PersistentVolumeClaim metadata: namespace: default name: nfs-test-pvc spec: accessModes: # ReadWriteOnce 可读可写,但只支持被单个节点挂载 # ReadOnlyMany 以只读的方式被多个节点挂载 # ReadWriteMany 以读写的方式被多个节点共享 - ReadOnlyMany storageClassName: test-sc-name # 和刚刚 PV 处定义的 storageClassName 一致 resources: requests: storage: 1Gi # 容量小于等于 PV ``` 最后修改:2021 年 10 月 14 日 05 : 01 PM © 允许规范转载 赞赏 如果觉得我的文章对你有用,请随意赞赏 赞赏作者 支付宝微信