NFS 通过 rook 进行部署

NFS 通过 rook 进行部署

文章目录

NFS 介绍

NFS(Network File System)即网络文件系统, 是FreeBSD支持的文件系统中的一种。NFS是基于RPC(Remote Procedure Call)远程过程调用实现,其允许一个系统在网络上与它人共享目录和文件。通过使用NFS,用户和程序就可以像访问本地文件一样访问远端系统上的文件。NFS是一个非常稳定的,可移植的网络文件系统。具备可扩展和高性能等特性,达到了企业级应用质量标准。由于网络速度的增加和延迟的降低,NFS系统一直是通过网络提供文件系统服务的有竞争力的选择。

NFS 使用方式

  1. 已有NFS集群,例如公司QCE 申请的NFS集群, 在K8S中创建PVC和STorageClass ,一般通过 Kubernetes NFS Subdir External Provisioner 创建动态的provisioner,然后就可以在集群中使用NFS服务了;

2.物理机上手动安装NFS集群, 通过linux命令进行安装, 然后可以按照 1 进行使用;

3.通过K8S进行安装, 安装方式有多种 NFS Provisioner 以及 rook 等, 通过k8s 管理nfs 集群, 然后对外提供服务;

此处主要介绍在 k8s 中安装nfs 服务并对集群内外提供服务.

NFS 安装

主要步骤

  • Step0: 创建Local Persistent Volume;
  • Step1: 创建StorageClass;
  • Step2: 创建PVC, 关联 Step2 中的StorageClass;
  • Step3: 部署NFS Operator;
  • Step4: 创建NFS Server;
  • Step5: 创建NFS Storage Class;
  • Step6: 创建 Pod 并使用NFS;
  • Step7: 让集群外部服务也可以访问NFS Server;

Step0: 创建 Local Persistent Volume

首先在集群的宿主机(k8s-node2)创建挂载点, 比如 /mnt/disk; 然后 用RAM Disk 来模拟本地磁盘, 如下所示:

1# 在 k8s-node2 上执行
2$ mkdir /mnt/disks
3$ for vol in vol1 vol2 vol3; do
4      mkdir -p /mnt/disks/$vol
5      mount -t tmpfs $vol /mnt/disks/$vol
6   done
1$ df 查看
2vol3            7.8G     0  7.8G   0% /mnt/disks/vol3
3vol1            7.8G     0  7.8G   0% /mnt/disks/vol1
4vol2            7.8G     0  7.8G   0% /mnt/disks/vol2

注意: 其他机器如果也要创建 Local Persistent Volume, 那就执行相同的操作,但是磁盘名字不能重复.

接下来,定义PV, 如下所示:

 1apiVersion: v1
 2kind: PersistentVolume
 3metadata:
 4  name: example-pv
 5spec:
 6  accessModes:
 7  - ReadWriteOnce
 8  capacity:
 9    storage: 5Gi
10  local:
11    path: /mnt/disks/vol1
12  nodeAffinity:
13    required:
14      nodeSelectorTerms:
15      - matchExpressions:
16        - key: kubernetes.io/hostname
17          operator: In
18          values:
19          - k8s-node2
20  persistentVolumeReclaimPolicy: Delete
21  storageClassName: local-storage
22  volumeMode: Filesystem

这个 PV 的定义里:local 字段,指定了它是一个 Local Persistent Volume; 而 path 字段,指定的正是这个 PV 对应的本地磁盘的路径,即:/mnt/disks/vol1。

接下来, 我们使用 kubectl create 来创建这个PV, 如下所示:

1➜   kubectl get pv 
2NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM                       STORAGECLASS      REASON   AGE
3example-pv                                 5Gi        RWO            Delete           Available                               local-storage              6s

可以看到,example-pv创建后已经变成可用可用状态了.

Step1: 创建StorageClass

通过StorageClass 描述 PV, 如下所示:

1apiVersion: storage.k8s.io/v1
2kind: StorageClass
3metadata:
4  name: local-storage
5provisioner: kubernetes.io/no-provisioner
6reclaimPolicy: Delete
7volumeBindingMode: WaitForFirstConsumer

这里有两个重要的字段: provisioner: 我们使用no-provisioner, 这是因为 Local Persistent Volume 目前尚不支持Dynamic Provisioning,所以它没办法在用户创建 PVC 的时候,就自动创建出对应的PV。 volumeBindingMode: WaitForFirstConsumer, 指定了延迟绑定.因为Local Persistent 需要等到调度时才可以进行绑定操作. 通过 kubectl create 来创建 StorageClass, 如下所示:

1➜  kubectl create -f sc.yaml
2storageclass.storage.k8s.io/local-storage created
3➜  kubectl get sc
4NAME              PROVISIONER                                     RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
5local-storage     kubernetes.io/no-provisioner                    Delete          WaitForFirstConsumer   false                  25s

Step2: 创建PVC

这里我们定义一个PVC来使用之前定义好的Local PV, 如下所示:

 1apiVersion: v1
 2kind: PersistentVolumeClaim
 3metadata:
 4  name: example-local-claim
 5  namespace: rook-nfs
 6spec:
 7  accessModes:
 8  - ReadWriteOnce
 9  resources:
10    requests:
11      storage: 5Gi
12  storageClassName: local-storage
13  volumeMode: Filesystem
14  volumeName: example-pv

接下来创建这个PVC:

1➜  kubectl create -f example-local-claim.yaml
2persistentvolumeclaim/example-local-claim created
3➜  kubectl get pvc -n rook-nfs
4NAME                  STATUS   VOLUME       CAPACITY   ACCESS MODES   STORAGECLASS    AGE
5example-local-claim   Bound    example-pv   5Gi        RWO            local-storage   25s

