Storageclass 外挂NFS配置与应用
Storageclass 外挂NFS配置与应用
1.StorageClass概念
PV 都是静态的,要使用的一个 PVC 的话就必须手动去创建一个 PV,这种方式在很大程度上并不能满足我们的需求,比如我们有一个应用需要对存储的并发度要求比较高,而另外一个应用对读写速度又要求比较高,特别是对于 StatefulSet 类型的应用简单的来使用静态的 PV 就很不合适了,这种情况下我们就需要用到动态 PV,这就需要 StorageClass动态的创建PV。
要使用 StorageClass,需要安装对应的自动配置程序,比如我们这里存储后端使用的是 nfs,那么我们就需要使用到一个 nfs-client 的自动配置程序,我们也叫它 Provisioner,这个程序使用我们已经配置好的 nfs 服务器,来自动创建持久卷,也就是自动帮我们创建 PV。
自动创建的 PV 以 ${namespace}-${pvcName}-${pvName} 这样的命名格式创建在 NFS 服务器上的共享数据目录中。
2.部署NFS
2.1 配置服务端
使用nfs作为外挂存储首先就是部署nfs服务器。
[root@k8s-master-3 ~]# yum -y install nfs-utils
[root@k8s-master-3 ~]# cat /etc/exports
/data/nfs 172.16.1.0/24(rw,sync,no_subtree_check,no_root_squash)
no_root_squash # 以root身份来执行文件的操作,这样数据目录中的文件就可以被挂载对象使用权限更改的命令,笔者因权限问题,k8s一直报错 already present on machine ;通过pod日志查看才知道在容器中执行chown命令而出错。
# 建议将数据目录的权限调到最大来避免因权限引发对k8s内部的错误。
# 下面的图片中容器通过chown命令更改了属组,而引发了一系列的报错。起先就是在nfs上面没有权限的原因。
mkdir /data/nfs
chmod 777 /data/nfs
systemctl start nfs
systemctl enable nfs
2.2 客户端验证
[root@k8s-master-3 nfs]# exportfs -avr
exporting 172.16.1.0/24:/data/nfs
[root@k8s-master-2 mnt]# showmount -e 172.16.1.83
Export list for 172.16.1.83:
/data/nfs 172.16.1.0/24
3.部署Storageclass
3.1 克隆代码
git clone https://github.com/kubernetes-incubator/external-storage.git
3.2 创建角色绑定
cd external-storage/nfs-client/deploy
cat rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: default
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: nfs-client-provisioner-runner
rules:
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "list", "watch", "update"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["create", "update", "patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: run-nfs-client-provisioner
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: default
roleRef:
kind: ClusterRole
name: nfs-client-provisioner-runner
apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: leader-locking-nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: default
rules:
- apiGroups: [""]
resources: ["endpoints"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: leader-locking-nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: default
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: default
roleRef:
kind: Role
name: leader-locking-nfs-client-provisioner
apiGroup: rbac.authorization.k8s.io
kubectl apply -f rbac.yaml
3.2 部署 nfs client 插件
[root@k8s-master-1 deploy]# cat deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nfs-client-provisioner
labels:
app: nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: default
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: nfs-client-provisioner
template:
metadata:
labels:
app: nfs-client-provisioner
spec:
serviceAccountName: nfs-client-provisioner
containers:
- name: nfs-client-provisioner
# 如果地址下载比较慢可以先把镜像下载下来然后,修改这里的地址
image: quay.io/external_storage/nfs-client-provisioner:latest
# 1.20 之后的版本用这个image easzlab/nfs-subdir-external-provisioner:v4.0.1
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME
# 与class 中的provisioner要一致
value: fuseim.pri/ifs
- name: NFS_SERVER
value: 172.16.1.83 # <=====NFS服务器的地址
- name: NFS_PATH
value: /data/nfs # <=====NFS服务器的路径
volumes:
- name: nfs-client-root
nfs:
server: 172.16.1.83 # <=====NFS服务器的地址
path: /data/nfs # <=====NFS服务器的路径
kubectl apply -f deployment.yaml
3.3 创建Storageclass
[root@k8s-master-1 deploy]# cat class.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: managed-nfs-storage
# or choose another name, must match deployment's env PROVISIONER_NAME'
# 这里的名字要与deployment中PROVISIONER_NAME的名字一致
provisioner: fuseim.pri/ifs
parameters:
archiveOnDelete: "false"
kubectl apply -f class.yaml
4.查看 nfs 客户端 和 Storageclass
[root@k8s-master-1 deploy]# kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
managed-nfs-storage (default) fuseim.pri/ifs Delete Immediate false 6h42m
[root@k8s-master-1 deploy]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nfs-client-provisioner-7bf6ff7b75-8p55n 1/1 Running 4 6h43m
5.验证storageclass
5.1 创建pvc
申请一个名字叫做test-claim的pv,从storageclass managed-nfs-storage中申请。
[root@k8s-master-1 pvtest]# cat pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: test-claim
annotations:
# 这里指定了是用storageclass
volume.beta.kubernetes.io/storage-class: "managed-nfs-storage"
spec:
accessModes: # 策略
- ReadWriteMany
resources:
requests:
storage: 1Mi # 请求空间大小
kubectl apply -f pvc.yaml
5.2 使pvc,绑定pv
[root@k8s-master-1 pvtest]# cat test-pod.yaml
kind: Pod
apiVersion: v1
metadata:
name: test-pod
spec:
containers:
- name: test-pod
image: docker.io/library/busybox:latest
command:
- "/bin/sh"
args:
- "-c"
- "touch /mnt/SUCCESS && exit 0 || exit 1"
volumeMounts:
- name: nfs-pvc # 绑定pvc
mountPath: "/mnt"
restartPolicy: "Never"
volumes:
- name: nfs-pvc #pvc 通过pvc 动态创建pv
persistentVolumeClaim:
claimName: test-claim # <=====这里指向了上面创建的pvc
kubectl apply -f test-pod.yaml
查看、验证
[root@k8s-master-1 pvtest]# kubectl get pv
pvc-c1dde5e5-c91a-4d4e-98f1-2b022438bcd7 1Mi RWX Delete Bound default/test-claim managed-nfs-storage 7m19s
6.设置为默认存储
使用storageclass的方式有两种一种是在创建pvc资源配置清单中指定使用。另外一种方法就是把它设置为默认的存储。
[root@k8s-master-1 pvtest]# cat pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: test-claim
annotations:
# 这里指定了是用storageclass,如果storageclass是默认的存储方式则这里可以不用写。
volume.beta.kubernetes.io/storage-class: "managed-nfs-storage"
spec:
accessModes: # 策略
- ReadWriteMany
resources:
requests:
storage: 1Mi # 请求空间大小
kubectl apply -f pvc.yaml
6.1 设置为默认的存储方式
kubectl patch storageclass managed-nfs-storage -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
managed-nfs-storage # storageclass 配置的名字
[root@k8s-master-1 pvtest]# kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
managed-nfs-storage (default) fuseim.pri/ifs Delete Immediate false 7h28m
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具