Kubernetes本地持久化存储:Local PV的配置与限制

Local PV为Kubernetes工作负载提供高IOPS、低延迟的本地存储,但受节点故障影响。本文解析其配置步骤、调度约束与适用场景,帮你判断是否该用。

Kubernetes本地持久化存储:Local PV的配置与限制
封面图:ZuCDN · ZuCDN 原创

当你的Kubernetes应用需要高IOPS、低延迟的存储时,本地持久化存储(Local PV)往往是首选。它直接将宿主机上的目录或块设备作为持久卷,绕过了网络存储的开销。但这份性能优势并非没有代价——节点故障意味着数据丢失,调度也受到严格约束。本文将从典型场景出发,带你走一遍Local PV的配置流程,并剖析其限制与适用边界。

场景一:数据库需要极低延迟

假设你运行一个Cassandra集群,每个节点需要本地SSD来保证写入性能。使用网络存储(如NFS)时,网络延迟和带宽会成为瓶颈。此时,Local PV能提供接近裸机的性能。但你必须接受:数据只存在于特定节点,节点损坏则数据丢失。因此,Local PV适合有状态应用且自带副本机制的场景,如Cassandra、Etcd,而非单点数据库。

前置条件:静态配置与节点亲和

Local PV需要你预先在节点上准备存储路径,比如挂载的SSD目录 /mnt/disks/ssd1。Kubernetes不会自动创建这些路径。配置Local PV的关键是设置 nodeAffinity,确保PV只会被调度到指定节点。这是因为PV绑定到具体节点的路径,若Pod调度到其他节点,数据将不可用。

步骤一:准备本地存储

在目标节点上创建目录并挂载存储设备。例如,将SSD分区挂载到 /mnt/disks/ssd1。为避免与系统分区混淆,建议使用独立磁盘并明确挂载点。Kubernetes官方文档建议使用 mount 命令或 /etc/fstab 持久化挂载。

步骤二:定义StorageClass

创建一个StorageClass,指定 provisioner: kubernetes.io/no-provisioner,表示静态配置,不动态创建PV。这样PVC可以绑定到预先创建的PV上。示例:

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

volumeBindingMode: WaitForFirstConsumer 是推荐设置,它延迟PV绑定直到Pod调度完成,这样调度器能考虑节点资源,避免绑定到错误节点。

步骤三:创建Local PV

为每个节点的存储路径创建PV。注意 nodeAffinity 必须匹配节点标签。例如:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: local-pv-ssd1
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

这里使用 Retain 回收策略,防止删除PVC时自动清理数据,因为本地存储清理很危险。

步骤四:使用PVC与Pod

创建PVC请求存储,然后创建Pod。由于 WaitForFirstConsumer,PVC绑定会等待Pod调度。Pod必须调度到PV节点,否则PVC会Pending。确保Pod的调度约束与PV的 nodeAffinity 一致。

限制与失败条件

Local PV的核心限制是节点故障导致数据丢失。此外,它不支持动态配置,需要手动管理PV生命周期;无法跨节点迁移,Pod重建后仍被调度到原节点;且仅支持 ReadWriteOnce 访问模式,不支持共享访问。若Pod被驱逐或节点宕机,数据恢复困难,必须依赖应用层复制。

常见误区

误区一:认为Local PV是持久化的万能解。实际上,它只适合高性能场景,且必须接受数据本地性。误区二:忽略 nodeAffinity,导致PV调度失败。误区三:使用 Delete 回收策略,删除PVC时可能误删本地数据,应使用 Retain

适用条件与不确定性

Local PV适合对延迟敏感、数据可复制的有状态工作负载,如分布式数据库。如果你的应用需要跨节点高可用,或数据不能丢失,应使用网络存储或分布式存储。Kubernetes官方文档强调,Local PV的设计目标是性能,而非持久性。实际性能取决于硬件和配置,建议进行基准测试。

参考资料

延伸阅读