date: 2020-08-11title: k8s之pv与pvc #标题
tags: k8s数据持久化 #标签
categories: k8s # 分类

在k8s集群中,与管理计算资源相比,管理存储资源是一个完全不同的问题。为了更好的管理存储,Kubernetes 引入了 PersistentVolume (PV)和 PersistentVolumeClaim (PVC) 两个概念,将存储管理抽象成如何提供存储以及如何使用存储两个关注点。

PV与PVC简介

PV 存储卷是集群中的一块存储空间,由集群管理员管理、或者由 Storage Class(存储类)自动管理。PV(存储卷)和 node(节点)一样,是集群中的资源(kubernetes 集群由存储资源和计算资源组成)。PersistentVolumeClaim(存储卷声明,接下来统一简称为 PVC)是一种类型的 Volume(数据卷),PVC(存储卷声明)引用的 PV(存储卷)有自己的生命周期,该生命周期独立于任何使用它的容器组。PV描述了如何提供存储的细节信息(NFS、cephfs等存储的具体参数)。

PVC 存储卷声明代表用户使用存储的请求。Pod 容器组消耗 node 计算资源,PVC 存储卷声明消耗 PV 存储资源。Pod 容器组可以请求特定数量的计算资源(CPU / 内存);PVC 可以请求特定大小/特定访问模式(只能被单节点读写/可被多节点只读/可被多节点读写)的存储资源。

根据应用程序的特点不同,其所需要的存储资源也存在不同的要求,例如读写性能、存储空间大小等。我们必须能够提供关于 PV(存储卷)的更多选择,无需用户关心存储卷背后的实现细节。为了解决这个问题,K8s 引入了 StorageClass(存储类)的概念。

PV和PVC的关系如下:

  • PV: 用于提供持久卷,必须定义在与应用程序相同的名称空间中,关注应用程序如何使用存储,通常由应用程序管理员或开发人员负责;
  • PVC: 持久卷声明,用于向PV申请存储资源,只能定义在集群层面,关注集群如何提供存储,通常由集群管理员或者运维人员负责。

PV和PVC的关系

存储卷和存储卷声明的关系如下图所示:

  • PV 是集群中的存储资源,通常由集群管理员创建和管理。
  • StorageClass(接下来简称为 SC ) 用于对 PV 进行分类,如果正确配置,SC 也可以根据 PVC 的请求动态创建 PV。
  • PVC 是使用该资源的请求,通常由应用程序提出请求,并指定对应的 SC 和需求的空间大小。
  • PVC 可以做为数据卷的一种,被挂载到容器组/容器中使用。

k8s之pv与pvc - 图1

PVC的管理过程

PV和PVC的管理过程如下:

k8s之pv与pvc - 图2

k8s集群中,有两种方式实现PV和PVC的关联,一种是 手动创建PV和PVC,一种是动态创建,手动创建比较low,也不太实用,所以更建议通过SC去动态管理PV。在配置有合适的 SC(存储类)且 PVC 关联了该 SC 的情况下,k8s 集群可以为应用程序动态创建 PV。此方法的实现,可以参考我的博文: k8s数据持久化之自动创建pv

pvc和pv绑定(Binding)

假设创建了一个 PVC,并指定了需求的存储空间大小以及访问模式。K8s master 将立刻为其匹配一个 PV 存储卷,并将存储卷声明和存储卷绑定到一起。如果一个 PV 是动态提供给一个新的 PVC,K8s master 会始终将其绑定到该 PVC。除此之外,应用程序将被绑定一个不小于(可能大于)其 PVC 中请求的存储空间大小的 PV。一旦绑定,PVC 将拒绝其他 PV 的绑定关系。

PVC只能同时绑定到一个PV,但一个PV可以通过设置访问模式,被多个PVC绑定使用,关于PV的访问模式如下:

  • ReadWriteOnce:只能以读写的方式挂载到单个节点(单个节点意味着只能被单个PVC声明使用)。
  • ReadOnlyMany:能以只读的方式挂载到多个节点。
  • ReadWriteMany:能以读写的方式挂载到多个节点。

PVC 将始终停留在 未绑定 unbound 状态,直到有合适的 PV 可用。举个例子:集群中已经存在一个 50Gi 的 PV,同时有一个 100Gi 的 PVC,在这种情况下,该 PVC 将一直处于 未绑定 unbound 状态,直到管理员向集群中添加了一个 100Gi 的 PV。

注: 如果删除一个正在被使用的PVC,那么此PVC不会立即被删除,而是推迟到该 PVC 不在被任何容器组使用时才移除;同样的如果管理员删除了一个已经绑定到 PVC 的PV,则该 PV 也不会立刻被移除掉,而是推迟到其绑定的 PVC 被删除后才移除掉。

PV的回收策略

当用户不再需要其数据卷时,可以删除掉其PVC,此时其对应的PV将被集群回收并再利用。k8s集群根据PV中的reclaim policy(回收策略)决定在PV被回收时做对应的处理。当前支持的回收策略有:Retained(保留)、Recycled(重复利用)、Deleted(删除)

Recycle

此回收策略将在PV回收时,执行一个基本的清除操作(rm -rf /thevolume/*),并使其再次被新的PVC绑定。

Retain

此回收策略最为保险,需要集群管理员手动回收该资源,当绑定的PVC被删除后,PV仍然存在,并被认为是“已释放”。但是此时该PV仍然不能被其他PVC绑定,因为前一个绑定的PVC对应的容器组数据还在其中。

若要回收,可以通过以下步骤来回收;

  • 删除该PV,PV删除后,其数据仍然存在于对应的外部存储介质中(nfs、cefpfs、GFS等)。
  • 手工删除对应存储介质上的数据。
  • 手工删除对应的存储介质,也可以创建一个新的PV并再次使用该存储介质。

Delete

此策略将从k8s集群中移除PV以及其关联的外部存储介质(云环境中的 AWA EBS、GCE PD、Azure Disk 或 Cinder volume)。

注: 动态提供的 PV 将从其对应的 StorageClass 继承回收策略的属性。

PV的状态