minikube Persistent Volumes 完全指南:hostPath 持久化、动态供给与 CSI Hostpath Driver
【免费下载链接】minikubeRun Kubernetes locally项目地址: https://gitcode.com/gh_mirrors/mi/minikube
导读
minikube 开箱即用地支持 Kubernetes 的 PersistentVolume 展开,结合仓库源码详解三件事:哪些目录在重启后仍然保留数据、如何手工创建 hostPath 静态 PV、以及 minikube 内置的存储动态供给控制器与 CSI Hostpath Driver 插件的工作原理,让你在本地开发环境里放心地把数据库、缓存等有状态应用跑起来。
一、开箱即用的 hostPath 持久卷
minikube 原生支持hostPath类型的 PersistentVolume,无需任何额外配置。这类 PV 的本质是:把宿主机(minikube VM 内部)的一个目录,以持久卷的形式暴露给集群中的 Pod。因为 minikube 本身运行在本地,所以hostPath是成本最低、最贴合本地开发场景的存储方案。
下面是官方文档给出的一个持久化数据到/data目录的静态 PV 配置示例:
apiVersion: v1 kind: PersistentVolume metadata: name: pv0001 spec: accessModes: - ReadWriteOnce capacity: storage: 5Gi hostPath: path: /data/pv0001/使用时通过kubectl apply -f提交该清单,再创建引用它的 PVC(PersistentVolumeClaim)即可。这种"静态供给"方式适合需要精确控制数据落点(例如指定某个固定路径)的场景。
注意:
hostPath属于节点级存储,PV 与具体节点绑定。在单节点的 minikube 集群中这没有影响;但在多节点集群中,默认的 hostPath 供给器存在限制(详见下文"CSI Hostpath Driver"一节)。
二、mount、持久化与 minikube 主机:哪些目录会保留数据
理解 minikube 的持久化,关键要知道 VM 里哪些目录"重启不丢"。minikube 配置为持久化保存在以下目录中的文件(这些目录在 minikube VM 中创建;如果你使用--driver=none在裸机/本机运行时,则直接位于你的 localhost 上):
| 目录 | 说明 |
|---|---|
/data* | 数据目录,适合存放 PV 后端数据 |
/var/lib/minikube | minikube 自身运行时数据 |
/var/lib/docker | Docker 守护进程数据(镜像、容器层等) |
/var/lib/containerd | containerd 运行时数据 |
/var/lib/buildkit | BuildKit 构建缓存 |
/var/lib/containers | 容器/镜像相关数据 |
/tmp/hostpath_pv* | hostPath PV 的存放目录之一 |
/tmp/hostpath-provisioner* | 内置存储供给器创建 PV 后端目录的根目录 |
* 标记的目录是另一个目录的挂载点,实际数据存储在/var之下或独立的数据磁盘上。
重要提醒:除上述目录外,minikube VM 中其他目录中的文件在重启后可能丢失。如果你希望自己的数据跨minikube stop/minikube start(甚至跨机器删除重建)存活,务必把数据放到上表目录中,尤其是/data与/tmp/hostpath_pv。
源码印证:供给器默认写入/tmp/hostpath-provisioner
从源码结构看,内置存储供给器创建 PV 后端目录的默认根路径正是上表中的/tmp/hostpath-provisioner:
- cmd/storage-provisioner/main.go 中声明
var pvDir = "/tmp/hostpath-provisioner",随后调用storage.StartStorageProvisioner(pvDir)启动供给服务; - 供给器 Pod 的部署清单 deploy/addons/storage-provisioner/storage-provisioner.yaml.tmpl 中,将宿主机的
/tmp目录以hostPath卷挂载进容器(mountPath: /tmp),使供给器写入的文件直接落在 VM 的持久化区域内。
这也解释了为什么文档把/tmp/hostpath-provisioner列入持久化目录——动态供给出的每一个 PV 后端目录都创建在它下面。
三、通过挂载主机目录实现持久化
除了在 VM 内部使用静态 PV,你还可以把宿主机(物理机)上的某个文件夹挂载进 minikube VM,再基于挂载目录创建 PV,实现"本地代码/数据目录 ↔ 集群卷"的互通。这是本地开发中最常用的持久化手段之一。
minikube 提供mount命令,例如把宿主机的/home/user/data挂载到 VM 的/mnt/data:
minikube mount /home/user/data:/mnt/data挂载完成后,/mnt/data同样属于持久化范畴(数据真实存在于宿主机),你可以:
apiVersion: v1 kind: PersistentVolume metadata: name: pv-mounted spec: accessModes: - ReadWriteOnce capacity: storage: 10Gi hostPath: path: /mnt/data创建该 PV 后,集群中的 Pod 即可通过 PVC 绑定它。由于底层就是宿主机的真实目录,你甚至可以直接在 IDE 里编辑这些文件,做到"本地文件即集群数据"。
四、动态供给:内置 Storage Provisioner 工作原理
minikube 不仅支持静态 PV,还内置了一个非常简单、规范的动态存储控制器实现,它随集群部署一起运行,负责按需供给hostPath卷(替代早期 Kubernetes 内置的 in-tree hostPath provider)。它演示了"如何把一个自定义存储控制器轻松接入 Kubernetes 作为系统存储组件",并能为 Pod 动态提供持久化存储,方便你测试 Pod 在挂载持久存储时的行为。
4.1 这不是 CSI
需要特别强调:minikube 内置供给器不是基于 CSI 的存储提供方。它的工作方式更朴素——当控制器发现存在未满足的存储请求(PVC)时,动态地声明一个hostpath类型的 PersistentVolume 对象来满足它。也就是说,它不实现 CSI 的CreateVolume/DeleteVolumegRPC 接口,而是直接通过 Kubernetes API 创建 PV 资源。
4.2 供给器标识与核心流程
内置供给器实现在 pkg/storage/storage_provisioner.go,核心设计如下:
- 供给器名称:
const provisionerName = "k8s.io/minikube-hostpath",它与 StorageClass 中的provisioner字段一一对应; - 身份标识:
hostPathProvisioner结构体持有一个identity types.UID(通过uuid.NewUUID()生成),用于标识"本供给器创建的 PV",并在删除时做归属校验; - 供给(Provision):收到 PVC 请求后,在
pvDir(即/tmp/hostpath-provisioner)下创建<namespace>/<pvc-name>目录,显式chmod 0777(不受 umask 影响),然后构造一个PersistentVolume对象返回:- 容量来自 PVC 的资源请求(
options.PVC.Spec.Resources.Requests[core.ResourceStorage]); accessModes沿用 PVC 声明;reclaimPolicy取自 StorageClass;- 卷类型为
HostPath,路径指向刚创建的目录; - 并在 PV 上打上
hostPathProvisionerIdentity注解;
- 容量来自 PVC 的资源请求(
- 删除(Delete):删除 PV 时先校验
hostPathProvisionerIdentity注解是否与自身身份一致(不一致则返回controller.IgnoredError交给控制器忽略),一致则os.RemoveAll清理后端目录; - 启动(StartStorageProvisioner):通过
rest.InClusterConfig()获取集群内配置,创建 clientset,读取服务端版本,然后用controller.NewProvisionController(clientset, provisionerName, hostPathProvisioner, serverVersion.GitVersion)启动供给控制器并pc.Run(context.Background())常驻运行。
4.3 部署形态与默认 StorageClass
供给器以独立 Pod 形式部署在kube-system命名空间,清单见 deploy/addons/storage-provisioner/storage-provisioner.yaml.tmpl:
- 使用
storage-provisionerServiceAccount,并通过 ClusterRoleBinding 绑定system:persistent-volume-provisioner集群角色; hostNetwork: true,容器直接以宿主机网络运行,命令为/storage-provisioner;- 以
hostPath方式把宿主机/tmp挂载到容器/tmp,供供给器在 VM 持久化目录内创建 PV 后端目录。
同时,minikube 会创建一个名为standard的默认 StorageClass,见 deploy/addons/storageclass/storageclass.yaml:
kind: StorageClass apiVersion: storage.k8s.io/v1 metadata: name: standard annotations: storageclass.kubernetes.io/is-default-class: "true" provisioner: k8s.io/minikube-hostpath由于它被标记为默认 StorageClass,不指定storageClassName的 PVC 会自动走动态供给,由k8s.io/minikube-hostpath供给器创建 hostPath PV——这正是本地开发中最省事的用法:
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mypvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi提交后无需关心 PV 如何创建,kubectl get pv即可看到自动生成的后端卷。
4.4 相关 addon 与行为验证
storage-provisioner与default-storageclass都是可开关的 addon,注册于 pkg/addons/config.go;- pkg/addons/addons_storage_classes.go 展示了"切换默认 StorageClass"的完整逻辑:
defaultStorageClassProvisioner = "standard",而storage-provisioner-rancheraddon 则使用local-path作为供给器,启用后通过storageclass.SetDefaultStorageClass把对应类标记为默认; - 集成测试 test/integration/addons_test.go 中也包含对 CSI hostpath 驱动的端到端验证:创建 PVC、挂载 PV 的 Pod、创建快照、再从快照恢复 PVC 与 Pod(见其中
validateCSIDriverAndSnapshots测试)。
五、CSI Hostpath Driver addon:多节点与快照
当单节点的内置供给器无法满足需求时,minikube 还提供了CSI Hostpath Driveraddon(对应教程见 site/content/en/docs/tutorials/volume_snapshots_and_csi.md),它带来两个关键能力:
- 多节点集群支持:默认的 hostPath 供给器不支持多节点集群(详见 site/content/en/docs/tutorials/multi_node.md 的说明)。而
csi-hostpath-driveraddon 以 DaemonSet 形式在每个节点上运行 hostpath 驱动,从而支持在多节点集群中供给与声明卷; - 卷快照(Volume Snapshot):内置供给器不实现 CSI 接口,因此无法创建/处理快照;CSI 驱动则补上了这一能力。
启用方式:
minikube addons enable volumesnapshots minikube addons enable csi-hostpath-drivervolumesnapshotsaddon 负责部署快照所需的 CRD 与 Volume Snapshot Controller(默认禁用);csi-hostpath-driveraddon 将驱动资源部署到kube-system命名空间,驱动名为hostpath.csi.k8s.io,并创建一个专用 StorageClasscsi-hostpath-sc(清单见 deploy/addons/csi-hostpath-driver/deploy/csi-hostpath-storageclass.yaml,provisioner: hostpath.csi.k8s.io),PVC 需要显式引用该 StorageClass:- 在 pkg/addons/config.go 中,
csi-hostpath-driveraddon 带有isVolumesnapshotsEnabled校验,即启用它之前需要先启用volumesnapshots;
- 在 pkg/addons/config.go 中,
- CSI 驱动创建的所有持久卷数据存放在 minikube 主机的
/var/lib/csi-hostpath-data/目录中。
如需让 CSI 类成为默认存储,可以参考教程中的做法:禁用内置供给器相关 addon,再把csi-hostpath-sc打上默认类注解:
minikube addons disable storage-provisioner minikube addons disable default-storageclass kubectl patch storageclass csi-hostpath-sc -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'六、总结与选型建议
| 场景 | 推荐方案 | 数据落点 |
|---|---|---|
| 单节点、快速验证有状态应用 | 静态 hostPath PV(写入/data等持久化目录) | VM 内持久化目录 |
| 单节点、想省去 PV 管理 | 默认 StorageClassstandard动态供给 | /tmp/hostpath-provisioner/<ns>/<pvc> |
| 需要与宿主机文件互通 | minikube mount+ hostPath PV | 宿主机真实目录 |
| 多节点集群 | csi-hostpath-driveraddon | /var/lib/csi-hostpath-data/ |
| 需要卷快照/恢复 | volumesnapshots+csi-hostpath-driver | /var/lib/csi-hostpath-data/ |
总而言之,minikube 的持久化体系围绕"VM 内持久化目录 + hostPath 卷 + 内置动态供给控制器"构建:静态 PV 适合精确控制,standardStorageClass 让 PVC 即申即得,而 CSI Hostpath Driver 则把能力延伸到多节点与快照场景。只要把数据放到文档列出的持久化目录内,你的本地集群数据就能在重启、重建之间安稳保留。
【免费下载链接】minikubeRun Kubernetes locally项目地址: https://gitcode.com/gh_mirrors/mi/minikube
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考