千家信息网

kubernetes的存储类介绍

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,k8s有很多的服务,很多的资源对象。如果要去创建服务,做数据持久化,需要预先知道可用PV有哪些?如果为了这个服务去提前创建PV,那么我们还需要知道,这个服务,大概需要多大的空间?环境介绍主机IP地址服
千家信息网最后更新 2026年11月01日kubernetes的存储类介绍

k8s有很多的服务,很多的资源对象。

如果要去创建服务,做数据持久化,需要预先知道可用PV有哪些?

如果为了这个服务去提前创建PV,那么我们还需要知道,这个服务,大概需要多大的空间?

环境介绍

主机IP地址服务
master192.168.1.21k8s
node01192.168.1.22k8s
node02192.168.1.23k8s

基于[ https://blog.51cto.com/14320361/2464655]() 的实验继续进行

存储类介绍

Kubernetes集群管理员通过提供不同的存储类,可以满足用户不同的服务质量级别、备份策略和任意策略要求的存储需求。动态存储卷供应使用StorageClass进行实现,其允许存储卷按需被创建。如果没有动态存储供应,Kubernetes集群的管理员将不得不通过手工的方式类创建新的存储卷。通过动态存储卷,Kubernetes将能够按照用户的需要,自动创建其需要的存储。

基于StorageClass的动态存储供应整体过程如下图所示:

1)集群管理员预先创建存储类(StorageClass);
2)用户创建使用存储类的持久化存储声明(PVC:PersistentVolumeClaim);
3)存储持久化声明通知系统,它需要一个持久化存储(PV: PersistentVolume);
4)系统读取存储类的信息;
5)系统基于存储类的信息,在后台自动创建PVC需要的PV;
6)用户创建一个使用PVC的Pod;
7)Pod中的应用通过PVC进行数据的持久化;
8)而PVC使用PV进行数据的最终持久化处理。

先来简单看一下这张图实现的过程,然后我们再来研究一下

说在前面的话,静态供给的话,会需要我们手动去创建pv,如果没有足够的资源,找不到合适的pv,那么pod就会处于pending等待的状态,就是说找不到合适的伴侣了,所以解决这两种问题,就给出了这种动态供给,主要是能够自动帮你创建pv
,就是你需要多大的容量,就自动给你创建多大的容量,也就是pv,k8s帮你创建了,创建pvc的时候就需要找pv了,这个时候就交给这个存储类了,而存储类呢,去帮你创建这些pv,存储类呢,就是实现了对指定存储的一个支持,直接帮你去调用api去创建存储类,所以就不需要人工的去帮你创建pv了。
而你去想想,当节点比较多,业务比较多的时候,再去人工手动创建pv,量还是很大的,而且也不是很好去维护。
而动态供给主要的一个实现就是StorageClass存储对象,其实它就是声明你使用哪个存储,然后呢帮你去连接,再帮你去自动创建pv。

举个例子更好去理解
话不多说下图

其实它是一个基于NFS实现的一个pv供给,它大概流程是这样的,我们可能会创建一个statefulset有状态的应用存储,然后有一个管理的nfs-storageClass,因为nfs目前是不支持这个自动的创建pv的,我们可以利用社区实现的插件来完成这个pv的自动创建,也就是StorageClass这一块,创建完之后,然后pod再去引用。

一,Storage Class(存储类)

作用:它可以动态的自动的创建所需要的PV

Provisioner(供给方,提供者):及提供了存储资源的存储系统。k8s内建有多重供给方,这些供给方的名字都以"kubernetes.io"为前缀。并且还可以自定义。

Parameters(参数):存储类使用参数描述要关联到的存储卷,注意不同的供给方参数也不同。

ReclaimPlicy: PV的回收策略,可用值有Delete(默认)和Retain

(1)确定基于NFS服务来做的SC。NFS开启

[root@master yaml]# showmount -e

(2)需要RBAC权限。

