Kubernetes:Kubernetes卷、持久卷声明(PVC)、持久卷(PV)
在这篇文章中,我们将讲解Kubernetes卷的适用场景和限制,以及处理Kubernetes中PVC和PV的步骤概览。
作者:阿里巴巴的高级研发工程师,黄柯(Zhitian)先生。
1)卷的介绍
音频容量
Pod Volume在以下情况下被使用。
-
- シナリオ1)Pod内のコンテナがクラッシュし、kubeletによって再起動されたときに、コンテナが生成した重要なデータが失われないようにする。
-
- シナリオ2)Pod内の複数のコンテナ間でのデータ共有を確保する。
- では、一般的なPod Volumesの種類を見てみましょう。
1)本地存储:可能包含emptydir/hostpath。
2)网络存储:分为内部实现方式和外部实现方式。内部实现方式将实现代码存储在Kubernetes的代码库中。随着Kubernetes支持的存储类型增多,这种方式会使得Kubernetes的维护和开发变得困难。外部实现方式则将不同存储设备的驱动程序从Kubernetes代码库中移除,并使用抽象API。因此,在实现网络存储插件时,推荐使用外部实现方式。
接下来,理解以下音量的概念是很重要的。
1)预测的卷:部分配置如secret/configmap通过卷挂载到容器中,容器内的程序通过POSIX(可移植操作系统接口)访问配置。
2)持久卷(PVs)和持久卷声明(PVCs):本文重点介绍了这些卷,并在以下章节进行解释。
视频

在可用Pod Volume情况下,理解引入PV的必要性非常重要。声明为Pod的Volume的生命周期和Pod的生命周期相同。通常情况如下:
-
- シナリオ1:イメージのアップグレード中にDeploymentで管理されているPodが削除され、再作成された場合、新しいPodは古いPodのデータを再利用する必要があります。
-
- シナリオ2:ホストが応答しなくなったとき、Podをホストから移行する必要があります。StatefulSetで管理されているPodには、Podボリュームでは実現できないボリュームベースの移行のセマンティクスが実装されています。
-
- シナリオ3:Pod間のデータ共有を宣言する必要があります。Pod Volumeは、Pod内の複数のコンテナ間でデータを共有するために使用されます。しかし、Pod Volumeは、複数のPod間のデータ共有には使用できません。
- シナリオ4:スナップショットの追加やリサイズ機能など、ボリュームの機能を拡張する必要があります。
在前面的方案中,很难准确地通过Pod Volume来表示重用和共享的语义,并且难以扩展功能。因此,我们将存储和计算分离,并通过不同的组件来管理存储资源和计算资源,将Pod的生命周期和卷的生命周期分离,将PV引入Kubernetes。这样,即使Pod被删除,其PV依然存在并可以在新的Pod中重新使用。
PVC设计

使用PV其实是在使用PVC。那么既然可以使用PV,为什么还需要设计PVC呢?PVC的设计是为了简化Kubernetes用户的存储使用,并将用户的存储需求与实现细节分离。通常情况下,在使用存储时,只需声明所需的存储大小和访问模式即可。
访问模式是指所使用的存储是在多个节点(而不是Pod)中共享,还是在单个节点(而不是Pod)中独占访问。此外,还需要指明所使用的存储是只支持读取访问,还是同时支持读取和写入。这是唯一的关注点。
PVC和PV将需求和实现细节分离。使用PVC声明存储要求。通过集群管理员和存储团队统一管理PV,简化存储使用。PV和PVC的设计类似于面向对象的API和实现的关系,使用函数时无需了解实现细节,只需关注API即可。
在接下来的部分中,我们将讨论PV是如何生成的。
静态容量分配

在这个模式下,集群管理员会规划集群用户如何使用存储。预先创建了一些永久卷(PV)。用户提交PVC后,Kubernetes的组件会协助将PVC和PV进行匹配。当用户需要通过Pod使用存储时,用户可以根据PVC找到相应的PV并使用它们。
静态卷予配的缺点是什么?集群管理员需要预先创建持久卷(PV),然而预测用户实际需求是困难的。例如,即使用户需要一个20GB的PV,但集群管理员预先创建了80GB或100GB的PV,这些卷将成为资源的浪费,并且无法满足用户的实际需求。
音量的动态分配

在这种模式下,集群管理员无需预先创建永久卷(PV)。相反,集群管理员需要创建包含特定类型存储设备所需参数的模板文件,如块存储或网络附加存储(NAS)。这些参数与存储实施相关,但与用户无关。用户所需要做的就是提交持久卷声明(PVC)并指定要使用的存储模板(StorageClass)。
Kubernetes集群中的控制组件根据PVC和StorageClass的动态信息生成用户所需的存储设备(PV)。在PVC和PV绑定后,Pod可以使用PV。控制组件通过生成存储所需的存储模板(StorageClass)并根据用户需求动态创建PV,实现按需分配。这样一来,可以减轻集群管理员的运维工作,同时不增加用户的使用难度。
使用样例
这里将对Pod Volume、PV、PVC、StorageClass的使用方法进行解释。
Pod Volumes的使用方式

