K8S 快速入门(十四)实战篇:持久卷(PV)、持久卷申领(PVC)

PV&PVC

持久卷 官方文档

1. PV&PVC介绍

存储的管理是一个与计算实例的管理完全不同的问题。PersistentVolume 子系统为用户 和管理员提供了一组 API,将存储如何供应的细节从其如何被使用中抽象出来。 为了实现这点,我们引入了两个新的 API 资源:PersistentVolumePersistentVolumeClaim

  • 持久卷(PersistentVolume,PV)是集群中的一块存储,可以由管理员事先供应,或者 使用存储类(Storage Class)来动态供应。 持久卷是集群资源,就像节点也是集群资源一样。PV 持久卷和普通的 Volume 一样,也是使用 卷插件来实现的,只是它们拥有独立于任何使用 PV 的 Pod 的生命周期。 此 API 对象中记述了存储的实现细节,无论其背后是 NFS、iSCSI 还是特定于云平台的存储系统。
  • 持久卷申领(PersistentVolumeClaim,PVC)表达的是用户对存储的请求。概念上与 Pod 类似。 Pod 会耗用节点资源,而 PVC 申领会耗用 PV 资源。Pod 可以请求特定数量的资源(CPU 和内存);同样 PVC 申领也可以请求特定的大小和访问模式 (例如,可以要求 PV 卷能够以 ReadWriteOnce、ReadOnlyMany 或 ReadWriteMany 模式之一来挂载,参见访问模式)。

尽管 PersistentVolumeClaim 允许用户消耗抽象的存储资源,常见的情况是针对不同的 问题用户需要的是具有不同属性(如,性能)的 PersistentVolume 卷。 集群管理员需要能够提供不同性质的 PersistentVolume,并且这些 PV 卷之间的差别不 仅限于卷大小和访问模式,同时又不能将卷是如何实现的这些细节暴露给用户。 为了满足这类需求,就有了 存储类(StorageClass) 资源。

PV/PVC主要实现了容器存储的编排

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

pv&pvc区别

PersistentVolume(持久卷)PersistentVolumeClaim(持久卷申领)是k8s提供的两种API资源,用于抽象存储细节。

管理员关注如何通过pv提供存储功能而无需关注用户如何使用,同样的用户只需要挂载pvc到容器中而不需要关注存储卷采用何种技术实现。

pvc和pv的关系与pod和node关系类似,前者消耗后者的资源。pvc可以向pv申请指定大小的存储资源并设置访问模式,这就可以通过Provision -> Claim 的方式,来对存储资源进行控制。

2. PV&PVC的生命周期

PV 卷是集群中的资源。PVC 申领是对这些资源的请求,也被用来执行对资源的申领检查。 PV 卷和 PVC 申领之间的互动遵循如下生命周期:

2.1 供应

PV 卷的供应有两种方式:静态供应或动态供应。

  • 静态供应
    集群管理员创建若干 PV 卷。这些卷对象带有真实存储的细节信息,并且对集群 用户可用(可见)。PV 卷对象存在于 Kubernetes API 中,可供用户消费(使用)。

  • 动态供应
    如果管理员所创建的所有静态 PV 卷都无法与用户的 PersistentVolumeClaim 匹配, 集群可以尝试为该 PVC 申领动态供应一个存储卷。 这一供应操作是基于 StorageClass 来实现的:PVC 申领必须请求某个 存储类,同时集群管理员必须 已经创建并配置了该类,这样动态供应卷的动作才会发生。 如果 PVC 申领指定存储类为 "",则相当于为自身禁止使用动态供应的卷。

    为了基于存储类完成动态的存储供应,集群管理员需要在 API 服务器上启用 DefaultStorageClass 准入控制器。 举例而言,可以通过保证 DefaultStorageClass 出现在 API 服务器组件的 --enable-admission-plugins 标志值中实现这点;该标志的值可以是逗号 分隔的有序列表。关于 API 服务器标志的更多信息,可以参考 kube-apiserver 文档。

2.2 绑定

