4、本地存储方案:HostPath与Local PV

聊到云原生存储,很多人第一反应就是分布式存储、Ceph、Longhorn这些高大上的东西。但说实话,我做了这么多年存储架构,本地存储反而是我用的最多的方案之一。为什么?因为它简单、直接、性能好。

今天我们就来聊聊Kubernetes里的两种本地存储方案:HostPathLocal PV。别看它们都是本地存储,但用法和坑点完全不同。

4.1 HostPath:最直接的本地存储

HostPath,说白了就是把宿主机上的一个目录挂载到Pod里。这是Kubernetes里最原始的存储方式之一。

核心概念:Pod直接访问宿主机的文件系统,绕过Kubernetes的存储抽象层。

4.1.1 HostPath的使用方式

我习惯把HostPath用在一些特殊场景,比如读取宿主机日志、访问Docker守护进程的socket。来看个例子:

apiVersion: v1
kind: Pod
metadata:
  name: hostpath-example
spec:
  containers:
  - name: test-container
    image: nginx
    volumeMounts:
    - name: host-volume
      mountPath: /data
  volumes:
  - name: host-volume
    hostPath:
      path: /var/log
      type: Directory

这里要注意type字段。我刚开始用的时候没注意这个,结果Pod启动失败。type有几种取值:

type值 说明 我踩过的坑
DirectoryOrCreate 目录不存在就创建 权限问题,创建出来的目录可能权限不对
Directory 目录必须存在 Pod调度到没有该目录的节点上就挂了
FileOrCreate 文件不存在就创建 文件创建后不会自动清理
File 文件必须存在 跟Directory类似,调度问题

⚠️ 重要警告:HostPath存在严重的安全风险。Pod可以访问宿主机上的任何目录,包括系统敏感文件。我曾经见过一个团队因为HostPath配置不当,导致Pod能读取到宿主机上的/etc/shadow文件。

4.1.2 HostPath的优缺点

优点:

  • 配置简单,一行YAML搞定
  • 性能最好,没有中间层开销
  • 适合调试和测试场景

缺点:

  • Pod调度不灵活,必须调度到指定节点
  • 数据不隔离,Pod之间可能互相影响
  • Pod删除后数据还在,需要手动清理
  • 安全风险高,容易越权访问

4.2 Local PV:更专业的本地存储

Local PV是Kubernetes 1.14之后引入的正式特性。它解决了HostPath的一些痛点,但又不是完全替代关系。

核心概念:Local PV通过PV/PVC机制管理本地存储,让Kubernetes感知到节点上的本地磁盘。

4.2.1 Local PV的工作原理

Local PV的工作流程是这样的:

  1. 管理员在节点上准备好本地磁盘或目录
  2. 创建StorageClass,指定provisioner: kubernetes.io/no-provisioner
  3. 手动创建PV,绑定到具体节点
  4. 用户创建PVC,Kubernetes自动绑定到合适的PV

来看个完整的例子:

# 1. 创建StorageClass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer

---
# 2. 创建PV
apiVersion: v1
kind: PersistentVolume
metadata:
  name: local-pv-1
spec:
  capacity:
    storage: 100Gi
  volumeMode: Filesystem
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: local-storage
  local:
    path: /mnt/disks/ssd1
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - node-1

💡 我的经验:这里volumeBindingMode: WaitForFirstConsumer很关键。它告诉Kubernetes:等Pod创建时再决定调度到哪个节点。这样可以避免Pod被调度到没有对应本地盘的节点上。

4.2.2 Local PV的优缺点

优点:

  • 性能接近裸盘,没有网络开销
  • 通过PV/PVC机制管理,更规范
  • 支持节点亲和性,调度更智能
  • 数据生命周期管理更完善

缺点:

  • 配置相对复杂,需要手动创建PV
  • 节点故障时数据丢失风险高
  • 不支持动态扩容
  • 备份和迁移比较麻烦

4.3 适用场景分析

说了这么多,到底什么时候用HostPath,什么时候用Local PV?我根据自己的项目经验,总结了几条原则:

场景 推荐方案 原因
调试和测试 HostPath 简单快速,用完即弃
读取宿主机日志 HostPath 需要直接访问宿主机文件系统
高性能数据库 Local PV 需要稳定的磁盘性能和规范管理
有状态中间件 Local PV 需要持久化数据和节点亲和性
临时缓存 HostPath 数据不重要,追求性能
生产环境关键应用 Local PV + 备份 需要数据可靠性和可管理性

我的建议:生产环境尽量用Local PV。虽然配置麻烦点,但管理起来更规范。HostPath更适合开发测试环境,或者一些特殊的运维场景。

4.4 避坑指南

做本地存储这么多年,我踩过的坑不少。分享几个典型的:

⚠️ 我曾经遇到的一个坑:用HostPath挂载了宿主机上的一个目录,结果Pod被调度到另一个节点上,数据全丢了。后来我才意识到,HostPath不感知节点,Pod调度时不会考虑数据位置。

其他常见问题:

  • 磁盘空间不足:本地存储没有自动扩容机制,需要提前规划好容量
  • 节点故障恢复:节点挂了,本地数据就丢了,需要配合应用层复制
  • 权限问题:HostPath挂载的目录,Pod里的进程可能没有写入权限
  • 清理问题:Pod删除后,HostPath的数据不会自动清理,需要手动处理

4.5 总结

本地存储方案,说白了就是用空间换性能。HostPath和Local PV各有各的适用场景,没有绝对的好坏。

我个人习惯:

  • 开发测试用HostPath,省事
  • 生产环境用Local PV,规范
  • 关键数据一定要做备份,别指望本地存储能保你平安

嗯,本地存储就聊这么多。下一章我们聊聊网络存储方案,那又是另一个世界了。