根据左侧的图表,我们在Pod的YAML文件中的”volume”字段中声明了一个卷的名称和类型。一个卷是emptyDir类型,另一个是hostPath类型。它们都是本地卷。卷会在容器内部使用,根据”volumeMounts”字段进行挂载。”volumeMounts”指定的”name”表示要使用的卷的名称,”mountPath”表示容器内的挂载目录。
还有一个”subPath”字段。
无论哪个容器,都使用名为”cache-volume”的相同卷,并且当多个容器共享相同卷时,使用”subPath”来分离数据。这样一来,在卷内会创建两个子目录。容器1写入缓存的数据实际上会被写入cache1子目录中,容器2写入的数据则会被写入cache2子目录中。
「readOnly」字段将禁止向挂载点写入数据。
请问,emptyDir和hostPath有什么区别呢?emptyDir是在创建Pod时临时创建的目录。当Pod被删除时,目录和其中的数据也会被删除。而hostPath是主机上的目录,即使Pod被删除,目录和其中的数据仍然存在。
静态PV的使用方式

静态PV由管理员创建。在这篇文章中,以NAS(网络附加存储)为例。在阿里云NAS控制台上创建NAS,并将NAS信息添加到PV对象中。一旦预先创建了PV对象,就可以使用PVC声明存储需求并创建Pod。要创建Pod,需要将存储挂载到容器的挂载点,根据上述字段进行操作。
为了写入YAML文件,集群管理员可以在云存储供应商端创建PV并添加相关的信息到PV对象中。

请注意作成的NAS对应的一些重要字段。”capacity”字段表示创建的存储的大小,”accessModes”字段表示创建的存储的访问模式。
「PersistentVolumeReclaimPolicy」字段表示PV的回收策略。换句话说,它指定了在删除使用PV的Pod和PVC之后,是删除PV还是保留PV。
在使用存储之前,请创建 PVC 对象。此对象仅需指定存储需求,无需指定存储实现的详细信息。存储需求包括所需存储的大小 “resources.requests.storage” 和存储访问模式 “accessModes”。访问模式声明为 “ReadWriteMany”,表示支持对多个节点具有读写权限的访问,这是 NAS 的典型功能。

在前面的图中所展示的大小和访问模式与创建的静态PV匹配。在这种情况下,在提交PVC时,Kubernetes集群组件将绑定PV和PVC。然后,在提交Pod的YAML文件时,将claimName设置为卷,并声明所需的PVC。挂载方法与前面的相同。提交YAML文件后,将找到基于PVC绑定的PV,并可用于使用存储。以上就是PV在静态预配的情况下被创建,并在Pod中使用的机制。
动态光伏的使用方法
在动态PV中,系统管理员可以创建模板文件,而不需要事先分配PV。

模板文件需要在StorageClass中设置重要信息,例如提供者等。提供者会指定用于创建持久卷和相应存储的存储插件。
创建 Kubernetes 存储时,需要指定这些参数。在这里,我们忽略 regionld、zoneld、fsType、type 等参数。reclaimPolicy 参数用于表示动态持久卷(PV)和持久卷声明(PVC)在被删除后的处理方式,”Delete” 的值表示当 Pod 和 PVC 被删除时,PV 也会被删除。
在集群管理员提交StorageClass(PV创建模板)后,首先要创建PVC文件。