用户创建一个带有特定存储容量和特定访问模式需求的 PersistentVolumeClaim 对象; 在动态供应场景下,这个 PVC 对象可能已经创建完毕。 主控节点中的控制回路监测新的 PVC 对象,寻找与之匹配的 PV 卷(如果可能的话), 并将二者绑定到一起。 如果为了新的 PVC 申领动态供应了 PV 卷,则控制回路总是将该 PV 卷绑定到这一 PVC 申领。 否则,用户总是能够获得他们所请求的资源,只是所获得的 PV 卷可能会超出所请求的配置。 一旦绑定关系建立,则 PersistentVolumeClaim 绑定就是排他性的,无论该 PVC 申领是 如何与 PV 卷建立的绑定关系。 PVC 申领与 PV 卷之间的绑定是一种一对一的映射,实现上使用 ClaimRef 来记述 PV 卷 与 PVC 申领间的双向绑定关系。

如果找不到匹配的 PV 卷,PVC 申领会无限期地处于未绑定状态。 当与之匹配的 PV 卷可用时,PVC 申领会被绑定。 例如,即使某集群上供应了很多 50 Gi 大小的 PV 卷,也无法与请求 100 Gi 大小的存储的 PVC 匹配。当新的 100 Gi PV 卷被加入到集群时,该 PVC 才有可能被绑定。

2.3 使用

Pod 将 PVC 申领当做存储卷来使用。集群会检视 PVC 申领,找到所绑定的卷,并 为 Pod 挂载该卷。对于支持多种访问模式的卷,用户要在 Pod 中以卷的形式使用申领 时指定期望的访问模式。

一旦用户有了申领对象并且该申领已经被绑定,则所绑定的 PV 卷在用户仍然需要它期间 一直属于该用户。用户通过在 Pod 的 volumes 块中包含 persistentVolumeClaim 节区来调度 Pod,访问所申领的 PV 卷。

2.4 保护使用中的存储对象

保护使用中的存储对象(Storage Object in Use Protection)这一功能特性的目的 是确保仍被 Pod 使用的 PersistentVolumeClaim(PVC)对象及其所绑定的 PersistentVolume(PV)对象在系统中不会被删除,因为这样做可能会引起数据丢失。

说明: 当使用某 PVC 的 Pod 对象仍然存在时,认为该 PVC 仍被此 Pod 使用。

如果用户删除被某 Pod 使用的 PVC 对象,该 PVC 申领不会被立即移除。 PVC 对象的移除会被推迟,直至其不再被任何 Pod 使用。 此外,如果管理员删除已绑定到某 PVC 申领的 PV 卷,该 PV 卷也不会被立即移除。 PV 对象的移除也要推迟到该 PV 不再绑定到 PVC。

你可以看到当 PVC 的状态为 Terminating 且其 Finalizers 列表中包含 kubernetes.io/pvc-protection 时,PVC 对象是处于被保护状态的。

kubectl describe pvc hostpath
Name:          hostpath
Namespace:     default
StorageClass:  example-hostpath
Status:        Terminating
Volume:
Labels:        <none>
Annotations:   volume.beta.kubernetes.io/storage-class=example-hostpath
               volume.beta.kubernetes.io/storage-provisioner=example.com/hostpath
Finalizers:    [kubernetes.io/pvc-protection]
...

你也可以看到当 PV 对象的状态为 Terminating 且其 Finalizers 列表中包含 kubernetes.io/pvc-protection 时,PV 对象是处于被保护状态的。

kubectl describe pv task-pv-volume
Name:            task-pv-volume
Labels:          type=local
Annotations:     <none>
Finalizers:      [kubernetes.io/pv-protection]
StorageClass:    standard
Status:          Terminating
Claim:
Reclaim Policy:  Delete
Access Modes:    RWO
Capacity:        1Gi
Message:
Source:
    Type:          HostPath (bare host directory volume)
    Path:          /tmp/data
    HostPathType:
Events:            <none>

2.5 回收

当用户不再使用其存储卷时,他们可以从 API 中将 PVC 对象删除,从而允许 该资源被回收再利用。PersistentVolume 对象的回收策略告诉集群,当其被 从申领中释放时如何处理该数据卷。 目前,数据卷可以被 Retained(保留)Recycled(回收)Deleted(删除)

2.5.1 保留(Retain)

