pvc|pv

正常创建pv时的逻辑,需要定义如下,用户\开发使用pvc,集群管理员创建pv,存储人员负责维护存储

在这里插入图片描述
​ 在pod中直接定义一个存储卷, 定义的时候只需要说明用多大的存储卷, 这个存储卷叫PVC类型的存储卷, 而该这个PVC类型的存储卷必须与当前名称空间中PVC建立直接绑定关系,而PVC又必须与PV建立绑定关系,PV应该是某个真正存储设备上的存储空间;

​ PVC与PC只是k8s之上的一种抽象资源,这两种资源与创建ingress或server并没有本质区别,底层存储给它切成块,然后在将块做成PV,pod直接指定volume并且PVC与PV建立绑定关系, PVC与PV建立绑定关系取决于在创建POD定义使用多大的存储空间时决定;
在这里插入图片描述

pvc

PersistentVolumeClaim(PVC)是用户存储的请求。它与 Pod 相似。Pod 消耗节点资源,PVC 消耗 PV 资源。Pod 可以请求特定级别的资源(CPU 和内存)。声明可以请求特定的大小和访问模式(例如,可以以读/写一次或 只读多次模式挂载)。

~]# kubectl explain pvc          # 系统自带的pvc资源
    KIND:     PersistentVolumeClaim 
    VERSION:  v1

~]# kubectl explain pvc.spec
    accessModes: 访问模型,是否支持多人访问
    resources:  资源限制, 最少需要多少资源
    selector:  必须选择哪个pv建立关系
    storageClassName: 存储类名称
    volumeMode: 存储卷模式
    volumeName:  精确选择某一个pv资源,默认就是随机
    
# PVC与PV是一一对应的, 但多个POD可以绑定一个PVC, 这个需要accessModes进行控制,绑定不了PVC就会padding

pvc状态

状态说明
Available资源尚未被claim使用
Bound卷已经被绑定到claim了
Releasedclaim被删除,卷处于释放状态,但未被集群回收
Failed卷自动回收失败

pv

PersistentVolume(PV)是由管理员设置的存储,它是群集的一部分。就像节点是集群中的资源一样,PV 也是集群中的资源。 PV 是 Volume 之类的卷插件,但具有独立于使用 PV 的 Pod 的生命周期。此 API 对象包含存储实现的细节,即 NFS、iSCSI 或特定于云供应商的存储系统。

~]# kubectl explain pv          # 建立与存储之间的关连
    KIND:     PersistentVolume
    VERSION:  v1

accessModes: 可以定义成多种权限, 三种权限都能被定义
    ReadWriteOnce – 存储卷只能被一个节点读写    RWO 
    ReadOnlyMany  – 存储卷可以同时被多个节点只读 ROX
    ReadWriteMany – 存储卷可以同时被多个节点读写 RWX

RECLAIM POLICY: 回收策略
 	Retain:   当删除PVC之后还保留PV

pv状态

binding:绑定状态,也就是说该pv已经绑定到了一个名称空间;

availble:可用状态,也就是说该pv可以供名称空间申请绑定;

reclaim:回收状态,表示pvc已删除,处于回收状态,回收有三种逻辑;
    recycle:删除pvc之后,清空对应pv里面的数据;
    delete(废弃):删除pvc同时删除pv;
    retain:删除pvc,pv和数据都保留;

PV生命周期

PV对于底层存储提供多种解决方案

  1. 静态提供,由管理员手动创建
  2. 动态提供,后端存储系统需要有很多的逻辑存储单元,但它并没有手动定义成PV,只有当用户有需要时在某个名称空间中创建PVC时,才会根据用户请求的需求来动态创建PV,比如说创建PVC时指定存储大小为1Gi,那么这时就会根据用户的需求找出底层存储空间中最合适的一个存储逻辑单元,将其动态创建成PV,并且让PV与PVC二者绑定,这就叫动态供给,而这种动态供给要求存储系统要实现存在多个逻辑存储单元,这种多个存储单元在必要时能满足PVC的请求,自动创建PV;
  3. 自动创建,后端存储只提供存储空间,也没有划分逻辑存储单元(类似于磁盘没有格式化),当用户创建PVC的时,根据用户的请求,动态的调用存储系统的管理接口,创建一个正好满足PVC需求的逻辑存储单元, 在将这个逻辑存储单元创建成为k8s集群上的PV,然后再与PVC绑定,但这个有一个基本的前提条件就是对应的存储系统需要支持restfull接口的API,比如ceph,不支持的如NFS

所以我们整个PV的生命周期,一、先提供PV,二、绑定PVC,三、绑定之后使用,四、用完就可以回收了;

存储类

​ 为什么pvc在创建时能动态触发供给pv,这个功能主要依赖于一个存储类(storageClass),也就是说,我们需要事先在k8s之上将外部的存储系统,比如ceph,在k8s之上先定义一种其它类型的存储资源(存储类[storageClass]);
​ 当创建一个PVC时,PVC不是向存储系统请求,而是向storageClass请求,而storageClass已经配置了如何连接这个外部存储系统的管理API接口,其内部配置了各种各样的连接参数,并且也知道如何连接底层的存储系统管理接口,在必要时会调用管理接口去创建一个逻辑存储单元,并且会自动在当前storageClass中创建一个PV,所以PV是属于storageClass的;
​ 当PVC去请求PV时,如果通过storageClass来实现,那么该PVC也属于storageClass, 需要注意的是,PVC只能向同一个storageClass中的PV请求绑定,假设PVC属于storageClass1,那它一定向storageClass1的PV请求绑定,不能跨存储类,如果PVC不属于任何一个storageClass,那么PV也不属于任何的storageClass;

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

