存储之NFS
介绍
NFS(Network FileSystem),可以通过网络,让不同的机器、不同的操作系统可以分享文件。可以看作是一个文件服务器(File Server)。
NFS服务器可以将源成的NFS服务器分享的目录,挂载到客户端的机器中。当服务器端将系统目录分享出来后。其他客户端就可以将这个目录挂载到自己系统上的挂载点上。

NFS使用网络进行数据的传输,NFS服务端与客户端之间通过RPC。服务器在启动时,会随机取用数个端口,并主动向RPC注册。因此RPC可以知道每个端口的功能。客户端上,RPC固定使用111端口,来监听客户端的请求,并响应给客户端对应服务正确的端口。

部署
安装配置NFS
- 安装NFS
1
yum install nfs-utils rpcbind -y
- 创建共享目录
1
2
3
4
5# vim /etc/exports
/usr/nfs 10.0.38.0/24(rw,no_root_squash,sync)
# exportfs -r
exports文件说明:
内容格式应为: <输出目录> [客户端](参数...) [客户端2](参数...)
说明:
- 输出目录:本地需要共享给客户端的文件夹路径
- 客户端:
- 可以指定ip,如10.0.38.82
- 可以指定子网,如10.0.38.0/24
- 可以指定主机名
- 可以指定域中的所有主机,如*.[域名]
- 指定所有主机: *
- 可选参数之间用逗号分隔
参数值 内容说明 rw
ro该目录分享的权限是可读写(read-write)或只读(read-only),但最终能不能读写,还是与文件系统的rwx及身份有关 sync
asyncsync代表数据会同步写入到内存与硬盘中。async代表数据会先暂存于内存当中,而非直接写入硬盘 no_root_squash
root_squash客户端使用NFS文件系统的账号若为root时,系统该如何判断这个账号的身份?预设的情况下,客户端root的身份会由root_squash的设定压缩成nfsnobody,如此对服务器的系统会交由保障。但如果想要开放客户端使用root身份来操作服务器的文件系统,那么就需要开no_root_squash才行 all_squash 不论登入NFS的使用者是什么身份,他的身份都会被压缩为匿名用户(nobody(nfsnobody)) anonuid
anongidanon指anonymous(匿名者)。关于*_squash提到的匿名用户的UID设定值,通常为nobody(nfsnobody),但是可以自行设定这个UID的值。当然,这个UID必须要存在于你的/etc/passwd当中。anonuid指的是UID而anongid则是群组的GID
- 启动服务通过showmount [-ae] [hostname|ip]查看共享目录
1
2systemctl start rpcbind && systemctl enable rpcbind
systemctl start nfs && systemctl enable nfs
- -a:显示目前主机与客户端的NFS联机分享的状态
- -e:显示某主机的的/etc/exports所分享的目录数据

k8s使用nfs-client-provisioner,创建PV和PVC
nfs-client-provisioner使用现有的和已配置的NFS服务器来支持通过持久卷声明动态配置 Kubernetes 持久卷。其本身不提供NFS,需要现有的NFS服务器提供存储。
- PV以
{namespace}-{pvcName}-{pvName}的命名格式提供 - PV回收时以
archieved-{namespace}-{pvcName}-{pvName}的命名格式提供
k8s部署nfs-client-provisioner的清单文件:
- deployment需要修改NFS服务器地址,以及NFS共享路径
- 官方配置说明参见NFS Ganesha server and external provisioner
使用NFS创建PV和PVC说明
k8s 创建PVC时,需指定
storageClassName,其值与StorageClass中配置的name相同。StorageClass中指定了
provisioner: fuseim.pri/ifs。其中fuseim.pri/ifs与PROVISIONER_NAME相同绑定PV如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15apiVersion: apps/v1
kind: Deployment
...
spec:
containers:
- ...
volumeMounts:
- name: data
mountPath: {container-filepath}
volumes:
- name: data
nfs:
server: {nfs-server-ip}
path: {nfs-shared-filepath}
...绑定PVC如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31apiVersion: apps/v1
kind: Deployment
...
spec:
containers:
- ...
volumeMounts:
- name: data
mountPath: {container-filepath}
volumes:
- name: data
persistentVolumeClaim:
claimName: {myapp-pvc}
...
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: {myapp-pvc}
namespace: {namespace}
spec:
storageClassName: {StorageClass} # StorageClass中配置的name
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi #存储卷大小
参照
鸟哥的Linux私房菜–NFS服务器
NFS Ganesha server and external provisioner