RBAC:rbac是k8s的API的安全策略,是基于用户的访问权限的控制。规定了谁,可以有什么样的权限。

为了给SC资源操作k8s集群的权限。

[root@master yaml]# vim rbac-rolebind.yamlkind: NamespaceapiVersion: v1metadata:  name: bdqn-test---apiVersion: v1kind: ServiceAccountmetadata:  name: nfs-provisioner  namespace: bdqn-test---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRolemetadata:  name: nfs-provisioner-runner  namespace: bdqn-testrules:   -  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: ["watch", "create", "update", "patch"]   -  apiGroups: [""]      resources: ["services", "endpoints"]      verbs: ["get","create","list", "watch","update"]   -  apiGroups: ["extensions"]      resources: ["podsecuritypolicies"]      resourceNames: ["nfs-provisioner"]      verbs: ["use"]---kind: ClusterRoleBindingapiVersion: rbac.authorization.k8s.io/v1metadata:  name: run-nfs-provisionersubjects:  - kind: ServiceAccount    name: nfs-provisioner    namespace: bdqn-testroleRef:  kind: ClusterRole  name: nfs-provisioner-runner  apiGroup: rbac.authorization.k8s.io

运行一下

[root@master yaml]# kubectl apply -f rbac-rolebind.yaml 

(3)nfs-deployment

作用:其实它是一个NFS客户端。但它通过K8S的内置的NFS驱动挂载远端的NFS服务器到本地目录;然后将自身作为storage provider,关联storage class。

[root@master yaml]# vim nfs-deployment.yamlapiVersion: extensions/v1beta1kind: Deploymentmetadata:  name: nfs-client-provisioner  namespace: bdqn-testspec:  replicas: 1  strategy:    type: Recreate  template:    metadata:      labels:        app: nfs-client-provisioner    spec:      serviceAccount: nfs-provisioner    #指定账户      containers:        - name: nfs-client-provisioner          image: registry.cn-hangzhou.aliyuncs.com/open-ali/nfs-client-provisioner          volumeMounts:            - name: nfs-client-root              mountPath:  /persistentvolumes   #指定容器内的挂载目录          env:            - name: PROVISIONER_NAME            #这是这个容器内置的变量              value: bdqn-test                  #这是上面变量的值(名字)            - name: NFS_SERVER                  #内置变量,用于指定nfs服务的IP              value: 192.168.1.21            - name: NFS_PATH                    #内置变量,指定的是nfs共享的目录              value: /nfsdata      volumes:                                  #这下面是指定上面挂载到容器内的nfs的路径及IP        - name: nfs-client-root          nfs:            server: 192.168.1.21            path: /nfsdata

执行一下

[root@master yaml]# kubectl apply -f nfs-deployment.yaml

(4)创建storageclass

[root@master yaml]# vim test-storageclass.yamlapiVersion: storage.k8s.io/v1kind: StorageClassmetadata:  name: stateful-nfs  namespace: bdqn-testprovisioner: bdqn-test  #这里要和第三个nfs-client-provisioner的env环境变量中的value值对应。reclaimPolicy: Retain   #回收策略为:retain,还有一个默认的值为"default"

执行一下

[root@master yaml]# kubectl apply -f test-storageclass.yaml

(5)创建PVC

[root@master yaml]# vim test-pvc.yamlapiVersion: v1kind: PersistentVolumeClaimmetadata:  name: test-claim  namespace: bdqn-testspec:  storageClassName: stateful-nfs   #定义存储类的名字,要和SC的名字对应  accessModes:    - ReadWriteMany         #访问模式为RWM  resources:    requests:      storage: 500Mi

执行一下

[root@master yaml]# kubectl apply -f test-pvc.yaml 

查看一下

[root@master yaml]# kubectl get pvc

(6)创建一个Pod

