目录

一、概述

StorageClass运行原理

搭建StorageClass+NFS,大致有以下几个步骤:

StorageClass 动态供给

 核心架构

存储方案选型对比

storageclass字段

二、安装nfs provisioner,用于配合存储类动态生成pv

案例:

1、创建运行nfs-provisioner需要的sa账号

2、安装nfs-provisioner程序

更新资源清单文件

查看nfs-provisioner是否正常运行

3 创建storageclass,动态供给pv

查看storageclass是否创建成功

4、创建pvc,通过storageclass动态生成pv

提交资源清单

查看是否动态生成了pv,pvc是否创建成功,并和pv绑定

 ​编辑

步骤总结:

5、创建pod,挂载storageclass动态生成的pvc:storage-pvc

更新资源清单文件

查看pod是否创建成功

查看一下路径

​编辑

查看index.html的物理位置

6、删除read-pod ,删除pvc 会自动删除pv ,所以默认的回收策略是delete是可以验证出来的

重新更新pvc文件,会发现物理nfs中多了一个目录。


一、概述

上面介绍的PV和PVC模式都是需要先创建好PV,然后定义好PVC和pv进行一对一的Bond,但是如果PVC请求成千上万,那么就需要创建成千上万的PV,对于运维人员来说维护成本很高,Kubernetes提供一种自动创建PV的机制,叫StorageClass,它的作用就是创建PV的模板。k8s集群管理员通过创建storageclass可以动态生成一个存储卷pv供k8s pvc使用。

每个StorageClass都包含字段provisioner,parameters和reclaimPolicy。

具体来说,StorageClass会定义以下两部分:

1、PV的属性 ,比如存储的大小、类型等;

2、创建这种PV需要使用到的存储插件,比如Ceph、NFS等

有了这两部分信息,Kubernetes就能够根据用户提交的PVC,找到对应的StorageClass,然后Kubernetes就会调用 StorageClass声明的存储插件,创建出需要的PV。

StorageClass运行原理

  • volumeClaimTemplates实现了pvc的自动化,StorageClass实现了pv的自动化

  • 每个 StorageClass 都包含 provisioner、parameters 和 reclaimPolicy 字段, 这些字段会在 StorageClass 需要动态分配 PersistentVolume 时会使用到。

  • StorageClass 对象的命名很重要,用户使用这个命名来请求生成一个特定的类。 当创建 StorageClass 对象时,管理员设置 StorageClass 对象的命名和其他参数,一旦创建了对象就不能再对其更新。

  • 管理员可以为没有申请绑定到特定 StorageClass 的 PVC 指定一个默认的存储类

要使用 StorageClass,我们就得安装对应的自动配置程序,比如我们这里存储后端使用的是 nfs,那么我们就需要使用到一个 nfs-client 的自动配置程序,我们也叫它 Provisioner(制备器),这个程序使我们已经配置好的 nfs 服务器,来自动创建持久卷,也就是自动帮我们创建 PV。

搭建StorageClass+NFS,大致有以下几个步骤:
1.创建一个可用的NFS Serve(实际存储文件的空间)
2.创建Service Account 这是用来管控NFS provisioner在k8s集群中运行的权限
3.创建StorageClass 负责建立PVC并调用NFS provisioner进行预定的工作,并让PV与PVC建立管理
4.创建NFS provisioner(存储制备器)
    1)每个 StorageClass 都有一个制备器(Provisioner)用来决定使用哪个卷插件制备 PV。 该字段必须指定。
    2)主要有两个功能
        一个是在NFS共享目录下创建挂载点(volume)
        另一个则是建了PV并将PV与NFS的挂载点建立关联

StorageClass 动态供给

 核心架构
graph TB  
    PVC-->|1.申请存储| StorageClass  
    StorageClass-->|2.调用| Provisioner  
    Provisioner-->|3.创建| PV  
    PV-->|4.绑定| PVC  
    Pod-->|5.挂载| PVC  

存储方案选型对比