注意: 这里我们指定了namespace 为rook-nfs , 这是为了方便nfs operator 使用.

Step3: 部署NFS Operator

安装 rook 之前需要先安装 NFS Client 安装包。在 CentOS 节点上安装 nf-utils,在 Ubuntu 节点上安装 nf-common。然后就可以安装 Rook 了。

1$ git clone --single-branch --branch v1.7.3 https://github.com/rook/nfs.git
2cd rook/cluster/examples/kubernetes/nfs
3kubectl create -f crds.yaml
4kubectl create -f operator.yaml

检查operator 是否运行正常:

1➜   kubectl -n rook-nfs-system get pod
2NAME                                READY   STATUS    RESTARTS   AGE
3rook-nfs-operator-d489f8c4b-4hr9m   1/1     Running   0          33s

Step4: 创建NFS Server

现在 operator 已经运行起来了,我们可以通过创建 nfsservers.nfs.rook.io 资源的实例来创建NFS服务器的实例,在这之前我们需要创建 ServiceAccount 和 RBAC规则:

1➜  kubectl create -f rbac.yaml
2namespace/rook-nfs created
3serviceaccount/rook-nfs-server created
4clusterrole.rbac.authorization.k8s.io/rook-nfs-provisioner-runner created
5clusterrolebinding.rbac.authorization.k8s.io/rook-nfs-provisioner-runner created

接下来 将以下内容保存到nfs.yaml:

 1apiVersion: nfs.rook.io/v1alpha1
 2kind: NFSServer
 3metadata:
 4  name: rook-nfs
 5  namespace: rook-nfs
 6spec:
 7  replicas: 1
 8  exports:
 9    - name: share1
10      server:
11        accessMode: ReadWrite
12        squash: "none"
13      # A Persistent Volume Claim must be created before creating NFS CRD instance.
14      persistentVolumeClaim:
15        claimName: example-local-claim
16        #claimName: nfs-default-claim
17  # A key/value list of annotations
18  annotations:
19    rook: nfs

然后通过kubectl create 创建 NFSf 服务器:

1➜  kubectl create -f nfs.yaml
2nfsserver.nfs.rook.io/rook-nfs created

验证 nfs server 是否运行正常:

1➜  kubectl get pod -n rook-nfs
2NAME         READY   STATUS    RESTARTS   AGE
3rook-nfs-0   2/2     Running   0          6m9s

Step5: 创建NFS Storage Class

部署OPerator 和 NFSServer实例之后,. 必须创建 StrorageClass 来动态配置 Volume:

 1apiVersion: storage.k8s.io/v1
 2kind: StorageClass
 3metadata:
 4  labels:
 5    app: rook-nfs
 6  name: rook-nfs-share1
 7parameters:
 8  exportName: share1
 9  nfsServerName: rook-nfs
10  nfsServerNamespace: rook-nfs
11provisioner: nfs.rook.io/rook-nfs-provisioner
12reclaimPolicy: Delete
13volumeBindingMode: Immediate

通过 kubectl create 创建:

1➜  kubectl create -f sc.yaml
2storageclass.storage.k8s.io/rook-nfs-share1 created

这里 StorageClass 需要传递以下三个参数:

  1. exportName: 告诉provisioner 使用那个 export;
  2. nfsServerName: NFSServer 实例名字;
  3. nfsServerNamespace:NFSServer实例运行的命名空间;

StorageClass创建之后, 我们接下来就可以创建PVC来引用它:

 1apiVersion: v1
 2kind: PersistentVolumeClaim
 3metadata:
 4  name: rook-nfs-pv-claim
 5spec:
 6  storageClassName: "rook-nfs-share1"
 7  accessModes:
 8    - ReadWriteMany
 9  resources:
10    requests:
11      storage: 1Mi

通过kubectl create 进行创建:

1➜  kubectl create -f pvc.yaml
2persistentvolumeclaim/rook-nfs-pv-claim created

Step6: 创建 Pod 并使用NFS

官方给出的例子 是通过 busybox-rc.yaml 和 web-rc.yaml 创建出两个POD:

  1. web server 用来读取和展示 NFS share 的内容;
  2. busybox 是往 NFS share写入随机数据,以便 website的内容可以一直更新; 然后通过 web-service.yaml 创建一个service;

最后通过以下命令查看内容:

1
2
3$ echo; kubectl exec $(kubectl get pod -l app=nfs-demo,role=busybox -o jsonpath='{.items[0].metadata.name}') -- wget -qO- http://$(kubectl get services nfs-web -o jsonpath='{.spec.clusterIP}'); echo
4Mon Sep 13 12:20:59 UTC 2021
5nfs-busybox-77c79b4b7b-5fc2w

Step7: 让集群外部服务也可以访问NFS Server

如果外部服务也可以访问NFS Server ,则可以通过修改 rook-nfs 的Service 类型为NodePort 来暴露 NFS 服务:

1
2
3➜  kubectl get svc -n rook-nfs
4NAME       TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)                        AGE
5rook-nfs   NodePort   10.1.191.178   <none>        2049:32401/TCP,111:31081/TCP   45m

换到其他机器上 通过 mount 进行连接:

1
2➜  ~ mkdir -p  /mnt/nfs/share
3➜  ~ mount -t nfs -o port=32401  10.41.24.236:/ /mnt/nfs/share
4➜  ~ cd /mnt/nfs/share
5➜  share ls
6example-local-claim
7➜  share cd example-local-claim
8➜  example-local-claim ls
9default-rook-nfs-pv-claim-pvc-476a215e-120c-4f76-a73f-3641a5f2af9f

参考

Network Filesystem (NFS) Quickstart
透過 K8S 建立 NFS 服務