不会更改PVC文件的存储大小和访问模式。在这种情况下,需要添加StorageClassName字段,并指定动态PV模板文件的名称。在这里,我们将StorageClassName设置为csi-disk。
当PVC被提交时,Kubernetes集群内的组件会根据PVC和对应的StorageClass动态生成PV,并将PV与PVC绑定。在发送YAML文件后,根据PVC找到动态PV并将其挂载到相应的容器上。
PV的主要领域 (PV zhī

-
- Capacity:ストレージオブジェクトのサイズ。
- AccessModes:PVの使用モード。PVは3つのモードで使用されます。
1) 一次讀寫:單節點的讀寫模式
2) 僅讀多人:多節點的只讀模式,一般的數據共享模式
3) 讀寫多人:多節點的讀寫兩用模式
“Capacity” 和 “AccessModes” 是提交的 PVC 中最重要的字段。当 PVC 被提交后,Kubernetes 集群中的组件会通过以下方式找到合适的 PV。
这个组件是基于PV创建的AccessModes索引,获取满足特定PVC的AccessModes字段的所有PV的列表,并根据PVC的Capacity、StorageClassName和Label Selector的值将PV进行筛选。如果有多个PV满足条件,则选择大小最短且访问模式列表最短的PV。
- PersistentVolumeReclaimPolicy:特定のPVのPVCが削除された後、PVがどのように処理されるかを指定するポリシーです。PV は 3 つのモードで処理されます。
1)回收利用:(放棄)
2) 刪除:當 PVC 被刪除時,PV 也會被刪除。
3) 保留:即使 PVC 被刪除,PV 仍然保留。這將由系統管理員處理。
-
- StorageClassName:ボリュームの動的プロビジョニング時にPVを生成するために使用するテンプレートファイルの名前です。
- NodeAffinity:作成されたPVがマウントされるノードの制限です。NodeAffinity は、PV を使用するPodも制限します。この場合、Podは、PV を使用するノードにスケジュールされたときにのみ PV を使用します。このフィールドについては、ストレージトポロジースケジューリングのセクションで説明します。
PV状态的转变 de

在PV对象创建之后,会处于保留状态一段时间。实际的PV创建完成后,将变为可用状态。
提交 PVC 后,相关的 Kubernetes 组件会将 PV 绑定到 PVC 上。在这种情况下,PV 和 PVC 都会处于绑定状态。当使用 PVC 后,如果删除 PVC,则 PV 将释放并变为可用状态。此外,PersistentVolumeReclaimPolicy 字段决定是否删除或保留 PV。
当PV被释放后,无法直接恢复为可直接使用的状态,因此无法绑定到新的PVC上。要重新使用被释放的PV,可以使用以下任何一种方法。
方法1: 创建一个PV对象,并将发布的PV字段信息添加到其中,将PV绑定到新的PVC。
方法2: 删除Pod,但保留PVC对象。在这种情况下,与PV绑定的PVC仍然存在,Pod将直接重用PV基于PVC。这是Kubernetes中StatefulSet管理的基于卷的Pod迁移。
3)示范演示
下一步,我们将介绍在实际环境中进行静态卷配置和动态卷配置的方法。
静态音量配置的例子
在静态卷的供给方面,我们使用阿里云的NAS。在动态卷的供给方面,我们使用阿里云的磁盘。我们已经将必要的存储插件如阿里云NAS的csi-nasplugin和阿里云磁盘的csi-disk部署到Kubernetes集群中。

下图是一个静态配置的PV YAML文件,用于容量配置。

volumeAttributes用于指定与已在阿里巴巴云NAS控制台上预先创建的NAS相关的信息。存储字段下的容量为5Gi,访问模式字段为ReadWriteMany,持久卷回收策略为Retain,该驱动程序在卷上被使用。
我将创建PV。

如上图所示,太阳能电池已经处于可利用状态。
然后,创建nas-pvc。

那么,PVC已经被创建并且已绑定到创建的PV上。

PVC的YAML文件中记录了所需的存储大小和访问模式。当发送PVC时,它将绑定到集群中匹配的PV。
接下来,我们将创建一个使用nas-fs的Pod。

如上图所示,两个Pod正在运行中。

Pod的YAML文件中声明了创建的PVC对象,并将PVC对象挂载到nas-container容器的/data目录。通过“Deployment”创建了Pod的两个副本,并通过反亲和性调度到不同的节点上。

在上述图中,有两个Pod被部署在不同的主机上。
以下是对中文的同义转述:
按照下图,登录到第一个容器并执行findmnt命令以显示其挂载信息。请注意它被挂载到已声明的nas-fs。接下来,对test.test.test文件执行touch命令。然后,登录到另一个容器并确认是否已共享。

完成後,再次登錄到初始容器中。
执行findmnt命令,确认两个Pod被远程挂载到同一个目录,也就是使用了相同的NAS PV。通过两个Pod的存在,可以确定这两个Pod在不同的节点上运行,并且共享NAS。

请先删除 Pod,然后再删除相应的 PVC。无法删除正在使用的 PVC。

像下面的图一样,PVC被移除。

NAS的PV在发布状态下仍然存在,并且使用此PV的PVC已被删除,表明它已被释放。由于RECLAIM POLICY设置为Retain,PV将被保留。
动态配置的例子
手动删除保持的PV。在这种情况下,集群内不存在PV。
创建用于生成PV的StorageClass模板文件,并验证文件内容。

根据上述图示,指定使用用于创建存储的卷插件(由阿里云团队创建的阿里云磁盘插件)。请忽略参数部分,其包含了创建存储所需的参数。reclaimPolicy参数被设置为Delete,表示由StorageClass创建的持久卷(PV)将在其绑定的持久卷声明(PVC)被删除后也被删除。

