本文将介绍使用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 |
[root@master ~]# kubectl get nodesNAME STATUS ROLES AGE VERSIONmaster Ready control-plane,master 56d v1.21.5node1 Ready worker 56d v1.21.5node2 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
使用样例
- 创建一个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

我这里遇到了一个问题,执行 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#

