写点什么

K8s 进阶之一文搞懂 PV,PVC 及 SC

  • 2025-05-12
    福建
  • 本文字数:14875 字

    阅读完需:约 49 分钟

概述


官方文档:



什么是 PV?


PV(Persistent Volume)是持久化卷的意思,是对底层的共享存储的一种抽象。一般情况下 PV 由 kubernetes 管理员进行创建和配置,它与底层具体的共享存储技术有关,并通过插件完成与共享存储的对接。


什么是 PVC?


PVC(Persistent Volume Claim)是持久卷声明的意思,是用户对于存储需求的一种声明。换句话说,PVC 其实就是用户向 kubernetes 系统发出的一种资源需求申请。


什么是 SC?


SC(StorageClass)是存储类的意思,Kubernetes 可以根据 StorageClass 的定义动态地创建持久化存储卷(PersistentVolume, PV)和持久化卷声明(PersistentVolumeClaim, PVC)。StorageClass 提供了一种抽象层,允许用户在不关心底层存储实现细节的情况下请求存储资源。




PV 详解


PV 是集群中可被申请的存储资源,由管理员提前创建并定义存储参数(如容量、访问权限、回收策略等)。它与具体的 Pod 解耦,可被多个 Pod 声明(通过 PVC)和使用。


PV 分类


静态 PV


由管理员手动创建 PV 资源清单,预先定义存储容量、访问模式、存储路径等参数,不依赖 StorageClass。

适用于预先配置好的存储(如自建 NFS、GlusterFS 共享目录),或需要精细控制存储配置的场景。


动态 PV:


通过 StorageClass 自动创建,无需手动编写 PV 清单,Kubernetes 根据 PersistentVolumeClaim(PVC)的请求动态分配存储。

适用于云原生环境(如 AWS EBS、GCE PD)或需要按需分配存储的场景。


核心作用


解耦应用与存储基础设施:Pod 无需关心底层存储细节(如 NFS 服务器地址、云硬盘类型),通过 PVC 声明存储需求即可。提供持久化存储:数据不随 Pod 销毁而丢失,适用于有状态应用(如数据库、文件服务)。


PV 的生命周期


供应阶段(Provisioning):

静态供应(Static Provisioning):管理员手动创建 PV 资源,预先定义存储细节(如容量、访问模式、存储类型等),适用于已知存储需求的场景。

动态供应(Dynamic Provisioning):通过 StorageClass 自动创建 PV,当 PVC 申请存储时,Kubernetes 根据 SC 配置调用存储插件(如 NFS CSI 驱动)动态生成 PV。


绑定阶段(Binding)

Bound:找到匹配的 PV,两者绑定(如用户示例中的 pvc-sc-01 状态为 Bound)。

Pending:未找到匹配 PV(如用户示例中的 pvc-sc-02 因未指定 SC,但默认 SC 可能不满足条件而处于 Pending)。


使用阶段(Using)

Pod 通过 PVC 挂载 PV,数据持久化存储到后端存储(如 NFS 共享目录)。

支持动态扩缩容(需 SC 开启 allowVolumeExpansion: true),通过 kubectl patch pvc 调整容量。


释放阶段(Releasing)

当 PVC 被删除(kubectl delete pvc),PV 进入 Released 状态:

PV 不再被 PVC 绑定,但数据仍保留在后端存储中(取决于 SC 的 reclaimPolicy)。

此时 PV 可能存在 “孤儿” 状态(如 PV 配置与新 PVC 需求不匹配,无法重新绑定)。


回收阶段(Reclaiming)

PV 的回收行为由 reclaimPolicy 决定(定义在 PV 或 SC 中,SC 优先级高于 PV),支持三种策略:


Retain(保留,默认)

PV 释放后保留数据,需管理员手动清理后端存储或删除 PV。

适用于需要手动管理数据的场景(如用户示例中的 SC 配置 reclaimPolicy: Retain)。


Delete(删除)

PV 释放后自动删除后端存储资源(如 NFS 共享目录会被删除,需谨慎!)。

适用于临时存储或无状态应用。


Recycle(回收,已弃用)