特性 emptyDir hostPath NFS PVC+StorageClass
持久性 ❌ Pod删除消失 ⚠️ 节点故障丢失 ✅ 持久化 ✅ 持久化
多节点共享
动态扩容
生产环境适用性
典型场景 临时缓存 节点日志收集 团队文件共享 数据库/有状态服务

storageclass字段

#查看定义的storageclass需要的字段
[root@k8s-master~]# kubectl explain storageclass
KIND:     StorageClass
VERSION:  storage.k8s.io/v1
DESCRIPTION:
    StorageClass describes the parameters for a class of storage for which
    PersistentVolumes can be dynamically provisioned.
    StorageClasses are non-namespaced; the name of the storage class according
    to etcd is in ObjectMeta.Name.
FIELDS:
  allowVolumeExpansion    <boolean>
  allowedTopologies   <[]Object>
  apiVersion  <string>
  kind<string>
  metadata<Object>
  mountOptions    <[]string>
  parameters  <map[string]string>
   provisioner<string> -required-
  reclaimPolicy   <string>
  volumeBindingMode   <string>

二、安装nfs provisioner,用于配合存储类动态生成pv

案例:

1、创建运行nfs-provisioner需要的sa账号

        (在nfs服务器上操作)

        注意名称一定要相同

[root@k8s-master pvc]# cat sa.yaml 

apiVersion: v1
kind: Namespace
metadata:
  name: newnfs
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: nfs-client-provisioner
  namespace: newnfs
---
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
    namespace: newnfs
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
  namespace: newnfs
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
  namespace: newnfs
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    namespace: newnfs
roleRef:
  kind: Role
  name: leader-locking-nfs-client-provisioner
  apiGroup: rbac.authorization.k8s.io
[root@k8s-master pvc]# kubectl apply -f sa.yaml 
namespace/newnfs created
serviceaccount/nfs-client-provisioner created
clusterrole.rbac.authorization.k8s.io/nfs-client-provisioner-runner created
clusterrolebinding.rbac.authorization.k8s.io/run-nfs-client-provisioner created
role.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner created
rolebinding.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner created
2、安装nfs-provisioner程序

#把/data变成nfs共享的目录


[root@k8s-master pvc]# vim /etc/exports
/data 192.168.158.0/24(rw,sync,no_root_squash)
/data 192.168.158.0/24(rw,no_root_squash)
/data/v1 192.168.158.0/24(rw,no_root_squash)
/data/v2 192.168.158.0/24(rw,no_root_squash)
/data/v3 192.168.158.0/24(rw,no_root_squash)
/data/v4 192.168.158.0/24(rw,no_root_squash)
/data/v5 192.168.158.0/24(rw,no_root_squash)
/data/v6 192.168.158.0/24(rw,no_root_squash)
/data/v7 192.168.158.0/24(rw,no_root_squash)
/data/v8 192.168.158.0/24(rw,no_root_squash)
/data/v9 192.168.158.0/24(rw,no_root_squash)
/data/v10 192.168.158.0/24(rw,no_root_squash)
~                                              
[root@k8s-master pvc]# vim  nfs.yaml 
kind: Deployment
apiVersion: apps/v1
metadata:
  name: nfs-client-provisioner
  namespace: newnfs
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nfs-client-provisioner
  strategy:
    type: Recreate        #设置升级策略为删除再创建(默认为滚动更新)
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      serviceAccountName: nfs-client-provisioner  #上一步创建的ServiceAccount名称
      containers:
        - name: nfs-client-provisioner
          image: registry.cn-beijing.aliyuncs.com/mydlq/nfs-subdir-external-provisioner:v4.0.0
          imagePullPolicy: IfNotPresent
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes     
          env:
            - name: PROVISIONER_NAME  # Provisioner的名称,以后设置的storageclass要和这个保持一致
              value: storage-nfs
            - name: NFS_SERVER        # NFS服务器地址,需和valumes参数中配置的保持一致
              value: 192.168.158.33
            - name: NFS_PATH          # NFS服务器数据存储目录,需和volumes参数中配置的保持一致
              value: /data
            - name: ENABLE_LEADER_ELECTION
              value: "true"
      volumes:
        - name: nfs-client-root
          nfs:
            server: 192.168.158.33       # NFS服务器地址
            path: /data        # NFS共享目录