[root@master yaml]# vim test-pod.yamlkind: PodapiVersion: v1metadata:  name: test-pod  namespace: bdqn-testspec:  containers:  - name: test-pod    image: busybox    args:      - /bin/sh      - -c      - sleep 30000    volumeMounts:      - name: nfs-pvc        mountPath: /test  restartPolicy: OnFailure  volumes:    - name: nfs-pvc      persistentVolumeClaim:        claimName: test-claim  #这的名字要和PVC的名字一致

执行一下

[root@master yaml]# kubectl apply -f  test-pod.yaml 

查看一下

[root@master yaml]# kubectl get pod -n bdqn-test 

(7)容器中添加内容,并查看挂载目录

进入容器修改页面内容

[root@master yaml]# kubectl exec -it test-pod -n bdqn-test /bin/sh/ # cd test//test # touch test-file/test # echo 123456 > test-file /test # cat test-file 123456

查看挂载目录

[root@master yaml]# ls /nfsdata/bdqn-test-test-claim-pvc-79ddfcf1-65ae-455f-9e03-5bcfe6c6ce15web1web2[root@master yaml]# cat /nfsdata/bdqn-test-test-claim-pvc-79ddfcf1-65ae-455f-9e03-5bcfe6c6ce15/test-file 123456

如果,K8S集群中, 有很多类似的PV, PVC在去向PV申请空间的时候,不仅会考虑名称以及访问控制模式,还会考虑你申请空间的大小,会分配给你最合适大小的PV。

运行一个web服务,采用Deployment资源,基于nginx镜像,replicas为3个。数据持久化目录为nginx服务的主访问目录:/usr/share/nginx/html

创建一个PVC,与上述资源进行关联。

1. 基于nfs服务来做的PV和pvc

下载nfs所需安装包

[root@node02 ~]# yum -y install nfs-utils  rpcbind

创建共享目录

[root@master ~]# mkdir /nfsdata

创建共享目录的权限

[root@master ~]# vim /etc/exports/nfsdata *(rw,sync,no_root_squash)

开启nfs和rpcbind

[root@master ~]# systemctl start nfs-server.service [root@master ~]# systemctl start rpcbind

测试一下

[root@master ~]# showmount -e

2.先创建两个PV, web- pV1(1G) ,web-pv2 (2G)

web1

[root@master yaml]# vim web.yaml apiVersion: v1kind: PersistentVolumemetadata:  name: web-pvspec :  capacity:    storage: 1Gi  accessModes:    - ReadWriteOnce  persistentVolumeReclaimPolicy: Recycle  storageClassName: nfs  nfs:    path: /nfsdata/web1    server: 192.168.1.21

web2

[root@master yaml]# vim web2.yaml apiVersion: v1kind: PersistentVolumemetadata:  name: web-pv2spec :  capacity :    storage: 2Gi  accessModes:    - ReadWriteOnce  persistentVolumeReclaimPolicy: Recycle  storageClassName: nfs  nfs:    path: /nfsdata/web2    server: 192.168.1.21
3.创建所需文件夹
[root@master yaml]# mkdir /nfsdata/web1[root@master yaml]# mkdir /nfsdata/web2
4.执行一下web和web2
[root@master yaml]# kubectl apply -f web.yaml [root@master yaml]# kubectl apply -f web2.yaml 
5.查看一下
[root@master yaml]# kubectl get pv

6.创建web的pvc的yaml文件
[root@master yaml]# vim web-pvc.yaml apiVersion: v1kind: PersistentVolumeClaimmetadata:  name: web-pvcspec:  accessModes:  - ReadWriteOnce  resources:    requests:      storage: 1Gi  storageClassName: nfs

执行一下

[root@master yaml]# kubectl apply -f web-pvc.yaml 

查看一下

[root@master yaml]# kubectl get pvc

系统会自动给pvc一个相近内存的pv,所以选择了1G的那个

