k8s学习笔记9—— 持久卷PV

在 Kubernetes 中,持久卷(Persistent Volume,简称 PV)是为集群提供持久化存储的核心资源。

为了帮助您快速构建一个整体印象,下面的表格概括了持久卷体系中的几个核心概念及其关系:

核心概念

角色与职责

一个简单的比喻

​Persistent Volume (PV)​​

集群中的一块实际存储资源,由管理员预先创建或由存储类动态制备。它就像是仓库里的一个实实在在的货架​

仓库里的物理货架​

​Persistent Volume Claim (PVC)​​

用户(应用)对存储资源的申请。它指定需要多大的存储空间、具备何种访问能力。PVC 会消费 PV 资源,类似于 Pod 消费 Node 资源

​货架使用申请单,写明需要多大、什么样的货架

​StorageClass (SC)​​

定义了存储的​“类型”或“服务等级”​​(如高速SSD、标准HDD),并包含动态创建 PV 的详细步骤。它实现了存储资源的按需动态供应​

​自动化货架制造机的蓝图和操作手册

 

 

 

 

 

 

 

🔗 PV 与 PVC 的生命周期

PV 和 PVC 的交互遵循一个清晰的生命周期,主要包括以下四个阶段:

  1. ​资源供应​:PV 可以通过两种方式准备:

    • ​静态制备​:集群管理员手动创建一批 PV

    • ​动态制备​:当用户提交的 PVC 在现有 PV 中找不到匹配项时,系统会根据 PVC 指定的 StorageClass自动创建合适的 PV

  2. ​绑定​:用户创建 PVC 后,Kubernetes 的控制平面会寻找一个满足其容量和访问模式要求的可用 PV。找到后,便将两者绑定。绑定是独占的,一个 PV 只能绑定一个 PVC

  3. ​使用​:Pod 通过在其配置文件中引用 PVC 来使用持久存储。PVC 需要与 Pod 位于同一命名空间

  4. ​回收​:当 PVC 被删除后,其绑定的 PV 会根据管理员设定的回收策略进行处理:

    • ​Retain​:保留资源及数据。PV 状态变为 Released,需管理员手动清理后才能再次使用

    • ​Delete​:自动删除 PV 以及后端存储设施中的数据

 

⚙️ PV 的关键配置属性

定义一个 PV 时,有几个关键的配置项决定了它的特性和行为:

 

属性

描述与可选值

​容量​

指定存储空间大小,如 10Gi

​访问模式​

定义卷的访问方式:
• ​ReadWriteOnce​:可被单个节点以读写方式挂载

• ​ReadOnlyMany​:可被多个节点以只读方式挂载
• ​ReadWriteMany​:可被多个节点以读写方式挂载
• ​ReadWriteOncePod​:仅可被单个 Pod 以读写方式挂载

​卷模式​

指定卷被格式化为文件系统​ 还是作为原始块设备​ 使用

​存储类​

通过 storageClassName字段指定 PV 所属的类别,用于与请求特定类的 PVC 进行匹配

 
未设置此字段的 PV 没有类,只能绑定到未指定存储类的 PVC

​回收策略​

即 PVC 释放后 PV 的处理方式,如 Retain, Delete

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

🗂️ 支持的存储类型

Kubernetes 支持丰富的存储类型(通过卷插件实现),常见的有:

  • ​网络存储​:NFS、iSCSI、CephFS、GlusterFS 等。

  • ​公有云存储​:AWS EBS、Google Persistent Disk、Azure Disk 等。

  • ​本地存储​:hostPath(仅限单节点测试)、local(适用于多节点集群的本地存储)等

 
 
 1. hostPath
  • 本质是使用本地设备,如磁盘,分区,目录等,hostPath的可用性取决于底层节点的可用性,如果节点变的不健康,那hostPath也将不可访问

  • hostPath卷里面的数据不会随着Pod的结束而消失

[root@master ~]# vim web1.yaml
---
kind: Pod
apiVersion: v1
metadata:
  name: web1
spec:
  volumes:                    # 卷定义
  - name: logdata             # 卷名称
    hostPath:                 # 资源类型
    path: /var/weblog         # 宿主机路径
    type: DirectoryOrCreate   # 目录不存在就创建
  containers:
  - name: nginx
    image: myos:nginx
    volumeMounts:             # mount- name: logdata         # 卷名称
        mountPath: /usr/local/nginx/logs # 容器内路径

type类型说明

  • DirectoryOrCreate 卷映射对象是一个目录,如果不存在就创建它
  • Directory 卷映射对象是一个目录,且必须存在
  • FileOrCreate 卷映射对象是一个文件,如果不存在创建它
  • File 卷映射对象是一个文件,且必须存在
  • Socket 卷映射对象是一个Socket套接字,且必须存在
  • CharDevice 卷映射对象是一个字符设备,且必须存在
  • BlockDevice 卷映射对象是一个块设备,且必须存在

 

