zl程序教程

您现在的位置是:首页 >  后端

当前栏目

Kubernetes 持久化存储 PV PVC

Kubernetes存储 持久 pv PVC
2023-09-14 09:15:18 时间

kubernetes存储管理按照发展的历程,涉及到有Volume,PV(Persistent Volume)和PVC(PersistentVolumeClaims),和StorageClass,Volume是最早提出的存储卷,主要解决容器和数据存储的依赖关系,抽象底层驱动以支持不同的存储类型;使用Volume需要了解底层存储细节,因此提出了PV,Persistent Volume是由k8s管理员定义的存储单元,应用端使用PersistentVolumeClaims声明去调用PV存储,进一步抽象了底层存储;随着PV数量的增加,管理员需要不停的定义PV的数量,衍生了通过StorageClass动态生成PV,StorageClass通过PVC中声明存储的容量,会调用底层的提供商生成PV。本文介绍Volume的使用,下篇文章介绍PV,PVC和StorageClass。

  • Volume 存储卷,独立于容器,后端和不同的存储驱动对接
  • PV Persistent Volume持久化存储卷,和node类似,是一种集群资源,由管理员定义,对接不同的存储
  • PVC PersistentVolumeClaims持久化存储声明,和pod类似,作为PV的使用者
  • StorageClass 动态存储类型,分为静态和动态两种类型,通过在PVC中定义存储类型,自动创建所需PV

持久卷概述


PersistentVolume(PV): 对存储资源创建和使用的抽象,使得存储作为集群中的资源管理
PersistentVolumeClaim(PVC): 让用户不需要关心具体的Volume实现细节

K8s将存储当作资源管理,这样我们不需要知道存储具体的实现,我们不需要知道具体的细节,只需要关心使用多大的容量。

存储概述


kubernetes容器中的数据是临时的,即当重启重启或crash后容器的数据将会丢失,此外容器之间有共享存储的需求,所以kubernetes中提供了volume存储的抽象,volume后端能够支持多种不同的plugin驱动,通过.spec.volumes中定义一个存储,然后在容器中.spec.containers.volumeMounts调用,最终在容器内部以目录的形式呈现。

kubernetes内置能支持多种不同的驱动类型,大体上可以分为四种类型:

1. 公/私有云驱动接口,如awsElasticBlockStore实现与aws EBS集成,

2. 开源存储驱动接口,如ceph rbd,实现与ceph rb块存储对接,

3. 本地临时存储,如hostPath,

4. kubernetes对象API驱动接口,实现其他对象调用,如configmap,每种存储支持不同的驱动,如下介绍:

  1. 公/私有云驱动接口
  • awsElasticBlockStore AWS的EBS云盘
  • azureDisk 微软azure云盘
  • azureFile 微软NAS存储
  • gcePersistentDisk google云盘
  • cinder openstack cinder云盘
  • vsphereVolume VMware的VMFS存储
  • scaleIO EMC分布式存储
  1. 开源存储驱动接口
  • ceph rbd ceph块存储
  • cephfs ceph文件存储
  • glusterfs glusterfs存储
  • nfs nfs文件
  • iscsi
  • flexvolume
  • csi 社区标准化驱动
  • flocker
  1. 本地临时存储
  • hostpath 宿主机文件
  • emptyDir 临时目录
  1. kubernetes对象API驱动接口
  • configMap 调用configmap对象,注入配置文件
  • secrets 调用secrets对象,注入秘文配置文件
  • persistentVolumeClaim 通过pvc调用存储
  • downloadAPI 下载URL
  • projected

Volume 提供了非常好的数据持久化方案,不过在可管理性上还有不足。

拿前面 AWS EBS 的例子来说,要使用 Volume,Pod 必须事先知道如下信息:

  1. 当前 Volume 来自 AWS EBS。

  2. EBS Volume 已经提前创建,并且知道确切的 volume-id。

Pod 通常是由应用的开发人员维护,而 Volume 则通常是由存储系统的管理员维护。开发人员要获得上面的信息:

  1. 要么询问管理员。

  2. 要么自己就是管理员。