回收策略 Retain 使得用户可以手动回收资源。当 PersistentVolumeClaim 对象 被删除时,PersistentVolume 卷仍然存在,对应的数据卷被视为"已释放(released)"。 由于卷上仍然存在这前一申领人的数据,该卷还不能用于其他申领。 管理员可以通过下面的步骤来手动回收该卷:

  1. 删除 PersistentVolume 对象。与之相关的、位于外部基础设施中的存储资产 (例如 AWS EBS、GCE PD、Azure Disk 或 Cinder 卷)在 PV 删除之后仍然存在。
  2. 根据情况,手动清除所关联的存储资产上的数据。
  3. 手动删除所关联的存储资产;如果你希望重用该存储资产,可以基于存储资产的 定义创建新的 PersistentVolume 卷对象。

2.5.2 删除(Delete)

对于支持 Delete 回收策略的卷插件,删除动作会将 PersistentVolume 对象从 Kubernetes 中移除,同时也会从外部基础设施(如 AWS EBS、GCE PD、Azure Disk 或 Cinder 卷)中移除所关联的存储资产。 动态供应的卷会继承其 StorageClass 中设置的回收策略,该策略默认 为 Delete。 管理员需要根据用户的期望来配置 StorageClass;否则 PV 卷被创建之后必须要被 编辑或者修补。参阅更改 PV 卷的回收策略.

2.5.3 回收(Recycle)

警告: 回收策略 Recycle 已被废弃。取而代之的建议方案是使用动态供应。