2. NFS

  • k8s中允许将nfs存储以卷的方式挂载到你的Pod中。在删除Pod时,nfs存储卷会被卸载(umount),而不是被删除。nfs卷可以在不同节点的Pod之间共享数据。
  • NFS最大的功能就是在不同节点的不同Pod中共享读写数据。
  • 需要一台NFS服务器
  • 在所有节点都需安装NFS(因为Pod是随机调度的,所以为保证NFS存储卷可以正确加载,需在所有node节点上都安装NFS软件工具包)
[root@master ~]# vim nfs.yaml
---
kind: Pod
apiVersion: v1
metadata:
  name: web1
spec:
  volumes:                  # 卷定义
  - name: website           # 卷定义
    nfs:                    # NFS 资源类型
      server: 192.168.1.10  # NFS 服务器地址
      path: /var/webroot    # NFS 共享目录
  containers:
  - name: nginx
    image: myos:nginx
    volumeMounts:            # mount- name: website          # 卷名称
      mountPath: /usr/local/nginx/html # 容器内路径
 
[root@master ~]# kubectl apply -f nfs.yaml
pod/nfs created

 

3. PV/PVC

accessMode:存储卷能提供的访问方式:

  • ReadWriteOnce: 单节点读写
  • ReadOnlyMany: 多节点只读
  • ReadWriteMang: 多节点读写
  • ReadWriteOnceMangy: 在一个Pod中只读

 

volumeMode: 提供资源的类型:

  • Filesystem:文件系统,直接mount就可以使用
  • Block:块设备,要先格式化在mount

 

1) 持久卷PV

[root@master ~]# vim pv.yaml
---
kind: PersistentVolume
apiVersion: v1
metadata:
  name: pv-local
spec:
  volumeMode: Filesystem     # 提供资源的类型[Filesystem,Block]
  accessModes:               # 存储卷能提供的访问模式
    - ReadWriteOnce          # 卷支持的模式,支持多种(hostPAth 只支持 RWO)
  capacity:                  # 存储卷能提供的存储空间
    storage: 30Gi            # 空间大小
  persistentVolumeReclaimPolicy: Retain  # 数据回收方式(手工回收) 
  hostPath:                  # hostPath配置
    path: /var/weblog
    type: DirectoryOrCreate
---
kind: PersistentVolume
apiVersion: v1
metadate:
  name: pv-nfs
spec:
  volumeMode: Filesystem     # 提供Filesystem访问方式
  accessModes:               # NFS支持多种访问方式
    - ReadWriteOnce          # RWO、ROX、RWX    
    - ReadOnlyMany
    - ReadWriteMany
  capacity:
    storage: 20Gi            # 提供的磁盘空间大小
  persistentVolumeReclaimPolicy: Retain # 数据手动回收
  mountOptions:              # mount的参数
    - nolock
  nfs:                       # NFS配置
    server: 192.168.1.10
    path: /var/webroot
 
[root@master ~]# kubectl apply -f pv.yaml
persistentvolume/pv-local created
persistentvolume/pv-nfs created
[root@master ~]# kubectl get persistentvolume
NAME     CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-local 30Gi     RWO          Retain         Available                        2s
pv-nfs   20Gi     RWO,ROX,RWX  Retain         Available                        2s

2)持久卷声明PVC

[root@master ~]# vim pvc.yaml
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: pvc1
spec:                      # 定义需求
  volumeMode: Filesystem   # 需要使用Filesystem的存储卷
  accessModes:
    - ReadWriteOnce        # 需要支持RWO的存储卷
  resources:
    requests:
      storage: 25Gi        # 最小磁盘空间需求
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata: 
  name: pvc2
spec:                      # 定义需求
  volumeMode: Filesystem   # 需要使用Filesystem的存储卷
  accessModes:
    - ReadWriteMany        # 需要支持RWX的存储卷
  resources:    
    requests:
      storage: 15Gi        # 最小磁盘空间需求
 
[root@master ~]# kubectl apply -f pvc.yaml
persistentvolumeclaim/pvc1 created
persistentvolumeclaim/pvc2 created
[root@master ~]# kubectl get persistentvolumeclaims
NAME STATUS VOLUME   CAPACITY ACCESS MODES STORAGECLASS AGE
pvc1 Bound  pv-local 30Gi     RWO                       17s
pvc2 Bound  pv-nfs   20Gi     RWO,ROX,RWX               17s

3)Pod挂载PVC

[root@master ~]# vim web1.yaml
---
kind: Pod
apiVersion: v1
metadata:
  name: web1
spec:
  volumes:                   # 卷定义
  - name: logdata            # 卷名称
    persistentVolumeClaim:   # 通过PVC引用存储资源
      claimName: pvc1        # PVC名称
  - name: website            # 卷名称
    persistentVolumeClaim:   # 通过PVC引用存储资源
      claimName: pvc2        # 卷名称
  containers:
  - name: nginx
    image: myos:nginx
    volumeMounts:            # mount- name: logdata            # 卷名称
      mountPath: /usr/local/nginx/logs # 容器内路径
    - name: website            # 卷名称
      mountPath: /usr/local/nginx/html # 容器内路径

 

 

 

 

 
 
 

posted on 2025-10-17 16:34  Karlkiller  阅读(16)  评论(0)    收藏  举报

导航