这样就带来一个管理上的问题:应用开发人员和系统管理员的职责耦合在一起了。如果系统规模较小或者对于开发环境这样的情况还可以接受。但当集群规模变大,特别是对于生成环境,考虑到效率和安全性,这就成了必须要解决的问题。

Kubernetes 给出的解决方案是 PersistentVolume 和 PersistentVolumeClaim。

PersistentVolume (PV) 是外部存储系统中的一块存储空间,由管理员创建和维护。与 Volume 一样,PV 具有持久性,生命周期独立于 Pod。

PersistentVolumeClaim (PVC) 是对 PV 的申请 (Claim)。PVC 通常由普通用户创建和维护。需要为 Pod 分配存储资源时,用户可以创建一个 PVC,指明存储资源的容量大小和访问模式(比如只读)等信息,Kubernetes 会查找并提供满足条件的 PV。

有了 PersistentVolumeClaim,用户只需要告诉 Kubernetes 需要什么样的存储资源,而不必关心真正的空间从哪里分配,如何访问等底层细节信息。这些 Storage Provider 的底层信息交给管理员来处理,只有管理员才应该关心创建 PersistentVolume 的细节信息。

Kubernetes 支持多种类型的 PersistentVolume,比如 AWS EBS、Ceph、NFS 等,完整列表请参考 https://kubernetes.io/docs/concepts/storage/persistent-volumes/#types-of-persistent-volumes

下面我们用 NFS 来体会 PersistentVolume 的使用方法。 p

[root@k8s-master ~]# cat pv.yaml 
apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteMany
  nfs:
    path: /ifs/kubernetes
    server: 192.168.179.102


[root@k8s-master ~]# kubectl get pv
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
my-pv   5Gi        RWX            Retain           Available                                   8s
[root@k8s-master ~]# kubectl describe pv my-pv
Name:            my-pv
Labels:          <none>
Annotations:     Finalizers:  [kubernetes.io/pv-protection]
StorageClass:    
Status:          Available
Claim:           
Reclaim Policy:  Retain
Access Modes:    RWX
VolumeMode:      Filesystem
Capacity:        5Gi
Node Affinity:   <none>
Message:         
Source:
    Type:      NFS (an NFS mount that lasts the lifetime of a pod)
    Server:    192.168.179.102
    Path:      /ifs/kubernetes
    ReadOnly:  false
Events:        <none>

pvc定义要使用多大的存储就行

[root@k8s-master ~]# cat my-pvc.yml 
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 7Gi


[root@k8s-master ~]# kubectl get pvc
NAME     STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
my-pvc   Pending                                                     21s

[root@k8s-master ~]# kubectl describe pvc my-pvc
Name:          my-pvc
Namespace:     default
StorageClass:  
Status:        Pending
Volume:        
Labels:        <none>
Annotations:   Finalizers:  [kubernetes.io/pvc-protection]
Capacity:      
Access Modes:  
VolumeMode:    Filesystem
Mounted By:    <none>
Events:
  Type    Reason         Age               From                         Message
  ----    ------         ----              ----                         -------
  Normal  FailedBinding  4s (x4 over 46s)  persistentvolume-controller  no persistent volumes available for this claim and no storage class is set

修改为5G,可以看到和Pv绑定了

[root@k8s-master ~]# kubectl get pvc
NAME     STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
my-pvc   Bound    my-pv    5Gi        RWX                           38s

删除pvc那么pv状态relase 后面就不能再绑定了

[root@k8s-master ~]# kubectl delete -f my-pvc.yml 
persistentvolumeclaim "my-pvc" deleted
[root@k8s-master ~]# kubectl get pv,pvc
NAME                     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS     CLAIM            STORAGECLASS   REASON   AGE
persistentvolume/my-pv   5Gi        RWX            Retain           Released   default/my-pvc                           30m

[root@k8s-master ~]# kubectl apply -f my-pvc.yml 
persistentvolumeclaim/my-pvc created
[root@k8s-master ~]# kubectl get pv,pvc
NAME                     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS     CLAIM            STORAGECLASS   REASON   AGE
persistentvolume/my-pv   5Gi        RWX            Retain           Released   default/my-pvc                           31m

NAME                           STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/my-pvc   Pending                                                     3s