类别类型说明
Bonze Storage Class图排存储又慢又笨,
Sliver Storage Class条形存储速度一般,
Gold Storage Class金牌存储性能可观,ssd

创建-示例-NFS

说明: pv绑定存储, pvc绑定pv(自动寻找大小匹配或者选择器选定的), pod绑定pvc, 动态提供
pod–>pvc–>pv–>存储

# 定义pvc存储卷
~]# kubectl explain pod.spec.volumes.persistentVolumeClaim
    claimName	<string> -required   # pvc卷组名称
    readOnly	<boolean>   # 是否只读

挂载目录

以NFS,动态提供为例, 实际 client --> storageClass --> 【PVC --> PV】 同一个存储类

[root@slave1 nfs]# cat /etc/exports
/data/nfs/v1 192.168.2.0/24(rw)
/data/nfs/v2 192.168.2.0/24(rw)
/data/nfs/v3 192.168.2.0/24(rw)

[root@slave1 nfs]# exportfs -arv     
exporting 192.168.2.0/24:/data/nfs/v3
exporting 192.168.2.0/24:/data/nfs/v2
exporting 192.168.2.0/24:/data/nfs/v1

Export list for slave1:
/data/nfs/v3 192.168.2.0/24
/data/nfs/v2 192.168.2.0/24
/data/nfs/v1 192.168.2.0/24

创建pv

1024 = 1Ki but 1000 = 1k

]# cat pv.yaml 
apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv-1
spec:
  capacity:
    storage: 5Gi
  accessModes:
  - ReadWriteOnce
  nfs:
    path: /data/nfs/v1
    server: 192.168.2.221
---
。。。。

]# kubectl get pv   # 定义三个
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM
my-pv-1   5Gi        RWO,ROX,RWX    Retain           Available        
my-pv-1   5Gi        RWO,ROX,RWX    Retain           Available        

]# kubectl describe pv my-pv-1
Name:            my-pv-1
Labels:          <none>
Annotations:     pv.kubernetes.io/bound-by-controller: yes
Finalizers:      [kubernetes.io/pv-protection]
StorageClass:    
Status:          Bound
Claim:           default/my-pvc-1
Reclaim Policy:  Retain
Access Modes:    RWO
VolumeMode:      Filesystem
Capacity:        5Gi
Node Affinity:   <none>
Message:         
Source:
    Type:      NFS (an NFS mount that lasts the lifetime of a pod)
    Server:    192.168.2.221
    Path:      /data/nfs/v1
    ReadOnly:  false

创建pvc

]# cat pvc.yaml 
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc-1
spec:
  accessModes: 
  - ReadWriteOnce
  resources:
    requests:
      storage: 4Gi
  volumeMode: Filesystem
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc-2
spec:
  accessModes: 
  - ReadWriteOnce
  resources:
    requests:
      storage: 4Gi
  volumeMode: Filesystem
      
]# kubectl get pv
NAME      CAPACITY   ACCESS  RECLAIM POLICY   STATUS   CLAIM              AGE
my-pv-1   5Gi        RWO     Retain           Bound    default/my-pvc-1   3d4h
my-pv-2   5Gi        RWO     Retain           Bound    default/my-pvc-2   3d4h

]# kubectl get pvc
NAME       STATUS   VOLUME    CAPACITY   ACCESS MODES   STORAGECLASS   AGE
my-pvc-1   Bound    my-pv-1   5Gi        RWO                           3d4h
my-pvc-2   Bound    my-pv-2   5Gi        RWO                           3d4h

]# kubectl describe pvc my-pvc-2
Name:          my-pvc-2
Namespace:     default
StorageClass:  
Status:        Bound
Volume:        my-pv-2
Labels:        <none>
Annotations:   pv.kubernetes.io/bind-completed: yes
               pv.kubernetes.io/bound-by-controller: yes
Finalizers:    [kubernetes.io/pvc-protection]
Capacity:      5Gi
Access Modes:  RWO
VolumeMode:    Filesystem
Mounted By:    <none>
Events:        <none>

创建pod

# cat nfs_bound_pv.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nfs2nfs
spec:
  selector:
    matchLabels:
      name: my-bound
      release: qa
  replicas: 2
  strategy: 
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 0
    type: RollingUpdate
  template:
    metadata:
      name: my-temp
      labels:
        name: my-bound
        release: qa
    spec:
      containers:
      - name: my-bounds
        image: ikubernetes/myapp:v1
        imagePullPolicy: IfNotPresent
      volumes:
      - name: my-bounds
        persistentVolumeClaim:
          claimName: "my-pvc-1"
  
]# kubectl describe pvc my-pvc-1
Name:          my-pvc-1
Namespace:     default
StorageClass:  
Status:        Bound
Volume:        my-pv-1
Labels:        <none>
Annotations:   pv.kubernetes.io/bind-completed: yes
               pv.kubernetes.io/bound-by-controller: yes
Finalizers:    [kubernetes.io/pvc-protection]
Capacity:      5Gi
Access Modes:  RWO
VolumeMode:    Filesystem
Mounted By:    nfs2nfs-7fccfd4dbb-9jjxb
               nfs2nfs-7fccfd4dbb-szhwv
Events:        <none>

yes
               pv.kubernetes.io/bound-by-controller: yes
Finalizers:    [kubernetes.io/pvc-protection]
Capacity:      5Gi
Access Modes:  RWO
VolumeMode:    Filesystem
Mounted By:    nfs2nfs-7fccfd4dbb-9jjxb
               nfs2nfs-7fccfd4dbb-szhwv
Events:        <none>
Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