清除 PV 数据(如执行 rm -rf /data/*),Kubernetes 1.17 + 已废弃,推荐使用 Delete 或 Retain。


PV 资源清单文件详解


apiVersion: v1          # API版本,PV属于core API组,版本固定为v1kind: PersistentVolume  # 资源类型为PersistentVolumemetadata:  name: pv-nfs          # PV名称,全局唯一  labels:               # 可选标签,用于筛选和关联PVC    storage: nfs  annotations:          # 可选注解,附加元数据    description: "NFS storage for web apps"spec:  capacity:             # PV的存储容量,必填    storage: 10Gi       # 容量大小,支持Gi、Ti等单位  accessModes:          # 访问模式,定义PV如何被挂载,必填(至少一个)    - ReadWriteOnce     # RWO:单节点读写(最常用,支持Node或Pod级别)    - ReadOnlyMany      # ROX:多节点只读    - ReadWriteMany     # RWX:多节点读写(需存储支持,如NFS、GlusterFS)  persistentVolumeReclaimPolicy: # 回收策略,定义PV释放后的处理方式,默认Retain    Retain              # 保留数据,需手动清理(默认)    # Recycle         # 已弃用,等价于Delete(仅支持NFS等少数存储)    # Delete            # 删除存储(如云硬盘EBS会被删除,NFS仅删除PVC绑定)  storageClassName: ""  # 关联的StorageClass名称,空字符串表示默认类,或不指定  mountOptions:         # 挂载时的额外选项(如文件系统参数),可选    - hard    - nfsvers=4.1  nfs:                  # 存储类型配置(不同存储类型字段不同,此处以NFS为例)    server: 10.0.0.30   # NFS服务器IP    path: /data/nfs     # NFS共享路径  # 其他存储类型(如hostPath、AWS EBS、Ceph等)的配置字段不同,见下方说明
复制代码


关键字段说明

spec.accessModes(访问模式):必须至少指定一个模式,需与存储类型兼容:
  • ReadWriteOnce (RWO):单节点读写(支持同一节点上的多个 Pod 共享)。

  • ReadOnlyMany (ROX):多节点只读(如 NFS 允许多个节点挂载为只读)。

  • ReadWriteMany (RWX):多节点读写(需存储支持,如 NFS、GlusterFS、CephFS)。

注意:云硬盘(如 EBS、PD)通常仅支持 RWO,而 NFS、CephFS 等分布式存储支持 RWX。

spec.persistentVolumeReclaimPolicy(回收策略)
  • Retain(保留)(默认):当 PVC 删除时,PV 数据保留,状态变为 Released,需手动清理数据或删除 PV。

  • Delete(删除):当 PVC 删除时,自动删除底层存储(如云硬盘、S3 Bucket),适用于动态创建的存储。

  • Recycle(回收)(已弃用):清空存储数据,仅适用于 NFS 等少数存储,Kubernetes 1.14 + 已移除。


创建静态 pv 实战案例


示例:

# 定义pv[root@master01 ~/volumes]# cat pv-test01.yamlapiVersion: v1kind: PersistentVolumemetadata:  name: pv-01  labels:    name: pv-01spec:  capacity:    storage: 10Gi  # 指定存储类型为nfs  nfs:    server: 10.0.0.30    path: /data/nfs/nginx/pv-01  # 访问模式  accessModes:  # 多节点读写  - ReadWriteMany  persistentVolumeReclaimPolicy: Retain # 创建pv[root@master01 ~/volumes]# kubectl apply -f pv-test01.yamlpersistentvolume/pv-01 created # 查看pv[root@master01 ~/volumes]# kubectl get pvNAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGEpv-01   10Gi       RWX            Retain           Available                                   7s # 查看详细信息[root@master01 ~/volumes]# kubectl describe pv pv-01Name:            pv-01Labels:          <none>Annotations:     <none>Finalizers:      [kubernetes.io/pv-protection]StorageClass:Status:          AvailableClaim:Reclaim Policy:  RetainAccess Modes:    RWXVolumeMode:      FilesystemCapacity:        20GiNode Affinity:   <none>Message:Source:    Type:      NFS (an NFS mount that lasts the lifetime of a pod)    Server:    10.0.0.30    Path:      /data/nfs/nginx/pv-01    ReadOnly:  falseEvents:        <none>
复制代码


使用 kubectl 管理 pv


查看 pv

kubectl get pv <pv-name> kubectl describe pv <pv-name>
复制代码


删除 pv

kubectl delete pv <pv-name>
复制代码


修改 pv

方式一:修改资源清单文件再apply即可方式二:通过kubectl edit修改保存即可
复制代码


PVC 详解


PVC(Persistent Volume Claim)是持久卷声明的意思,是用户对于存储需求的一种声明。换句话说,PVC 其实就是用户向 kubernetes 系统发出的一种资源需求申请。


核心概念


PVC 是名称空间级别的资源,用于声明:

  • 需要的存储容量(如 5Gi)。

  • 支持的访问模式(如 ReadWriteOnce)。

  • 期望的存储类型(通过 storageClassName 关联 StorageClass)。


PVC 与 PV 的关系类似于 Pod 与 Node 的关系:PVC 请求资源,PV 提供资源,两者通过绑定机制匹配。


PVC 资源清单文件详解


apiVersion: v1kind: PersistentVolumeClaimmetadata:  name: my-pvc  # PVC名称,命名空间内唯一  namespace: default  # 命名空间,默认default  labels:    app: my-appspec:  accessModes:  # 访问模式,必须与PV兼容    - ReadWriteOnce  # 单节点读写  resources:    requests:      storage: 5Gi  # 请求的存储容量  storageClassName: "standard"  # 关联的StorageClass名称,""表示使用默认类  selector:  # 可选,通过标签筛选PV    matchLabels:      storage-type: "ssd"
复制代码


关键字段说明

spec.accessModes(访问模式):必须至少指定一个模式,需与存储类型兼容:
  • ReadWriteOnce (RWO):单节点读写(支持同一节点上的多个 Pod 共享)。

  • ReadOnlyMany (ROX):多节点只读(如 NFS 允许多个节点挂载为只读)。

  • ReadWriteMany (RWX):多节点读写(需存储支持,如 NFS、GlusterFS、CephFS)。

注意:云硬盘(如 EBS、PD)通常仅支持 RWO,而 NFS、CephFS 等分布式存储支持 RWX。


创建 PVC 关联 PV 实战


创建 PV


以上面案例为基础,可以修改一下,参考下面的资源文件

[root@master01 ~/volumes]# cat pv-test01.yamlapiVersion: v1kind: PersistentVolumemetadata:  name: pv-01  labels:    name: pv-01spec:  capacity:    storage: 10Gi  # 指定存储类型为nfs  nfs:    server: 10.0.0.30    path: /data/nfs/nginx/pv-01  # 访问模式  accessModes:  # 多节点读写  - ReadWriteMany  persistentVolumeReclaimPolicy: Retain
复制代码


创建 PVC

# 定义资源文件[root@master01 ~/volumes]# cat pvc-test01.yamlapiVersion: v1kind: PersistentVolumeClaimmetadata:  name: pvc-01  labels:    name: pvc-01  namespace: defaultspec:  # 定义访问模式,和pv一样即可  accessModes:  - ReadWriteMany  # 标签选择器,选择哪一个PV  selector:    matchExpressions:    - key: name      operator: In      values:      - pv-01  # 申请PV的容量,这里申请5G  resources:    requests:      storage: 5G# 创建PVC[root@master01 ~/volumes]# kubectl apply -f pvc-test01.yamlpersistentvolumeclaim/pvc-01 created
复制代码


查看 pv 和 pvc

[root@master01 ~/volumes]# kubectl get pv,pvcNAME                     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM            STORAGECLASS   REASON   AGEpersistentvolume/pv-01   10Gi       RWX            Retain           Bound    default/pvc-01                           27m NAME                           STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGEpersistentvolumeclaim/pvc-01   Bound    pv-01    10Gi       RWX                           7s # 查看详情[root@master01 ~/volumes]# kubectl describe pvc pvc-01Name:          pvc-01Namespace:     defaultStorageClass:Status:        BoundVolume:        pv-01Labels:        name=pvc-01Annotations:   pv.kubernetes.io/bind-completed: yes               pv.kubernetes.io/bound-by-controller: yesFinalizers:    [kubernetes.io/pvc-protection]Capacity:      10GiAccess Modes:  RWXVolumeMode:    FilesystemUsed By:       <none>Events:        <none>
复制代码


创建 Pod 关联 PVC 使用 PV 存储


这里创建 MySQL

# 定义资源文件[root@master01 ~/volumes]# cat pod-mysql.yamlapiVersion: v1kind: Podmetadata:  name: pod-pvcspec:  volumes:  - name: data    # 指定存储类型为PVC    persistentVolumeClaim:      # 指定PVC的名称      claimName: pvc-01      # 是否只读,默认值为false,代表可读写      readOnly: false  containers:  - name: mysql    image: mysql:8.0.26    env:    - name: "MYSQL_ROOT_PASSWORD"      value: "root123"    # 挂载存储卷    volumeMounts:    # 指定存储卷的名称    - name: data      mountPath: /var/lib/mysql # 创建pod[root@master01 ~/volumes]# kubectl apply -f pod-mysql.yamlpod/pod-pvc created
复制代码


查看 PV 存储路径的数据

[root@master01 ~/volumes]# ll /data/nfs/nginx/pv-01/total 198068-rw-r----- 1  999  999   196608 May 11 14:45 '#ib_16384_0.dblwr'-rw-r----- 1  999  999  8585216 May 11 14:45 '#ib_16384_1.dblwr'drwxr-x--- 2  999  999     4096 May 11 14:45 '#innodb_temp'/drwxr-xr-x 6  999 root     4096 May 11 14:45  ./drwxr-xr-x 4 root root     4096 May 11 14:44  ../-rw-r----- 1  999  999       56 May 11 14:45  auto.cnf-rw-r----- 1  999  999  3117023 May 11 14:45  binlog.000001-rw-r----- 1  999  999      156 May 11 14:45  binlog.000002-rw-r----- 1  999  999       32 May 11 14:45  binlog.index-rw------- 1  999  999     1680 May 11 14:45  ca-key.pem-rw-r--r-- 1  999  999     1112 May 11 14:45  ca.pem-rw-r--r-- 1  999  999     1112 May 11 14:45  client-cert.pem-rw------- 1  999  999     1680 May 11 14:45  client-key.pem-rw-r----- 1  999  999     5718 May 11 14:45  ib_buffer_pool-rw-r----- 1  999  999 50331648 May 11 14:45  ib_logfile0-rw-r----- 1  999  999 50331648 May 11 14:45  ib_logfile1-rw-r----- 1  999  999 12582912 May 11 14:45  ibdata1-rw-r----- 1  999  999 12582912 May 11 14:46  ibtmp1drwxr-x--- 2  999  999     4096 May 11 14:45  mysql/-rw-r----- 1  999  999 31457280 May 11 14:45  mysql.ibddrwxr-x--- 2  999  999     4096 May 11 14:45  performance_schema/-rw------- 1  999  999     1676 May 11 14:45  private_key.pem-rw-r--r-- 1  999  999      452 May 11 14:45  public_key.pem-rw-r--r-- 1  999  999     1112 May 11 14:45  server-cert.pem-rw------- 1  999  999     1680 May 11 14:45  server-key.pemdrwxr-x--- 2  999  999     4096 May 11 14:45  sys/-rw-r----- 1  999  999 16777216 May 11 14:45  undo_001-rw-r----- 1  999  999 16777216 May 11 14:45  undo_002
复制代码


验证删除 Pod 示例之后数据是否保留


创建模拟数据

# 进入容器[root@master01 ~/volumes]# kubectl exec -it pod-pvc -- /bin/bash# 连接MySQLroot@pod-pvc:/# mysql -uroot -proot123# 创建测试库mysql> create database testdb;Query OK, 1 row affected (0.01 sec)# 查看数据库mysql> show databases;+--------------------+| Database           |+--------------------+| information_schema || mysql              || performance_schema || sys                || testdb             |+--------------------+5 rows in set (0.01 sec)
复制代码


删除 Pod 后重新创建

# 删除pod[root@master01 ~/volumes]# kubectl delete po pod-pvcpod "pod-pvc" deleted# 查看pv和pvc[root@master01 ~/volumes]# kubectl get pv,pvcNAME                     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM            STORAGECLASS   REASON   AGEpersistentvolume/pv-01   10Gi       RWX            Retain           Bound    default/pvc-01                           47m NAME                           STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGEpersistentvolumeclaim/pvc-01   Bound    pv-01    10Gi       RWX                           20m# 重新创建[root@master01 ~/volumes]# kubectl apply -f pod-mysql.yamlpod/pod-pvc created
复制代码


进入新创建的 pod 内查看库是否存在

# 进入容器[root@master01 ~/volumes]# kubectl exec -it pod-pvc -- /bin/bash# 连接数据库root@pod-pvc:/# mysql -uroot -proot123mysql: [Warning] Using a password on the command line interface can be insecure.Welcome to the MySQL monitor.  Commands end with ; or \g.Your MySQL connection id is 8Server version: 8.0.26 MySQL Community Server - GPL Copyright (c) 2000, 2021, Oracle and/or its affiliates. Oracle is a registered trademark of Oracle Corporation and/or itsaffiliates. Other names may be trademarks of their respectiveowners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. # 查看数据mysql> show databases;+--------------------+| Database           |+--------------------+| information_schema || mysql              || performance_schema || sys                || testdb             |+--------------------+5 rows in set (0.00 sec)
复制代码


测试删除 Pod 和 PVC 之后,PV 的数据是否还存在


经过验证,数据依旧存在

# 删除pod和pvc[root@master01 ~/volumes]# kubectl delete po pod-pvcpod "pod-pvc" deleted[root@master01 ~/volumes]# kubectl delete pvc pvc-01persistentvolumeclaim "pvc-01" deleted # 查看pv,状态为Released[root@master01 ~/volumes]# kubectl get pvNAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS     CLAIM            STORAGECLASS   REASON   AGEpv-01   10Gi       RWX            Retain           Released   default/pvc-01                           50m # 查看数据是否存在[root@master01 ~/volumes]# ll /data/nfs/nginx/pv-01/total 185784-rw-r----- 1  999  999   196608 May 11 14:54 '#ib_16384_0.dblwr'-rw-r----- 1  999  999  8585216 May 11 14:45 '#ib_16384_1.dblwr'drwxr-x--- 2  999  999     4096 May 11 14:55 '#innodb_temp'/drwxr-xr-x 7  999 root     4096 May 11 14:55  ./drwxr-xr-x 4 root root     4096 May 11 14:44  ../-rw-r----- 1  999  999       56 May 11 14:45  auto.cnf-rw-r----- 1  999  999  3117023 May 11 14:45  binlog.000001-rw-r----- 1  999  999      370 May 11 14:52  binlog.000002-rw-r----- 1  999  999      179 May 11 14:55  binlog.000003-rw-r----- 1  999  999       48 May 11 14:52  binlog.index-rw------- 1  999  999     1680 May 11 14:45  ca-key.pem-rw-r--r-- 1  999  999     1112 May 11 14:45  ca.pem-rw-r--r-- 1  999  999     1112 May 11 14:45  client-cert.pem-rw------- 1  999  999     1680 May 11 14:45  client-key.pem-rw-r----- 1  999  999     3482 May 11 14:55  ib_buffer_pool-rw-r----- 1  999  999 50331648 May 11 14:54  ib_logfile0-rw-r----- 1  999  999 50331648 May 11 14:45  ib_logfile1-rw-r----- 1  999  999 12582912 May 11 14:55  ibdata1drwxr-x--- 2  999  999     4096 May 11 14:45  mysql/-rw-r----- 1  999  999 31457280 May 11 14:52  mysql.ibddrwxr-x--- 2  999  999     4096 May 11 14:45  performance_schema/-rw------- 1  999  999     1676 May 11 14:45  private_key.pem-rw-r--r-- 1  999  999      452 May 11 14:45  public_key.pem-rw-r--r-- 1  999  999     1112 May 11 14:45  server-cert.pem-rw------- 1  999  999     1680 May 11 14:45  server-key.pemdrwxr-x--- 2  999  999     4096 May 11 14:45  sys/drwxr-x--- 2  999  999     4096 May 11 14:49  testdb/-rw-r----- 1  999  999 16777216 May 11 14:54  undo_001-rw-r----- 1  999  999 16777216 May 11 14:54  undo_002
复制代码


PVC 和 PV 的绑定机制


PVC 与 PV 的绑定遵循以下规则:

  • 访问模式匹配:PVC 的 accessModes 必须是 PV 支持的子集(如 PV 支持 RWX,PVC 可请求 RWO 或 RWX)。

  • 容量匹配:PV 的容量必须≥PVC 请求的容量。

  • 存储类匹配:若 PVC 指定 storageClassName,则仅匹配相同 StorageClass 的 PV。若 PVC 未指定 storageClassName,则仅匹配未关联任何 StorageClass 的 PV。

  • 标签选择器匹配:若 PVC 使用 selector,则 PV 必须包含所有指定标签。

绑定状态:

  • Bound:已成功绑定 PV。

  • Pending:未找到匹配的 PV(需等待或手动创建)。

  • Lost:绑定的 PV 已消失(如被管理员删除)。


SC 详解


SC(StorageClass)是存储类的意思,Kubernetes 可以根据 StorageClass 的定义动态地创建持久化存储卷(PersistentVolume, PV)和持久化卷声明(PersistentVolumeClaim, PVC)。StorageClass 提供了一种抽象层,允许用户在不关心底层存储实现细节的情况下请求存储资源。


SC 的核心作用


  • 动态存储供给传统静态供给需要管理员手动创建 PV(PersistentVolume),而 StorageClass 支持动态供给:当用户创建 PVC(PersistentVolumeClaim)时,Kubernetes 会根据 PVC 指定的 StorageClass 自动创建对应的 PV,无需手动预定义。

  • 存储类型分类可定义多种 StorageClass(如 fast、slow、ssd、hdd),每种类型对应不同的存储参数(如存储介质、性能、备份策略等),满足不同业务需求。

  • 灵活配置 Provisioner 通过关联存储插件(Provisioner),支持对接多种后端存储(如 AWS EBS、NFS、Ceph、GlusterFS 等),实现对不同存储系统的统一管理。


资源清单文件详解


apiVersion: storage.k8s.io/v1kind: StorageClassmetadata:  name: standard  # StorageClass 名称,PVC 通过此名称引用provisioner: kubernetes.io/aws-ebs  # 存储插件(Provisioner)parameters:    # 存储插件专属参数  type: gp2     # 例如 AWS EBS 的卷类型(gp2、io1 等)reclaimPolicy: Delete  # 回收策略(Delete 或 Retain,默认 Delete)volumeBindingMode: Immediate  # 卷绑定模式(Immediate 或 WaitForFirstConsumer,默认 Immediate)allowVolumeExpansion: true #允许卷扩容mountOptions:    # 挂载选项(可选)  - debug
复制代码


核心字段说明


provisioner(必选)

指定负责创建 PV 的存储插件,通常格式为 厂商名称.插件类型,例如:

  • kubernetes.io/aws-ebs(AWS EBS 卷)

  • nfs-client.provisioner(NFS 客户端插件)

  • local.csi.k8s.io(本地存储 CSI 插件)


parameters(可选)

传递给 Provisioner 的参数,不同插件参数不同,例如:

  • NFS 插件:server=10.0.0.10, share=/nfs/share

  • AWS EBS 插件:type=io1, iopsPerGB=10


reclaimPolicy(可选,默认 Delete)

当 PVC 被删除时,PV 的处理策略:

  • Delete:自动删除 PV 及后端存储资源(如 EBS 卷)。

  • Retain:保留 PV 及数据,需手动清理(适用于需要数据持久化的场景)。


volumeBindingMode(可选,默认 Immediate)

控制 PV 与节点的绑定时机:

  • Immediate:立即绑定,适用于不需要节点亲和性的场景。

  • WaitForFirstConsumer:延迟绑定,直到 Pod 调度时才绑定 PV,支持结合节点亲和性选择存储位置(如本地存储需绑定到特定节点)。


配置以 NFS 为存储的 SC 插件


K8s 原生组件并不支持 NFS 动态存储,所以需要一些额外的配置 K8s 官网:https://kubernetes.io/zh-cn/docs/concepts/storage/storage-classes/#nfs项目官网:https://github.com/kubernetes-csi/csi-driver-nfs#readme

我这里使用 kubectl 进行安装,实操:

[root@master01 ~]# wget https://github.com/kubernetes-csi/csi-driver-nfs/archive/refs/tags/v4.11.0.tar.gz[root@master01 ~]# tar -xvf csi-driver-nfs-4.11.0.tar.gz[root@master01 ~]# cd csi-driver-nfs-4.11.0 # 修改镜像源,防止镜像拉不下来[root@master01 ~/csi-driver-nfs-4.11.0/deploy]# sed -i s#registry.k8s.io#k8s.m.daocloud.io#g deploy/csi-nfs-controller.yaml[root@master01 ~/csi-driver-nfs-4.11.0/deploy]# sed -i s#registry.k8s.io#k8s.m.daocloud.io#g deploy/csi-snapshot-controller.yaml[root@master01 ~/csi-driver-nfs-4.11.0/deploy]# sed -i s#registry.k8s.io#k8s.m.daocloud.io#g deploy/csi-nfs-node.yaml # 执行安装,注意脚本后面添加参数[root@master01 ~/csi-driver-nfs-4.11.0/deploy]# ./install-driver.sh master localInstalling NFS CSI driver, version: master ...serviceaccount/csi-nfs-controller-sa createdserviceaccount/csi-nfs-node-sa createdclusterrole.rbac.authorization.k8s.io/nfs-external-provisioner-role createdclusterrolebinding.rbac.authorization.k8s.io/nfs-csi-provisioner-binding createdclusterrole.rbac.authorization.k8s.io/nfs-external-resizer-role createdclusterrolebinding.rbac.authorization.k8s.io/nfs-csi-resizer-role createdcsidriver.storage.k8s.io/nfs.csi.k8s.io createddeployment.apps/csi-nfs-controller createddaemonset.apps/csi-nfs-node createdNFS CSI driver installed successfully. # 检查一下pod是否启动Running[root@master01 ~/csi-driver-nfs-4.11.0]# kubectl -n kube-system get pod -o wide -l app=csi-nfs-nodeNAME                 READY   STATUS    RESTARTS   AGE   IP          NODE       NOMINATED NODE   READINESS GATEScsi-nfs-node-4w6fg   3/3     Running   0          89s   10.0.0.32   node02     <none>           <none>csi-nfs-node-jhsf2   3/3     Running   0          89s   10.0.0.31   node01     <none>           <none>csi-nfs-node-sbp76   3/3     Running   0          89s   10.0.0.30   master01   <none>           <none> [root@master01 ~/csi-driver-nfs-4.11.0]# kubectl -n kube-system get pod -o wide -l app=csi-nfs-controllerNAME                                  READY   STATUS    RESTARTS      AGE    IP          NODE       NOMINATED NODE   READINESS GATEScsi-nfs-controller-6d4bb5ddbc-fgmq6   5/5     Running   1 (41s ago)   105s   10.0.0.30   master01   <none>           <none>
复制代码


创建 SC 实战


[root@master01 ~/volumes]# cat sc-01.yamlapiVersion: storage.k8s.io/v1kind: StorageClassmetadata:  name: sc-01  # StorageClass名称,PVC通过该名称引用此存储类provisioner: nfs.csi.k8s.io  # 指定使用NFS CSI驱动作为存储供给器parameters:  # 传递给NFS CSI驱动的参数  server: 10.0.0.30  # NFS服务器的IP地址  share: /data/nfs/nginx/sc-01  # NFS服务器上的共享目录路径  # csi.storage.k8s.io/provisioner-secret is only needed for providing mountOptions in DeleteVolume  # csi.storage.k8s.io/provisioner-secret-name: "mount-options"  # csi.storage.k8s.io/provisioner-secret-namespace: "default"reclaimPolicy: Retain  # 回收策略:当PVC被删除时,PV保留不删除volumeBindingMode: Immediate  # 卷绑定模式:立即绑定,不需要等待Pod调度allowVolumeExpansion: true  # 允许卷扩容:支持通过修改PVC请求更大容量 # 创建sc[root@master01 ~/volumes]# kubectl apply -f sc-01.yamlstorageclass.storage.k8s.io/sc-01 created # 查看sc[root@master01 ~/volumes]# kubectl get scNAME    PROVISIONER      RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGEsc-01   nfs.csi.k8s.io   Retain          Immediate           true                   5s
复制代码


创建 PVC 关联 SC


# 定义资源文件[root@master01 ~/volumes]# cat pvc-sc-01.yamlapiVersion: v1kind: PersistentVolumeClaimmetadata:  name: pvc-sc-01spec:  accessModes:    - ReadWriteMany  # 指定sc的名称进行关联  storageClassName: sc-01  resources:    requests:      storage: 5Gi # 创建sc[root@master01 ~/volumes]# kubectl apply -f pvc-sc-01.yamlpersistentvolumeclaim/pvc-sc-01 unchanged # 查看pvc和sc[root@master01 ~/volumes]# kubectl get pvc,scNAME                              STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGEpersistentvolumeclaim/pvc-sc-01   Bound    pvc-4ed0c30c-6827-4498-bd53-bff5accbd47d   5Gi        RWX            sc-01          28s NAME                                PROVISIONER      RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGEstorageclass.storage.k8s.io/sc-01   nfs.csi.k8s.io   Retain          Immediate           true                   6m4s
复制代码


创建 Pod 关联 PVC 使用 SC


示例:

#定义资源文件[root@master01 ~/volumes]# cat pod-sc.yamlapiVersion: v1kind: Podmetadata:  name: pod-scspec:  volumes:  - name: data    # 指定存储类型为PVC    persistentVolumeClaim:      # 指定PVC的名称      claimName: pvc-sc-01      # 是否只读,默认值为false,代表可读写      readOnly: false  containers:  - name: mysql    image: mysql:8.0.26    env:    - name: "MYSQL_ROOT_PASSWORD"      value: "root123"    # 挂载存储卷    volumeMounts:    # 指定存储卷的名称    - name: data      mountPath: /var/lib/mysql # 创建pod[root@master01 ~/volumes]# kubectl apply -f pod-sc.yamlpod/pod-sc created
复制代码


查看挂载的路径

[root@master01 ~]# cd /data/nfs/nginx/sc-01/ # pvc-4ed0c30c-6827-4498-bd53-bff5accbd47d/的名称和PVC的VOLUME字段对应[root@master01 /data/nfs/nginx/sc-01]# lltotal 12drwxr-xr-x 3 root root 4096 May 11 16:03 ./drwxr-xr-x 5 root root 4096 May 11 15:57 ../drwxr-xr-x 6  999 root 4096 May 11 16:07 pvc-4ed0c30c-6827-4498-bd53-bff5accbd47d/ [root@master01 /data/nfs/nginx/sc-01]# ll pvc-4ed0c30c-6827-4498-bd53-bff5accbd47d/total 198068-rw-r----- 1  999  999   196608 May 11 16:07 '#ib_16384_0.dblwr'-rw-r----- 1  999  999  8585216 May 11 16:07 '#ib_16384_1.dblwr'drwxr-x--- 2  999  999     4096 May 11 16:07 '#innodb_temp'/drwxr-xr-x 6  999 root     4096 May 11 16:07  ./drwxr-xr-x 3 root root     4096 May 11 16:03  ../-rw-r----- 1  999  999       56 May 11 16:07  auto.cnf-rw-r----- 1  999  999  3117023 May 11 16:07  binlog.000001-rw-r----- 1  999  999      156 May 11 16:07  binlog.000002-rw-r----- 1  999  999       32 May 11 16:07  binlog.index-rw------- 1  999  999     1680 May 11 16:07  ca-key.pem-rw-r--r-- 1  999  999     1112 May 11 16:07  ca.pem-rw-r--r-- 1  999  999     1112 May 11 16:07  client-cert.pem-rw------- 1  999  999     1680 May 11 16:07  client-key.pem-rw-r----- 1  999  999     5721 May 11 16:07  ib_buffer_pool-rw-r----- 1  999  999 50331648 May 11 16:07  ib_logfile0-rw-r----- 1  999  999 50331648 May 11 16:07  ib_logfile1-rw-r----- 1  999  999 12582912 May 11 16:07  ibdata1-rw-r----- 1  999  999 12582912 May 11 16:08  ibtmp1drwxr-x--- 2  999  999     4096 May 11 16:07  mysql/-rw-r----- 1  999  999 31457280 May 11 16:07  mysql.ibddrwxr-x--- 2  999  999     4096 May 11 16:07  performance_schema/-rw------- 1  999  999     1680 May 11 16:07  private_key.pem-rw-r--r-- 1  999  999      452 May 11 16:07  public_key.pem-rw-r--r-- 1  999  999     1112 May 11 16:07  server-cert.pem-rw------- 1  999  999     1680 May 11 16:07  server-key.pemdrwxr-x--- 2  999  999     4096 May 11 16:07  sys/-rw-r----- 1  999  999 16777216 May 11 16:07  undo_001-rw-r----- 1  999  999 16777216 May 11 16:07  undo_002
复制代码


配置默认的 SC


默认的 SC(StorageClass) 是指当创建 PVC(PersistentVolumeClaim) 时未显式指定 storageClassName 时,系统自动使用的 StorageClass。以下是关于默认 SC 的配置和相关说明:


在 Kubernetes 集群中,默认 StorageClass(SC)的数量是 0 个或 1 个。Kubernetes 不强制要求必须有默认 SC,但如果存在,只能有一个被标记为默认


创建默认的 SC


默认 SC 通过 metadata.annotations 中的 storageclass.kubernetes.io/is-default-class: "true" 标记

示例

# 定义资源清单文件[root@master01 ~/volumes]# cat sc-default.yamlapiVersion: storage.k8s.io/v1kind: StorageClassmetadata:  # StorageClass名称,PVC通过该名称引用此存储类  name: sc-default  annotations:    # 标记为默认存储类    storageclass.kubernetes.io/is-default-class: "true"# 指定使用NFS CSI驱动作为存储供给器provisioner: nfs.csi.k8s.io# 传递给NFS CSI驱动的参数parameters:  # NFS服务器的IP地址  server: 10.0.0.30  # NFS服务器上的共享目录路径  share: /data/nfs/nginx/sc-default  # csi.storage.k8s.io/provisioner-secret is only needed for providing mountOptions in DeleteVolume  # csi.storage.k8s.io/provisioner-secret-name: "mount-options"  # csi.storage.k8s.io/provisioner-secret-namespace: "default"# 回收策略:当PVC被删除时,PV保留不删除reclaimPolicy: Retain# 卷绑定模式:立即绑定,不需要等待Pod调度volumeBindingMode: Immediate# 允许卷扩容:支持通过修改PVC请求更大容量allowVolumeExpansion: true # 创建sc[root@master01 ~/volumes]# kubectl apply -f sc-default.yamlstorageclass.storage.k8s.io/sc-default created # 查看sc[root@master01 ~/volumes]# kubectl get scNAME                   PROVISIONER      RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGEsc-01                  nfs.csi.k8s.io   Retain          Immediate           true                   20m# 默认存储类sc-default (default)   nfs.csi.k8s.io   Retain          Immediate           true                   3s
复制代码


创建 PVC 关联默认的 SC


# 定义资源清单文件[root@master01 ~/volumes]# cat pvc-sc-02.yamlapiVersion: v1kind: PersistentVolumeClaimmetadata:  name: pvc-sc-02spec:  accessModes:    - ReadWriteMany  # 这里不指定sc的名称,使用默认的SC  # storageClassName: sc-default  resources:    requests:      storage: 5Gi # 创建pvc[root@master01 ~/volumes]# kubectl apply -f pvc-sc-02.yamlpersistentvolumeclaim/pvc-sc-02 created # 查看pvc和sc,发现都绑定成功了[root@master01 ~/volumes]# kubectl get pvc,scNAME                              STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGEpersistentvolumeclaim/pvc-sc-01   Bound    pvc-4ed0c30c-6827-4498-bd53-bff5accbd47d   5Gi        RWX            sc-01          19mpersistentvolumeclaim/pvc-sc-02   Bound    pvc-ae0b0c76-7c00-4986-b589-aa62ff9472fa   5Gi        RWX            sc-default     2m20s NAME                                               PROVISIONER      RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGEstorageclass.storage.k8s.io/sc-01                  nfs.csi.k8s.io   Retain          Immediate           true                   25mstorageclass.storage.k8s.io/sc-default (default)   nfs.csi.k8s.io   Retain          Immediate           true                   3m36s
复制代码


文章转载自:huangSir-devops

原文链接:https://www.cnblogs.com/huangSir-devops/p/18871414

体验地址:http://www.jnpfsoft.com/?from=001YH

用户头像

还未添加个人签名 2025-04-01 加入

还未添加个人简介

评论

发布
暂无评论
K8s进阶之一文搞懂PV,PVC及SC_Kubernetes_电子尖叫食人鱼_InfoQ写作社区