PV 生命周期


ACCESS MODES(访问模式):
AccessModes 是用来对 PV 进行访问模式的设置,用于描述用户应用对存储资源的访问权限,访问权限包括下面几种方式:
ReadWriteOnce(RWO):读写权限,但是只能被单个节点挂载
ReadOnlyMany(ROX):只读权限,可以被多个节点挂载
ReadWriteMany(RWX):读写权限,可以被多个节点挂载
RECLAIM POLICY(回收策略):
目前 PV 支持的策略有三种:
Retain(保留): 保留数据,需要管理员手工清理数据    
Recycle(回收):清除 PV 中的数据,效果相当于执行 rm -rf /ifs/kuberneres/*
[root@k8s-master ~]# kubectl get pv,pvc
NAME                      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM           STORAGECLASS   REASON   AGE
persistentvolume/nfs-pv   5Gi        RWX            Recycle          Bound    default/my-pv                           35s

NAME                          STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/my-pv   Bound    nfs-pv   5Gi        RWX                           12s

[root@localhost ~]# ls /opt/k8s-pods/data/
index.html


[root@k8s-master ~]# kubectl delete -f my-pvc.yml 
persistentvolumeclaim "my-pv" deleted


[root@k8s-master ~]# kubectl get pv,pvc
NAME                      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS     CLAIM           STORAGECLASS   REASON   AGE
persistentvolume/nfs-pv   5Gi        RWX            Recycle          Released   default/my-pv                           115s


[root@localhost ~]# ls /opt/k8s-pods/data/


[root@k8s-master ~]# kubectl get pv,pvc
NAME                      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
persistentvolume/nfs-pv   5Gi        RWX            Recycle          Available                                   4m19s

Delete(删除):与 PV 相连的后端存储同时删除
STATUS(状态):
一个 PV 的生命周期中,可能会处于4中不同的阶段:
Available(可用):表示可用状态,还未被任何 PVC 绑定
Bound(已绑定):表示 PV 已经被 PVC 绑定
Released(已释放):PVC 被删除,但是资源还未被集群重新声明
Failed(失败): 表示该 PV 的自动回收失败
[root@k8s-master ~]# kubectl apply -f my-pvc.yml 
persistentvolumeclaim/my-pvc created
[root@k8s-master ~]# kubectl apply -f pv.yaml 
persistentvolume/my-pv created
[root@k8s-master ~]# kubectl get pv,pvc
NAME                     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM            STORAGECLASS   REASON   AGE
persistentvolume/my-pv   5Gi        RWX            Retain           Bound    default/my-pvc                           16s

NAME                           STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/my-pvc   Bound    my-pv    5Gi        RWX                           21s
[root@k8s-master ~]# 
[root@k8s-master ~]# 
[root@k8s-master ~]# kubectl apply -f deployment-pvc.yaml 
deployment.apps/deployment-pvc created
[root@k8s-master ~]# kubectl get pod -o wide
NAME                              READY   STATUS        RESTARTS   AGE    IP            NODE         NOMINATED NODE   READINESS GATES
deployment-pvc-679bc8746f-ftwp8   1/1     Running       0          81s    10.244.0.22   k8s-master   <none>           <none>
deployment-pvc-679bc8746f-h6zp7   1/1     Running       0          81s    10.244.0.21   k8s-master   <none>           <none>
deployment-pvc-679bc8746f-r9bk8   1/1     Running       0          81s    10.244.0.20   k8s-master   <none>           <none>

[root@k8s-master ~]# curl 10.244.0.22
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.19.6</center>
</body>
</html>


[root@k8s-master ~]# cat deployment-pvc.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-pvc
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-pvc
  template:
    metadata:
      labels:
        app: nginx-pvc
    spec:
      containers:
      - name: nginx
        image: nginx
        volumeMounts:
        - name: wwwroot
          mountPath: /usr/share/nginx/html
        ports:
        - containerPort: 80
      volumes:
      - name: wwwroot
        persistentVolumeClaim:   # 引用Pvc
          claimName: my-pvc

PV 生命周期


现在PV使用方式称为静态供给,需要K8s运维工程师提前创 建一堆PV,供开发者使用。