更新资源清单文件
[root@k8s-master pvc]# kubectl apply -f nfs.yaml 
deployment.apps/nfs-client-provisioner created
查看nfs-provisioner是否正常运行
[root@k8s-master pvc]# kubectl -n newnfs get pods | grep nfs
NAME                                     READY   STATUS    RESTARTS   AGE
nfs-client-provisioner-9b865c8cb-w7txl   1/1     Running   0          119s

[root@k8s-master pvc]# kubectl -n newnfs get deployments.apps 
NAME                     READY   UP-TO-DATE   AVAILABLE   AGE
nfs-client-provisioner   1/1     1            1           2m38s
3 创建storageclass,动态供给pv

server  nfs 版本是v4

[root@k8s-master pvc]# vim sc.yaml 
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  namespace: newnfs
  name: nfs-storage
  annotations:
    storageclass.kubernetes.io/is-default-class: "false"  ## 是否设置为默认的storageclass
provisioner: storage-nfs                                   ## 动态卷分配者名称,必须和上面创建的deploy中环境变量“PROVISIONER_NAME”变量值一致
parameters:
  archiveOnDelete: "true"                                 ## 设置为"false"时删除PVC不会保留数据,"true"则保留数据
mountOptions: 
  - hard                                                  ## 指定为硬挂载方式
  - nfsvers=4                                             ## 指定NFS版本,这个需要根据NFS Server版本号设置nfs


[root@k8s-master pvc]# kubectl apply -f sc.yaml 
storageclass.storage.k8s.io/nfs-storage created
查看storageclass是否创建成功
[root@k8s-master pvc]# kubectl -n newnfs get storageclasses.storage.k8s.io 
NAME          PROVISIONER   RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
nfs-storage   storage-nfs   Delete          Immediate           false                  23s

显示内容如上,说明storageclass创建成功了

注意:provisioner处写的example.com/nfs应该跟安装nfs provisioner时候的env下的PROVISIONER_NAME的value值保持一致,如下:

env:
 name: PROVISIONER_NAME
 value: storage-nfs
4、创建pvc,通过storageclass动态生成pv
[root@k8s-master pvc]# vim pvc1.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: storage-pvc
  namespace: newnfs
spec:
  storageClassName: nfs-storage    ## 需要与上面创建的storageclass的名称一致
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Mi

提交资源清单
[root@k8s-master pvc]# kubectl apply -f pvc1.yaml 
persistentvolumeclaim/storage-pvc created
查看是否动态生成了pv,pvc是否创建成功,并和pv绑定
[root@k8s-master pvc]# kubectl -n newnfs get persistentvolumeclaims 
NAME          STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
storage-pvc   Bound    pvc-db0dc568-7b80-4fc9-b9ad-d9f7c5642cb7   1Mi        RWO            nfs-storage    30s
[root@k8s-master pvc]# kubectl -n newnfs get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                STORAGECLASS   REASON   AGE
pvc-db0dc568-7b80-4fc9-b9ad-d9f7c5642cb7   1Mi        RWO            Delete           Bound    newnfs/storage-pvc   nfs-storage             77s
[root@k8s-master pvc]# kubectl -n newnfs get pvc
NAME          STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
storage-pvc   Bound    pvc-db0dc568-7b80-4fc9-b9ad-d9f7c5642cb7   1Mi        RWO            nfs-storage    84s
[root@k8s-master pvc]# 
 
步骤总结:

1、供应商:创建一个nfs provisioner

2、创建storageclass,storageclass指定刚才创建的供应商

3、创建pvc,这个pvc指定storageclass

5、创建pod,挂载storageclass动态生成的pvc:storage-pvc
[root@k8s-master pvc]# vim  read-pod.yaml
kind: Pod
apiVersion: v1
metadata:
 name: read-pod
 namespace: newnfs