如果下层的卷插件支持,回收策略 Recycle 会在卷上执行一些基本的 擦除(rm -rf /thevolume/*)操作,之后允许该卷用于新的 PVC 申领。

不过,管理员可以按 参考资料 中所述,使用 Kubernetes 控制器管理器命令行参数来配置一个定制的回收器(Recycler) Pod 模板。此定制的回收器 Pod 模板必须包含一个 volumes 规约,如下例所示:

apiVersion: v1
kind: Pod
metadata:
  name: pv-recycler
  namespace: default
spec:
  restartPolicy: Never
  volumes:
  - name: vol
    hostPath:
      path: /any/path/it/will/be/replaced
  containers:
  - name: pv-recycler
    image: "k8s.gcr.io/busybox"
    command: ["/bin/sh", "-c", "test -e /scrub && rm -rf /scrub/..?* /scrub/.[!.]* /scrub/*  && test -z \"$(ls -A /scrub)\" || exit 1"]
    volumeMounts:
    - name: vol
      mountPath: /scrub

定制回收器 Pod 模板中在 volumes 部分所指定的特定路径要替换为 正被回收的卷的路径。

2.6 预留 PersistentVolume

通过在 PersistentVolumeClaim 中指定 PersistentVolume,你可以声明该特定 PV 与 PVC 之间的绑定关系。如果该 PersistentVolume 存在且未被通过其 claimRef 字段预留给 PersistentVolumeClaim,则该 PersistentVolume 会和该 PersistentVolumeClaim 绑定到一起。

绑定操作不会考虑某些卷匹配条件是否满足,包括节点亲和性等等。 控制面仍然会检查 存储类、访问模式和所请求的 存储尺寸都是合法的。

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: foo-pvc
  namespace: foo
spec:
  storageClassName: "" # 此处须显式设置空字符串,否则会被设置为默认的 StorageClass
  volumeName: foo-pv
  ...

此方法无法对 PersistentVolume 的绑定特权做出任何形式的保证。 如果有其他 PersistentVolumeClaim 可以使用你所指定的 PV,则你应该首先预留 该存储卷。你可以将 PV 的 claimRef 字段设置为相关的 PersistentVolumeClaim 以确保其他 PVC 不会绑定到该 PV 卷。

apiVersion: v1
kind: PersistentVolume
metadata:
  name: foo-pv
spec:
  storageClassName: ""
  claimRef: # 预留给指定的PVC
    name: foo-pvc
    namespace: foo
  ...

如果你想要使用 claimPolicy 属性设置为 Retain 的 PersistentVolume 卷 时,包括你希望复用现有的 PV 卷时,这点是很有用的

2.7 扩充 PVC 申领

现在,对扩充 PVC 申领的支持默认处于被启用状态。你可以扩充以下类型的卷:

  • gcePersistentDisk
  • awsElasticBlockStore
  • Cinder
  • glusterfs
  • rbd
  • Azure File
  • Azure Disk
  • Portworx
  • FlexVolumes
  • CSI

只有当 PVC 的存储类中将 allowVolumeExpansion 设置为 true 时,你才可以扩充该 PVC 申领。

关于存储类将在后面篇章中专门讲

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: gluster-vol-default
provisioner: kubernetes.io/glusterfs
parameters:
  resturl: "http://192.168.10.100:8080"
  restuser: ""
  secretNamespace: ""
  secretName: ""
allowVolumeExpansion: true

如果要为某 PVC 请求较大的存储卷,可以编辑 PVC 对象,设置一个更大的尺寸值。 这一编辑操作会触发为下层 PersistentVolume 提供存储的卷的扩充。 Kubernetes 不会创建新的 PV 卷来满足此申领的请求。 与之相反,现有的卷会被调整大小。

2.7.1 重设包含文件系统的卷的大小

只有卷中包含的文件系统是 XFS、Ext3 或者 Ext4 时,你才可以重设卷的大小。

当卷中包含文件系统时,只有在 Pod 使用 ReadWrite 模式来使用 PVC 申领的 情况下才能重设其文件系统的大小。 文件系统扩充的操作或者是在 Pod 启动期间完成,或者在下层文件系统支持在线 扩充的前提下在 Pod 运行期间完成。

如果 FlexVolumes 的驱动将 RequiresFSResize 能力设置为 true,则该 FlexVolume 卷可以在 Pod 重启期间调整大小。

2.7.2 重设使用中 PVC 申领的大小

说明: Kubernetes 从 1.15 版本开始将调整使用中 PVC 申领大小这一能力作为 Beta 特性支持;该特性在 1.11 版本以来处于 Alpha 阶段。 ExpandInUsePersistentVolumes 特性必须被启用;在很多集群上,与此类似的 Beta 阶段的特性是自动启用的。 可参考特性门控 文档了解更多信息。

在这种情况下,你不需要删除和重建正在使用某现有 PVC 的 Pod 或 Deployment。 所有使用中的 PVC 在其文件系统被扩充之后,立即可供其 Pod 使用。 此功能特性对于没有被 Pod 或 Deployment 使用的 PVC 而言没有效果。 你必须在执行扩展操作之前创建一个使用该 PVC 的 Pod。

与其他卷类型类似,FlexVolume 卷也可以在被 Pod 使用期间执行扩充操作。

说明: FlexVolume 卷的重设大小只能在下层驱动支持重设大小的时候才可进行。
说明: 扩充 EBS 卷的操作非常耗时。同时还存在另一个配额限制: 每 6 小时只能执行一次(尺寸)修改操作。

2.7.3 处理扩充卷过程中的失败

如果扩充下层存储的操作失败,集群管理员可以手动地恢复 PVC 申领的状态并 取消重设大小的请求。否则,在没有管理员干预的情况下,控制器会反复重试 重设大小的操作。

  1. 将绑定到 PVC 申领的 PV 卷标记为 Retain 回收策略;
  2. 删除 PVC 对象。由于 PV 的回收策略为 Retain,我们不会在重建 PVC 时丢失数据。
  3. 删除 PV 规约中的 claimRef 项,这样新的 PVC 可以绑定到该卷。 这一操作会使得 PV 卷变为 “可用(Available)”
  4. 使用小于 PV 卷大小的尺寸重建 PVC,设置 PVC 的 volumeName 字段为 PV 卷的名称。 这一操作将把新的 PVC 对象绑定到现有的 PV 卷。
  5. 不要忘记恢复 PV 卷上设置的回收策略。

3. PV的类型

在这里插入图片描述

4. PV

4.1 理解PV

比如你要对接OSS文件存储,下次想换FastDFS,为了以后方便的转换,而不用修改大量代码,肯定要对文件存储抽一层接口,然后在用OSS、FastDFS分别实现该接口,方便快速转换

PV就可以理解为就是这个接口,PV就是存储系统的一个代理,并且封装了具体的调用、交互代码,不需要我们关注,直接面向Pv即可。

PV [持久化数据卷]: 用来屏蔽pod对底层物理存储介质的关联性。Pod不用直接和底层物理存储介质进行交互,不需要关心底层到底是如何存储的,pod只需要关联PV进行数据的挂载即可。
在这里插入图片描述

PV PVC关系:
在这里插入图片描述

4.2 实战演示

4.2.1 构建网络存储介质

我们用比较简单的nfs文件系统

确保nfs处于启动状态:
在这里插入图片描述

我们创建的PV会挂载在/opt/k8s/demo2和/opt/k8s/demo1目录下,确保nfs服务器上存在该目录:
在这里插入图片描述

4.2.2 创建PV持久化数据卷

先创建pv持久化数据卷(k8s资源对象),使用nfs网络存储设备挂载数据

  • 每个 PV 对象都包含 spec 部分和 status 部分,分别对应卷的规约和状态。 PersistentVolume 对象的名称必须是合法的 DNS 子域名.
  • 在集群中使用持久卷存储通常需要一些特定于具体卷类型的辅助程序。 在这个例子中,PersistentVolume 是 NFS 类型的,因此需要辅助程序 /sbin/mount.nfs 来支持挂载 NFS 文件系统
# vim pv1.yaml,构建第一个PV
apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv1
spec:
  capacity: # 容量属性
    storage: 5Gi #5g,要确保提供的磁盘空间大小够用
  accessModes: # 访问模式
    - ReadWriteMany # 卷可以被多个节点以读写方式挂载
   				    # ReadWriteOnce -- 卷可以被一个节点以读写方式挂载
   				    # ReadOnlyMany -- 卷可以被多个节点以只读方式挂载
  nfs: # 绑定的存储介质是nfs
    path: /opt/k8s/demo1
    server: 192.168.66.13

在这里插入图片描述

在这里插入图片描述

# vim pv2.yaml 构建第二个PV
apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv2
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteMany
  nfs: # 绑定了nfs
    path: /opt/k8s/demo2
    server: 192.168.66.13

在这里插入图片描述

在这里插入图片描述

执行创建持久化数据卷:

Kubectl apply -f my-pv1.yaml
Kubectl apply -f my-pv2.yaml

在这里插入图片描述

产生了2个持久化数据卷资源对象,说明了PV就是把持久化数据存储方式(物理设备)抽象成了k8s的资源对象。

在这里插入图片描述

每个卷会处于以下阶段(Phase)之一:

  • Available(可用)-- 卷是一个空闲资源,尚未绑定到任何申领;
  • Bound(已绑定)-- 该卷已经绑定到某申领;
  • Released(已释放)-- 所绑定的申领已被删除,但是资源尚未被集群回收;
  • Failed(失败)-- 卷的自动回收操作失败。

注意:pv持久化的数据卷通常都是由运维来进行维护的。开发更多是服务部署pod,pvc这块维护部署。

5. PVC

5.1 PVC特点

  • 访问模式
    申领在请求具有特定访问模式的存储时,使用与卷相同的访问模式约定。

  • 卷模式
    申领使用与卷相同的约定来表明是将卷作为文件系统还是块设备来使用。

  • 资源
    申领和 Pod 一样,也可以请求特定数量的资源。在这个上下文中,请求的资源是存储。 卷和申领都使用相同的资源模型。

  • 选择算符
    申领可以设置标签选择算符 来进一步过滤卷集合。只有标签与选择算符相匹配的卷能够绑定到申领上。 选择算符包含两个字段:

    • matchLabels - 卷必须包含带有此值的标
    • matchExpressions - 通过设定键(key)、值列表和操作符(operator) 来构造的需求。合法的操作符有 In、NotIn、Exists 和 DoesNotExist。

    来自 matchLabels 和 matchExpressions 的所有需求都按逻辑与的方式组合在一起。 这些需求都必须被满足才被视为匹配。

  • 类(关于存储类将在后面章节细讲
    申领可以通过为 storageClassName 属性设置 StorageClass 的名称来请求特定的存储类。 只有所请求的类的 PV 卷,即 storageClassName 值与 PVC 设置相同的 PV 卷, 才能绑定到 PVC 申领。

    PVC 申领不必一定要请求某个类。如果 PVC 的 storageClassName 属性值设置为 "", 则被视为要请求的是没有设置存储类的 PV 卷,因此这一 PVC 申领只能绑定到未设置 存储类的 PV 卷(未设置注解或者注解值为 “” 的 PersistentVolume(PV)对象在系统中不会被删除,因为这样做可能会引起数据丢失。 )

    未设置 storageClassName 的 PVC 与此大不相同,也会被集群作不同处理。 具体筛查方式取决于 DefaultStorageClass 准入控制器插件 是否被启用。

    • 如果准入控制器插件被启用,则管理员可以设置一个默认的 StorageClass。 所有未设置 storageClassName 的 PVC 都只能绑定到隶属于默认存储类的 PV 卷。 设置默认 StorageClass 的工作是通过将对应 StorageClass 对象的注解 storageclass.kubernetes.io/is-default-class 赋值为 true 来完成的。 如果管理员未设置默认存储类,集群对 PVC 创建的处理方式与未启用准入控制器插件 时相同。如果设定的默认存储类不止一个,准入控制插件会禁止所有创建 PVC 操作。
    • 如果准入控制器插件被关闭,则不存在默认 StorageClass 的说法。 所有未设置 storageClassName 的 PVC 都只能绑定到未设置存储类的 PV 卷。 在这种情况下,未设置 storageClassName 的 PVC 与 storageClassName 设置未为"" 的 PVC 的处理方式相同。

    取决于安装方法,默认的 StorageClass 可能在集群安装期间由插件管理器(Addon Manager)部署到集群中。

    当某 PVC 除了请求 StorageClass 之外还设置了 selector,则这两种需求会按 逻辑与关系处理:只有隶属于所请求类且带有所请求标签的 PV 才能绑定到 PVC。

    说明: 目前,设置了非空 selector 的 PVC 对象无法让集群为其动态供应 PV 卷。

    早前,Kubernetes 使用注解 volume.beta.kubernetes.io/storage-class 而不是 storageClassName 属性。这一注解目前仍然起作用,不过在将来的 Kubernetes 发布版本中该注解会被彻底废弃。

5.2 实战演示

使用申领作为卷
Pod 将申领作为卷来使用,并藉此访问存储资源。 申领必须位于使用它的 Pod 所在的同一名字空间内。 集群在 Pod 的名字空间中查找申领,并使用它来获得申领所使用的 PV 卷。 之后,卷会被挂载到宿主上并挂载到 Pod 中。

关于名字空间的说明
PersistentVolume 卷的绑定是排他性的。 由于 PersistentVolumeClaim 是名字空间作用域的对象,使用 “Many” 模式(ROX、RWX)来挂载申领的操作只能在同一名字空间内进行。


每个 PVC 对象都有 spec 和 status 部分,分别对应申领的规约和状态。 PersistentVolumeClaim 对象的名称必须是合法的 DNS 子域名.

创建pod,同时通过pvc选择一个合适的pv存储数据。

# vim pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: nginx
    image: nginx:latest
    ports:
    - containerPort: 80
    volumeMounts:
      - name: www
        mountPath: /usr/share/nginx/html # 把数据卷挂载到容器此目录下
  volumes:
    - name: www
      persistentVolumeClaim: # 上一节演示的是直接挂载nfs,现在这里挂载的是PVC
        claimName: my-pvc # 通过此名称关联相应的pvc
---
apiVersion: v1
kind: PersistentVolumeClaim #创建了一个PVC
metadata:
  name: my-pvc
spec:    # spec所描述的内容: 表示向pv申请一个合适的存储介质
  accessModes:
    - ReadWriteMany # 访问模式
  resources:
    requests:
      storage: 5Gi # 访问大小
# PVC会通过访问模式、访问大小 去匹配PV

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

pod ,pvc ,pv ,nfs 关联关系:
在这里插入图片描述

验证,容器中对应目录下创建文件:
在这里插入图片描述

nfs服务器上检查是否存在该文件:
在这里插入图片描述

总结

  • PV的意义在于对物理设备进行高层次的抽象,转换成k8s的资源对象,封装了对物理设备的交互
  • PVC的意义在于管理PV,因为项目中PV的数量会有很多很多,维护就比较麻烦,不知道选择哪一个去绑定,选择的工作就交给PVC

猜你喜欢

转载自blog.csdn.net/weixin_41947378/article/details/111407594