本文将介绍使用nfs-client-provisioner和NFS Server给Kubernetes作为持久存储的后端,并且动态提供PV的功能

环境

主机名 ip 角色
master 192.168.102.65 master
node1 192.168.102.66 node1
node2 192.168.102.67 node2
  1. [root@master ~]# kubectl get nodes
  2. NAME STATUS ROLES AGE VERSION
  3. master Ready control-plane,master 56d v1.21.5
  4. node1 Ready worker 56d v1.21.5
  5. node2 Ready worker 56d v1.21.5

安装 nfs

所有节点安装NFS客户端

yum install -y nfs-utils

选择一台做nfs server

进行如下配置(这里选择node2节点)

1、创建根目录

mkdir -p /data

2、编辑

[root@node2 ~]# cat /etc/exports    
/data/     192.168.102.0/24(rw,sync,no_root_squash,no_all_squash)

同192.168.102.0/24一个网络号的主机可以挂载NFS服务器上的/data 目录到自己的文件系统中

参数 说明
ro 只读访问
rw 读写访问
sync 所有数据在请求时写入共享
async nfs在写入数据前可以响应请求
secure nfs通过1024以下的安全TCP/IP端口发送
insecure nfs通过1024以上的端口发送
wdelay 如果多个用户要写入nfs目录,则归组写入(默认)
no_wdelay 如果多个用户要写入nfs目录,则立即写入,当使用async时,无需此设置
hide 在nfs共享目录中不共享其子目录
no_hide 共享nfs目录的子目录
subtree_check 如果共享/usr/bin之类的子目录时,强制nfs检查父目录的权限(默认)
no_subtree_check 不检查父目录权限
all_squash 共享文件的UID和GID映射匿名用户anonymous,适合公用目录
no_all_squash 保留共享文件的UID和GID(默认)
root_squash root用户的所有请求映射成如anonymous用户一样的权限(默认)
no_root_squash root用户具有根目录的完全管理访问权限
anonuid=xxx 指定nfs服务器/etc/passwd文件中匿名用户的UID
anongid=xxx 指定nfs服务器/etc/passwd文件中匿名用户的GID

3、启动nfs服务

systemctl start rpcbind.service
systemctl start nfs-server.service

4、设置开机自启

systemctl enable rpcbind.service
systemctl enable nfs-server.service

5、使用配置生效

exportfs -r

6、查看挂载情况

[root@node2 ~]# exportfs
/data             192.168.102.0/24

在另一个节点上验证

这里选择node1

mkdir -p /data
mount -t nfs 192.168.102.67:/data /data

查看挂载情况

[root@node1 ~]# df -h | grep /data
192.168.102.67:/data      91G   68G   24G  75% /data

可在master上添加一个文件,再node上是否可以查看

取消挂载(按需)

umount /data

安装nfs-provisioner

1、添加Helm存储库

helm repo add azure http://mirror.azure.cn/kubernetes/charts/

2、本地仓库搜

helm search repo nfs-client-provisioner

3、开始安装

helm install nfs-storage azure/nfs-client-provisioner \
--set nfs.server=192.168.102.54 \
--set nfs.path=/data/kubesphere \
--set storageClass.name=nfs-storage \
--set storageClass.defaultClass=true

说明:

  • nfs.server:nfs服务地址
  • nfs.path:nfs根目录
  • storageClass.name:存储类名称
  • storageClass.defaultClass:设为默认存储类

4、查看安装情况

[root@master ~]# kubectl get sc
NAME              PROVISIONER                                        RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
local (default)   openebs.io/local                                   Delete          WaitForFirstConsumer   false                  56d
nfs-storage       cluster.local/nfs-storage-nfs-client-provisioner   Delete          Immediate              true                   14d

安装的时候未指定 ns 所以在default当中

[root@master ~]# helm list
NAME           NAMESPACE    REVISION    UPDATED                                    STATUS      CHART                            APP VERSION
nfs-storage    default      1           2022-02-24 11:12:15.934965896 +0800 CST    deployed    nfs-client-provisioner-1.2.11    3.1.0

使用样例

  1. 创建一个pvc
# 配置
cat <<EOF >  pvc-test.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-test
spec:
  storageClassName: "nfs-storage"
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 10Mi
EOF

执行发布命令

kubectl apply -f pvc-test.yaml

查看pvc

# 查看列表
kubectl get pvc

查看nfs目录

生成了一个动态的持久化目录

命名规则为:命名空间+pvc名称+pvc标识+随机字符串

default-pvc-test-pvc-7524c9f3-eee3-4e0c-97e7-2462606ad085

image.png

我这里遇到了一个问题,执行 apply 命令创建pvc的时候一直无法成功,查看日志发现如下的报错信息:

provision “default/myclaim” class “nfs-storage”: unexpected error getting claim reference: selfLink was empty, can’t make reference

查看日志的方法

[root@master ~]# kubectl get pod -n default
NAME                                                 READY   STATUS    RESTARTS   AGE
nfs-storage-nfs-client-provisioner-5fd768b98-kqjvw   1/1     Running   0          14d
[root@master ~]# kubectl logs -f nfs-storage-nfs-client-provisioner-5fd768b98-kqjvw

selfLink was empty 在k8s集群 v1.20之前都存在,在v1.20之后被删除,需要在/etc/kubernetes/manifests/kube-apiserver.yaml 添加参数 —feature-gates=RemoveSelfLink=false

需要注意的是我这里是使用kubeadm 安装的安装的 kubernetes

root@master:~# cd /etc/kubernetes/manifests/
root@master:/etc/kubernetes/manifests# ls
etcd.yaml  kube-apiserver.yaml  kube-controller-manager.yaml  kube-scheduler.yaml
root@master:/etc/kubernetes/manifests#

image.png