spec:
 containers:
 - name: read-pod
   image: nginx
   imagePullPolicy: IfNotPresent
   volumeMounts:
   - name: nfs-pvc
     mountPath: /usr/share/nginx/html
 restartPolicy: "Never"
 volumes:
   - name: nfs-pvc
     persistentVolumeClaim:
       claimName: storage-pvc
更新资源清单文件
[root@k8s-master pvc]# kubectl apply -f read-pod.yaml 
pod/read-pod created
查看pod是否创建成功
[root@k8s-master ~]# kubectl -n newnfs get pod read-pod -o wide
NAME       READY   STATUS    RESTARTS   AGE     IP              NODE        NOMINATED NODE   READINESS GATES
read-pod   1/1     Running   0          4m26s   10.244.36.115   k8s-node1   <none>           <none>
查看一下路径
[root@k8s-master pvc]# kubectl -n newnfs get pvc
NAME          STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
storage-pvc   Bound    pvc-db0dc568-7b80-4fc9-b9ad-d9f7c5642cb7   1Mi        RWO            nfs-storage    27m
##在NFS服务端写入首页
[root@k8s-master pvc]# cd /data/newnfs-storage-pvc-pvc-db0dc568-7b80-4fc9-b9ad-d9f7c5642cb7/
[root@k8s-master newnfs-storage-pvc-pvc-db0dc568-7b80-4fc9-b9ad-d9f7c5642cb7]# echo nfs > index.html



##测试访问
[root@k8s-master newnfs-storage-pvc-pvc-db0dc568-7b80-4fc9-b9ad-d9f7c5642cb7]# cd
[root@k8s-master ~]# curl 10.244.36.115
nfs
查看index.html的物理位置

6、删除read-pod ,删除pvc 会自动删除pv ,所以默认的回收策略是delete是可以验证出来的
###删除 read-pod 后 pv 没有变化

[root@k8s-master data]# ls
index.html  newnfs-storage-pvc-pvc-db0dc568-7b80-4fc9-b9ad-d9f7c5642cb7  v1  v10  v2  v3  v4  v5  v6  v7  v8  v9
[root@k8s-master data]# kubectl -n newnfs get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                STORAGECLASS   REASON   AGE
pvc-db0dc568-7b80-4fc9-b9ad-d9f7c5642cb7   1Mi        RWO            Delete           Bound    newnfs/storage-pvc   nfs-storage             31m
[root@k8s-master data]# kubectl -n newnfs delete pod read-pod 
pod "read-pod" deleted
[root@k8s-master data]# kubectl -n newnfs get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                STORAGECLASS   REASON   AGE
pvc-db0dc568-7b80-4fc9-b9ad-d9f7c5642cb7   1Mi        RWO            Delete           Bound    newnfs/storage-pvc   nfs-storage             32m


###再删除 pvc , pv发生变化,没有了

[root@k8s-master data]# kubectl -n newnfs delete pvc storage-pvc 
persistentvolumeclaim "storage-pvc" deleted
[root@k8s-master data]# kubectl -n newnfs get pv
No resources found



##在NFS服务端发生如下变化,会将原来的nfspv进行更改名称归档
archived-pvc-db0dc568-7b80-4fc9-b9ad-d9f7c5642cb7 

[root@k8s-master data]# ls
archived-pvc-db0dc568-7b80-4fc9-b9ad-d9f7c5642cb7  index.html  v1  v10  v2  v3  v4  v5  v6  v7  v8  v9
重新更新pvc文件,会发现物理nfs中多了一个目录。

newnfs-storage-pvc-pvc-4218d83c-d5f6-4dab-bc4e-fd638d4d59fb 

[root@k8s-master data]# cd /root/pvc
[root@k8s-master pvc]# kubectl apply -f pvc1.yaml 
persistentvolumeclaim/storage-pvc created
[root@k8s-master pvc]# cd /data
[root@k8s-master data]# ls
archived-pvc-db0dc568-7b80-4fc9-b9ad-d9f7c5642cb7            v1   v3  v6  v9
index.html                                                   v10  v4  v7
newnfs-storage-pvc-pvc-4218d83c-d5f6-4dab-bc4e-fd638d4d59fb  v2   v5  v8
[root@k8s-master data]# 

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