7.创建pod的yaml文件
[root@master yaml]# vim web-pod.yamlapiVersion: extensions/v1beta1kind: Deploymentmetadata:  name: web-podspec:  selector:    matchLabels:      app: nginx  template:    metadata:      labels:        app: nginx    spec:      containers:      - image: nginx        name: nginx        volumeMounts:        - name: web-test          mountPath: /usr/share/nginx/html      volumes:      - name: web-test        persistentVolumeClaim:          claimName: web-pvc
执行一下
[root@master yaml]# kubectl apply -f web-pod.yaml 
查看一下
[root@master yaml]# kubectl get pod

8. 访问一下nginx的网页
查看一下nginx的ip
[root@master yaml]# kubectl get pod -o wide

进入容器设置网页内容
root@master yaml]# kubectl exec -it web-pod-8686d9c594-qxhr9 /bin/bashroot@web-pod-8686d9c594-qxhr9:/# cd /usr/share/nginx/html/root@web-pod-8686d9c594-qxhr9:/usr/share/nginx/html# lsroot@web-pod-8686d9c594-qxhr9:/usr/share/nginx/html# echo 123456 > index.htmlroot@web-pod-8686d9c594-qxhr9:/usr/share/nginx/html# exit
访问一下
[root@master yaml]# curl 10.244.2.17

如果两个PV,大小一样,名称一样,访问控制模式不一样,PVC会关联哪一个? (验证PV和PVC 关联的时候,访问模式必须一样)

两个PV,大小一样,名称一样,访问控制模式不一样

<1>创建两个pv
web1
[root@master yaml]# vim web1.yaml apiVersion: v1kind: PersistentVolumemetadata:  name: web-pvspec :  capacity:    storage: 1Gi  accessModes:    - ReadWriteOnce  #能以读-写mount到单个的节点  persistentVolumeReclaimPolicy: Recycle  storageClassName: nfs  nfs:    path: /nfsdata/web1    server: 192.168.1.21
web2
[root@master yaml]# vim web2.yaml apiVersion: v1kind: PersistentVolumemetadata:  name: web-pvspec :  capacity:    storage: 1Gi  accessModes:    - ReadWriteMany        #能以读-写mount到多个的节点  persistentVolumeReclaimPolicy: Recycle  storageClassName: nfs  nfs:    path: /nfsdata/web1    server: 192.168.1.21
创建所需文件
[root@master yaml]# mkdir /nfsdata/web1
执行一下
[root@master yaml]# kubectl apply -f web1.yaml [root@master yaml]# kubectl apply -f web2.yaml 

<2>创建pvc
[root@master yaml]# vim web-pvc.yaml apiVersion: v1kind: PersistentVolumeClaimmetadata:  name: web-pvcspec:  accessModes:  - ReadWriteMany    #能以读-写mount到多个的节点  resources:    requests:      storage: 1Gi  storageClassName: nfs
执行一下
[root@master yaml]# kubectl apply -f web-pvc.yaml 
<3>查看一下
[root@master yaml]# kubectl get pv

[root@master yaml]# kubectl get pvc

现在可以看到pv和pvc关联成功,但是为什么只有一个pv呢?(pv挂载的目录要相同)

那是因为当创建了两个相同名字的pv时它并不会认为这是两个不同的pv,而会把他们当成是同一个pv,后创建的pv会刷新前面创建的pv。然后,当创建了pvc,并且pvc的访问模式和后面创建pv的访问模式一样,他们就会关联成功,反之不成功。(当然这些条件下还需要考虑,pv的内存)

(1)以自己的名称创建一个名称空间。以下所有资源都在此名称空间之下。

<1>编写namespace的yam文件

[root@master yaml]# vim namespace.yaml kind: NamespaceapiVersion: v1metadata:  name: xgp-znb

<2>执行一下

[root@master yaml]# kubectl apply -f namespace.yaml 

<3>查看一下

[root@master yaml]# kubectl get ns

(2)设置rbac权限。

下载所需镜像

docker pull registry.cn-hangzhou.aliyuncs.com/open-ali/nfs-client-provisioner

<1>编写rbac的yam文件