如上图所示,集群中不包含PV。将提交PVC文件。在PVC文件中,accessModes为ReadWriteOnce(阿里云的磁盘仅支持单节点读写模式),存储容量为30Gi,StorageClassName为之前创建的csi-disk StorageClass。

PVC保持中,表示相应的PV正在创建中。

请确认一段时间后生成了新的PV。这个PV是基于提供的PVC和PVC指定的存储类动态生成的。然后,Kubernetes将生成的PV绑定到提交的PVC(磁盘PVC)。接下来,让我们创建并使用Pod。

在 Pod 的 YAML 文件中,声明要使用的 PVC。然后,创建挂载点。

以下的图表表示了该事件。当节点被调度时,attachdetach控制器会将磁盘连接到节点上。这意味着调度器将挂载与调度的节点对应的持久卷(PV)。然后,Pod内相应的容器会启动,并使用相应的磁盘。

在这种情况下,PVC和相应的PV存在。

请删除 PVC。我们可以看到 PV 也被删除了。因此,PV 会根据 reclaimPolicy 与 PVC 一起被删除。

4) 建筑设计
PV和PVC的处理过程
让我们看一下图中右下方的CSI(容器存储接口)。

在Kubernetes社群中,推荐使用CSI来进行离线模式。CSI的实现分为两个部分。
-
- 1つはKubernetesコミュニティが推進する共通部分で、この図のcsi-provisionerやcsi-attacher controllerなどがそれにあたります。
- もう一つの部分は、図のcsi-controller-serverやcsi-node-serverのようなクラウドストレージベンダーによって実装されています。CSIはクラウドストレージベンダーのOpenAPIに接続して、create、delete、mount、unmountなどのストレージ関連の操作を実装します。
当发送PVC的YAML文件时,在集群内将生成PVC对象,并由csi-provisioner控制器进行监视。然后,csi-provisioner会根据PVC对象和声明在PVC对象中的StorageClass,通过GRPC调用csi-controller-server,在云存储服务上创建实际存储并创建PV对象。最后,集群内的PV控制器将PVC和PV进行绑定,然后PV将被使用。
在提交 Pod 后,调度器会安排合适的节点进行调度。在 Pod 创建过程中,节点上的 kubelet 会通过 csi-node-server 将创建的 PV 挂载到 Pod 的可用目录中,并创建和启动 Pod 中的所有容器。
使用情况为 PV、PVC 和 CSI 基础的存储。
以下图表展示了使用PV、PVC和CSI的存储方法。
(The following chart illustrates the usage methods of storage using PV, PVC, and CSI.)

整个过程分为三个阶段。
-
- Createステージでは、PVCを提出した後、csi-provisionerがストレージを作成してPVオブジェクトを生成し、PVコントローラがPVCと生成されたPVオブジェクトを結合します。
-
- Attachステージでは、PodのYAMLファイルを送信しながら、スケジューラが適切なノードをスケジュールします。ADコントローラは、ノードを監視した後、Podで使用されているPVをチェックします。その後、VolumeAttachmentという名前の内部オブジェクトが生成され、これがcsi-attacherのトリガーとなってcsi-controller-serverを呼び出し、クラウドストレージベンダーのOpenAPIを使用して実際のアタッチ操作を実行します。アタッチ操作は、Podが実行されるノードにストレージをアタッチします。
- マウントステージは、kubeletがPodを作成しているときに始まります。Pod作成時には、ノードに取り付けられたディスクが、Podからアクセス可能な特定のディレクトリにマウントされます。その後、kubeletはコンテナの作成と起動を開始します。
总结起来,Create阶段会创建存储。Attach阶段会将存储挂载到节点上(通常挂载到节点的/dev目录下)。Mount阶段会将存储挂载到Pod可以访问的目录中。
总结
在这篇文章中,我们解释了Kubernetes卷的应用场景和限制,并定义了PVC和PV系统。基于这个系统,Kubernetes在多个Pod共享、迁移和扩展存储等场景下扩展了Kubernetes卷。此外,我们还解释了不同的PV配置模式(静态和动态),以及如何为集群内的Pod在不同模式之间进行存储配置。最后,我们详细说明了Kubernetes中PVC和PV的处理步骤,以帮助用户理解PVC和PV的工作原理。
本博客是从英语版翻译而来的。您可以在这里查看原文。我们部分地使用机器翻译。如果有任何翻译错误,请您提醒我们,我们将不胜感激。
阿里巴巴云计算在日本拥有两个数据中心,并拥有超过60个可用区域,
是亚太地区的头号云基础设施服务提供商(2019 年由 Gartner 调研得出的结论)。
欲了解更多关于阿里巴巴云计算的详细信息,请点击这里。
阿里巴巴云计算日本官方网页。