Kubernetes搭建NFS原生服务
NFS是一个网络文件系统,可以将存储服务器的磁盘共享到集群范围内使用。虽然有Rook、CephFS、Gluster、Swift、Cinder、HDFS等集群存储系统以及Google、微软、百度的网盘,但NFS使用简单,性能也还不错,是快速自建集群的存储的首选方案,而且通过Kubernetes的PV/PVC等接口,以后还可以容易地迁移到新的存储系统。
使用NFS有几种情况:
- 已有NFS集群。只需要创建pv,然后就可以通过pvc和StorageClass来请求磁盘空间。
- 参考:
- 裸机新装NFS集群。安装完NFS服务后,使用跟上面一样。
- Kubernetes中新装NFS集群。在Kubernetes中创建NFS-provisioner作为服务管理,然后再提供pv服务,通过pvc和StorageClass来请求磁盘空间。
- 所用脚本资源:https://github.com/openthings/kubernetes-tools/tree/master/nfs
这里主要介绍Kubernetes中新装NFS集群及其使用。
NFS支持Helm安装工具,按照下面操作:
- Kubernetes存储系统-NFS的Helm部署,
- 请使用最新的版本,Ubuntu 18.04+JupyterHub的NFS服务 Bug 修复
- 查看最新版本,http://quay.io/kubernetes_incubator/nfs-provisioner
但是,缺省情况下的安装是不支持持久化的,NFS服务的数据保存在临时目录中,关机会丢失数据,容量也有限。如果主机临时目录空间被耗光,还会导致主机奔溃。因此,需要将NFS的数据安装到持久卷(PV)中。在GCP云环境中,会提供StorageClass可以直接创建出PV。在私有环境中,可以使用HostPath创建PV,然后创建PVC,就可以了配置到NFS的Helm参数文件中进行NFS安装了。
第一步,创建宿主机PV和PVC
关于Kubernetes的存储架构,参考:
- Kubernetes存储之Persistent Volumes,
1、创建宿主机的PV
这里的pv和pvc是nfs服务所使用的,而不是nfs提供的,使用HostPath卷来提供。参考:
- https://github.com/openthings/kubernetes-tools/blob/master/nfs/nfs-data-pv.yaml
主要内容如下:
apiVersion: v1
kind: PersistentVolume
metadata:
name: data-nfs-server-provisioner-0
spec:
capacity:
storage: 200Gi
accessModes:
- ReadWriteOnce
hostPath:
path: /srv/volumes/data-nfs-server-provisioner-0
claimRef:
namespace: default
name: data-nfs-server-nfs-server-provisioner-0
然后,运行:
kubectl create -f nfs-data-pv.yaml
基于HostPath创建的PV完成,可以到Kubernetes的Dashboard查看持久卷。其中数据的保存路径为path: /srv/volumes/data-nfs-server-provisioner-0。
2、创建供NFS存储的PVC
创建一个跟上面对应的PVC,配置文件如下(https://github.com/openthings/kubernetes-tools/blob/master/nfs/nfs-data-pvc.yaml):
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data-nfs-server-nfs-server-provisioner-0
spec:
storageClassName: ""
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 200Gi
运行:
kubectl create -f nfs-data-pvc.yaml
至此,NFS需要的基础存储已经准备好了。
第二步,安装NFS Provisioner
运行https://github.com/openthings/kubernetes-tools/blob/master/nfs/nfs-install.sh,内容如下:
helm install ./nfs-server-provisioner --name nfs-server --namespace default
- 注意,一定要在上面第一步之后运行,否则将会自动使用StorageClass来创建所用的持久卷,而目前持久卷默认的是gcp/aws之类的云存储,会导致失败,一直处于pending状态。
其中的values.yaml文件做了一些修改,注意里面的这些部分。如下:
persistence:
enabled: true
storageClass: ""
accessMode: ReadWriteOnce
size: 200Gi
## For creating the StorageClass automatically:
storageClass:
create: true
defaultClass: false
name: nfs
到Kubernetes的Dashboard查看NFS所提供的PV、StorageClass。注意这里的PV是逻辑上的,使用了上面第一步通过HostPath物理磁盘目录上创建的PV。
第三步,使用NFS的PV和PVC
1、创建PVC
首先,分配一个pvc,命名为nfs-pvc,内容如下(https://github.com/openthings/kubernetes-tools/blob/master/nfs/nfs-pvc.yaml):
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-pvc
spec:
storageClassName: "nfs"
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Mi
2、创建应用
然后,创建一个测试应用,将使用nfs-pvc,内容如下(https://github.com/openthings/kubernetes-tools/blob/master/nfs/nfs-pvc-client.yaml):
# This mounts the nfs volume claim into /mnt and continuously
# overwrites /mnt/index.html with the time and hostname of the pod.
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: busybox-deployment
spec:
replicas: 1
# selector:
# name: busybox-deployment
template:
metadata:
labels:
name: busybox-deployment
spec:
containers:
- image: busybox
command:
- sh
- -c
- 'while true; do date > /mnt/index.html; hostname >> /mnt/index.html; sleep $(($RANDOM % 5 + 5)); done'
imagePullPolicy: IfNotPresent
name: busybox
volumeMounts:
# name must match the volume name below
- name: nfs
mountPath: "/mnt"
#
volumes:
- name: nfs
persistentVolumeClaim:
claimName: nfs-pvc
3、查看持久化的数据
到宿主机,进入目录/srv/volumes/data-nfs-server-provisioner-0,可以看到NFS的配置、日志以及所分配的pv卷作为一个目录,里面包含了相应的数据(上面的pod生成的文件index.html)。
高级,多个磁盘的处理
- 注意:
- 通过NFS提供的存储服务,直接使用了物理磁盘,因此磁盘问题仍然会影响存储的可靠性、可用性。在kubernetes中运行主要改进了部署和管理的效率。
- NFS不提供存储冗余、故障转移、复制等功能,如果需要使用更高级的Rook、Ceph、HDFS等复制性冗余存储系统。
上面的方法,是将一个宿主机目录映射为NFS的PV卷,然后在NFS上面可以分配若干个逻辑PV,通过PVC或者StorageClass动态创建。
如果要将多个设备磁盘挂载进PV卷,方法包括:
- 有磁盘阵列的话,组装为一个逻辑盘。不过,JBOD之类的磁盘失效问题仍然是存在的。
- 可以使用mount将其它磁盘作为子目录挂载进主目录,但其每个子目录容量取决于原始磁盘目录的大小,不能平滑延展。
- 也可以将多个磁盘使用LVM首先组装为一个逻辑大盘,然后再挂载进来,可以作为一个磁盘整体进行存储操作。
- 可以运行多个NFS实例。需要修改的配置参数比较多,不建议使用。
更多参考:
- “基于Kubernetes的容器存储系统”-