[root@master yaml]# vim rbac-rolebind.yamlkind: NamespaceapiVersion: v1metadata:  name: xgp-znb---apiVersion: v1kind: ServiceAccountmetadata:  name: nfs-provisioner  namespace: xgp-znb---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRolemetadata:  name: nfs-provisioner-runner  namespace: xgp-znbrules:   -  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: ["watch", "create", "update", "patch"]   -  apiGroups: [""]      resources: ["services", "endpoints"]      verbs: ["get","create","list", "watch","update"]   -  apiGroups: ["extensions"]      resources: ["podsecuritypolicies"]      resourceNames: ["nfs-provisioner"]      verbs: ["use"]---kind: ClusterRoleBindingapiVersion: rbac.authorization.k8s.io/v1metadata:  name: run-nfs-provisionersubjects:  - kind: ServiceAccount    name: nfs-provisioner    namespace: xgp-znbroleRef:  kind: ClusterRole  name: nfs-provisioner-runner  apiGroup: rbac.authorization.k8s.io

<2>执行一下

[root@master yaml]# kubectl apply -f  rbac-rolebind.yaml 

(3)创建nfs-deployment.yaml

<1>编写deployment的yam文件

[root@master yaml]# vim nfs-deployment.yamlapiVersion: extensions/v1beta1kind: Deploymentmetadata:  name: nfs-client-provisioner  namespace: xgp-znbspec:  replicas: 1  strategy:    type: Recreate  template:    metadata:      labels:        app: nfs-client-provisioner    spec:      serviceAccount: nfs-provisioner      containers:        - name: nfs-client-provisioner          image: registry.cn-hangzhou.aliyuncs.com/open-ali/nfs-client-provisioner          volumeMounts:            - name: nfs-client-root              mountPath:  /persistentvolumes          env:            - name: PROVISIONER_NAME              value: xgp-znb            - name: NFS_SERVER              value: 192.168.1.21            - name: NFS_PATH              value: /nfsdata      volumes:        - name: nfs-client-root          nfs:            server: 192.168.1.21            path: /nfsdata

<2>执行一下

[root@master yaml]# kubectl apply -f nfs-deployment.yaml

(4)创建storageclass自动创建PV。

<1>编写storageclass的yam文件

[root@master yaml]# vim storageclass.yamlapiVersion: storage.k8s.io/v1kind: StorageClassmetadata:  name: test-scprovisioner: xgp-znb   #通过provisioner字段关联到上述DeployreclaimPolicy: Retain

<2>执行一下

[root@master yaml]# kubectl apply -f storageclass.yaml

(5)创建PVC

<1>编写PVC的yaml文件

[root@master yaml]# vim pvc.yamlapiVersion: v1kind: PersistentVolumeClaimmetadata:  name: test-claim  namespace: xgp-znbspec:  storageClassName: test-sc  accessModes:    - ReadWriteMany  resources:    requests:      storage: 500Mi

<2>执行一下

[root@master yaml]# kubectl apply -f pvc.yaml 

<3>查看一下

[root@master yaml]# kubectl get pvc -n xgp-znb

(6)创建一个Pod, 基于nginx运行一个web服务,使用Deployment资源对象,replicas=3.持久化存储目录为默认主目录

<1>编写deployment的yam文件

[root@master yaml]# vim pod.yaml apiVersion: extensions/v1beta1kind: Deploymentmetadata:  name: web-pod  namespace: xgp-znbspec:  replicas: 3  selector:    matchLabels:      app: nginx  template:    metadata:      labels:        app: nginx    spec:      containers:      - image: nginx        name: nginx        volumeMounts:        - name: web-test          mountPath: /usr/share/nginx/html      volumes:      - name: web-test        persistentVolumeClaim:          claimName: test-claim

<2>执行一下

[root@master yaml]# kubectl apply -f pvc.yaml 

<3>查看一下

[root@master yaml]# kubectl get pod -n xgp-znb

