Kubernetes高级概念和应用 之K8s存储解耦PVC和PV
Kubernetes PV和PVC的区别?
在Kubernetes中,PV(Persistent Volume)和PVC(Persistent Volume Claim)是用于持久化存储的两个核心概念。它们之间的区别如下:
Persistent Volume(PV):
- PV 是一种集群级别的资源对象,它代表着集群中的一个持久化存储卷。
- PV 独立于任何特定的Pod,可以在多个Pod之间共享使用。
- PV 需要由集群管理员预先创建和配置,以供用户使用。
- PV 定义了持久化存储的属性,如存储容量、访问模式(ReadWriteOnce、ReadOnlyMany、ReadWriteMany)、存储类别等。
Persistent Volume Claim(PVC):
- PVC 是Pod对PV的请求,它声明了Pod需要的持久化存储资源。
- PVC 是在Pod级别定义的,并与特定的Pod相关联。
- PVC 可以根据应用程序的需要灵活地创建和删除,无需干预集群管理员。
- PVC 指定了对存储资源的需求,如存储容量、访问模式等。
PV 和 PVC 之间的关系:
- 用户通过创建 PVC 来请求一定数量和类型的存储资源。
- Kubernetes 调度器会寻找匹配这些要求的 PV,并将其绑定到 PVC 上。
- 一旦 PV 和 PVC 绑定成功,PVC 就可以在 Pod 的配置中引用它,从而将持久化存储挂载到 Pod 中。
简而言之,PV 是一种集群级别的资源,由管理员配置,而 PVC 是在Pod级别定义的资源请求。PV 和 PVC 之间的绑定为Pod提供了持久化存储,并允许多个Pod共享同一个PV,提供了灵活且可伸缩的存储解决方案。
PVC的引入实现了Volume和持久化存储的具体实现 达到了解耦,另外还实现了职责分离,Volume和PVC由Pod的开发来定义,提出存储的需求,而不关心存储的具体实现; PV或Storange Class由K8s管理员负责
Pod可以关联Volume(Pod中的容器可以挂载Volume),Volume可以对接引用PVC,PVC可以绑定PV,PV可以对接具体的物理存储。
这节课我们讲一下K8S里的动态卷和静态卷的概念,这两个概念容易搞混。在讲之前,我们先说一下学习的基本套路,一般打开官方文档,特别是Tasks部分写的比较好,可直接实操验证特性。当然在此之前需要有环境,可以用minikube在本地跑一个K8S集群。
一般我们不会在应用程序的配置文件中使用ConfigMap,因为ConfigMap在更新后应用不会自动获取新配置。我们通常使用Apollo、Consul等集中式配置系统。ConfigMap和Secret我们一般只在一些基础组件如EFK、Prometheus等场景下使用。
对于无状态应用,我们可以用emptyDir这种临时共享存储目录。对于有状态应用,就需要用到PV和PVC了。PV可以理解为一块盘,通过NFS等后端存储系统挂载到节点上的一个目录。PVC用于管理和使用PV,可通过名字或标签绑定所需PV。
先看静态卷的例子。我们需要先创建一个PV,指定存储capability、path等,用storageClassName作为标识。然后创建PVC,通过storageClassName绑定所需的PV。如果没有对应的StorageClass,PVC会一直处于Pending状态报错。创建好后Pod中就可以通过Volume挂载该PVC从而使用对应存储了。
在这个示例中,我们先创建了一个PV,然后创建PVC绑定该PV。发现PVC报错是因为我们的StorageClass名称不正确,修复后就可以了。
接下来讲动态卷。与静态不同,动态不需要预先创建PV,而是通过StorageClass动态创建所需的PV。PVC在指定StorageClass后,会动态创建对应的PV,PV名称是随机的。每次删除PVC后,对应的动态PV也会根据策略被删除或保留。
在动态卷的示例中,我们直接创建PVC指定StorageClass,就会动态创建出随机命名的PV,而不需要预先创建PV资源。
关于PV,我们还需要注意status、reclaim policy和access mode等参数的作用。Status表示PV当前状态;access mode分为单节点读写、多节点读写和多节点只读等;reclaim policy包括Retain、Recycle和Delete等,控制PV删除后数据是否被保留。
如果需要固定存储位置的应用,如CI/CD构件、数据库等,需要使用静态PV,预先准备好存储资源。而对于通用应用,使用动态PV就更灵活方便了。
最后以AWS EBS为例,讲解了如何使用CSI驱动通过动态或静态方式将EBS卷挂载为PV的用法。
总之,对有状态应用的数据持久化,我们需要合理选择静态PV还是动态PV,并正确设置相关参数,以满足不同需求,这是管理有状态应用的关键。
emptyDir和PV/PVC有什么联系和区别?各用于什么场景?
emptyDir和PV/PVC虽然都是Kubernetes中用于存储的资源对象,但它们有一些区别和不同的使用场景:
emptyDir:
- 是一种临时存储卷,生命周期与Pod相同
- 可以用作临时目录存放一些临时数据,供同一Pod内的容器共享
- 当Pod被删除时,emptyDir卷中的数据也会被一起删除
- 常用于一些临时缓存、磁盘临时存放等场景
- 不适合持久化数据存储
PV/PVC:
- PV(Persistent Volume)表示一块外部的存储设备
- PVC(Persistent Volume Claim)是用户对存储资源的请求
- PVC通过绑定合适的PV来满足存储需求
- PV和PVC可以在Pod重启或者调度到其他节点时,实现数据持久化
- 适用于有状态应用需要持久化数据的场景
两者的主要区别:
生命周期不同
- emptyDir生命周期与Pod一致,临时性的
- PV/PVC的生命周期独立于Pod,属于集群资源
数据持久性不同
- emptyDir在Pod删除时会一起删除,不能持久化数据
- PV/PVC数据可以持久化,即使Pod被删除/迁移也不会丢失
存储性质不同
- emptyDir适合一些临时缓存、数据共享等
- PV/PVC更多用于持久化数据存储,如数据库、文件系统等
因此:
- 如果只是临时需要在同一Pod内的容器之间共享一些数据,可以用emptyDir
- 如果需要持久化数据,为有状态应用提供持久数据存储,应该使用PV/PVC
k8s中动态卷和静态卷是什么?
K8s中的动态卷和静态卷指的是使用PV/PVC资源对象实现持久化存储的两种方式:
静态卷(Static Provisioning):
- 集群管理员需要预先手动创建一些PV资源对象
- 创建PV时需要指定存储的详细信息,如存储类型、容量、访问模式等
- 创建PVC时,需要指定绑定哪个具体的PV
- 优点是PV的创建细节可控,但需要预先配置存储资源
动态卷(Dynamic Provisioning):
- 无需预先创建PV资源对象
- 集群管理员需要预先创建好”StorageClass”对象,定义存储的类型和配置
- 创建PVC时,直接指定StorageClass即可
- K8s会自动调用相应的存储插件(StorageProvisionor)动态创建PV,并绑定给PVC
- 优点是使用更加自动化,不需要预先创建PV资源
两者的区别主要在于PV对象的创建方式:
- 静态卷需要集群管理员预先手动创建PV
- 动态卷由K8s根据PVC请求动态自动创建PV
使用场景:
- 静态卷适用于存储资源有限并且需要细致控制的场景
- 动态卷则更加自动化,适用于公有云或灵活分配存储资源的环境
总的来说,动态卷的使用更加方便自动化,是推荐的做法;但在某些场景下静态卷仍然有其存在的价值和用途。
20250226
20250422
您的分析是正确的。在您提供的部署配置中,Pod 确实只能有一个副本,这主要是因为您使用了 PersistentVolumeClaim (PVC)。
当您的部署使用 PVC 时,是否能够支持多个副本取决于 PVC 的访问模式(accessModes):
- 如果 PVC 的访问模式是
ReadWriteOnce (RWO),那么它只能被一个节点上的一个 Pod 挂载为读写模式,因此无法支持多个副本。 - 如果 PVC 的访问模式是
ReadOnlyMany (ROX),则可以被多个节点的多个 Pod 以只读方式挂载。 - 如果 PVC 的访问模式是
ReadWriteMany (RWX),则可以被多个节点的多个 Pod 以读写方式挂载,这种情况下可以支持多个副本。
在您的配置中,使用了名为 “taskon-test-download” 的 PVC,但没有显示其访问模式。如果它是 RWO 模式(这也是许多存储类型的默认模式),那么确实只能支持单个 Pod。
如果您希望扩展到多个副本,可以考虑以下选项:
- 将 PVC 的访问模式更改为
ReadWriteMany(需要存储支持此模式,如 NFS) - 使用共享存储服务如 S3 兼容存储
- 根据应用需求,考虑是否可以将状态从应用中分离出来
要查看 PVC 的访问模式,可以运行:
1 | kubectl get pvc taskon-test-download -n taskon-test -o yaml |
我执行后的返回:
1 | apiVersion: v1 |
您的分析是完全正确的。从您提供的 PVC 配置可以看到,这个 PVC 的访问模式是 ReadWriteOnce:
1 | spec: |
这意味着这个 PVC 只能被挂载到一个节点上的一个 Pod,所以您的部署确实无法扩展到多个副本。这就是为什么您的部署中 replicas: 1 是必须的限制。
如果您想要扩展部署到多个副本,您有几个选项:
使用支持 ReadWriteMany 的存储类:
- 如 NFS, GlusterFS, Ceph RBD 等
- 腾讯云上可能提供一些支持 ReadWriteMany 的存储解决方案
使用对象存储:
- 如腾讯云 COS(对象存储)
- 应用程序需要修改为使用对象存储 API 而不是文件系统
数据分片:
- 每个副本使用自己的 PVC
- 需要在应用层实现数据分片逻辑
有状态应用考虑使用 StatefulSet:
- 为每个 Pod 提供独立的存储
- 适合需要唯一网络标识符的分布式应用
如果您必须保持当前的存储架构,那么确实只能使用单个 Pod。这是云原生应用中常见的限制,特别是在使用块存储(如腾讯云的 CBS)时。
现在使用的腾讯云 云硬盘CBS是只能 单机读写
另外几种可以多机读写
ReadWriteMany
@fliter 如果是多POD/容器的数据共享场景,推荐您使用CFS(文件存储),价格可以根据具体的使用需求使用价格计算器来参考下:https://buy.cloud.tencent.com/price/cfs/calculator
下次可以考虑使用另外两种
但貌似 文件存储需要开通, COS需要在集群里安装插件~
原文链接: https://dashen.tech/2024/12/24/K8s存储解耦PVC和PV/
版权声明: 转载请注明出处.