(7)访问nginx页面

修改nginx主页

[root@master yaml]# kubectl exec -it web-pod-8cd956cc7-6szjb -n xgp-znb /bin/bash//进入容器之中root@web-pod-8cd956cc7-6szjb:/# echo  xgp-znb > /usr/share/nginx/html/index.html//添加自定义内容主机

访问一下

[root@master yaml]# curl 10.244.2.18

五个可移植性建议

  1. 把你的 pvc,和 其它一系列配置放一起, 比如说deployment,configmap
  2. 不要把你的pv放在其它配置里, 因为用户可能没有权限创建pv
  3. 初始化pvc 模版的时候, 提供一个storageclass
  4. 在你的工具软件中,watch那些没有bound的pvc,并呈现给用户
  5. 集群启动的时候启用DefaultStorageClass, 但是不要指定某一类特定的class, 因为不同provisioner的class,参数很难一致

volumn phase

1. 在PVC中绑定一个PV,可以根据下面几种条件组合选择
  • Access Modes, 按照访问模式选择pv
  • Resources, 按照资源属性选择, 比如说请求存储大小为8个G的pv
  • Selector, 按照pv的label选择
  • Class, 根据StorageClass的class名称选择, 通过annotation指定了Storage Class的名字, 来绑定特定类型的后端存储
2. 关于根据class过滤出pv的说明:所有的 PVC 都可以在不使用 StorageClass 注解的情况下,直接使用某个动态存储。把一个StorageClass 对象标记为 "default" 就可以了。StorageClass 用注解http://storageclass.beta.kubernetes.io/is-default-class 就可以成为缺省存储。有了缺省的 StorageClass,用户创建 PVC 就不用 storage-class 的注解了,1.4 中新加入的DefaultStorageClass 准入控制器会自动把这个标注指向缺省存储类。PVC 指定特定storageClassName,如fast时, 绑定名称为fast的storageClassPVC中指定storageClassName为""时, 绑定no class的pv(pv中无class annotation, 或者其值为"")PVC不指定storageClassName时, DefaultStorageClass admission plugin 开启与否(在apiserver启动时可以指定), 对default class的解析行为是不同的。当DefaultStorageClass admission plugin启用时, 针对没有storageClass annotation的pvc,DefaultStorageClass会分配一个默认的class, 这个默认的class需要用户指定,比如在创建storageclass对象时加入annotation,如 http://storageclass.beta.kubernetes.io/is-default-class: "true" 。如果有多个默认的class, 则pvc会被拒绝创建, 如果用户没有指定默认的class, 则这个DefaultStorageClass admission plugin不会起任何作用。 pvc会找那些no class的pv做绑定。当DefaultStorageClass admission plugin没有启用时, 针对没有storageClass annotation的pvc, 会绑定no class的pv(pv中无class annotation, 或者其值为"")
存储 服务 目录 文件 用户 资源 动态 名字 名称 模式 供给 关联 不同 容器 时候 权限 两个 集群 选择 变量 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技工作委员会副主任毛军 中关村互联网科技集团 互联网属科技 互联网最新的科技 互联网电商科技 金融科技创新监管互联网金融 科技与互联网发展 善班互联网科技 友谊互联网络科技 火传媒上海互联网科技 互联网金融 科技创新 老年人脱离互联网科技的作文 重庆威客帮互联网科技 互联网对科技的发展 恒生互联网科技指数跳水 广州市恰铎互联网科技有限公司 佛山市拉法互联网科技有限公司 互联网安防科技感 北京品多多互联网科技有限公司 东风日产互联网科技公司叫什么 深圳九邦互联网科技有限公司 科技和互联网公司 华中科技大学互联网 银优互联网科技有限公司 宁波青枫互联网科技有限公司 阿里巴巴算科技企业还是互联网 互联网科技革命什么开始 国大互联网教育科技有限公司工作 广州燕处互联网科技有限公司 广东猫王互联网科技有限公司电话
0