注意:仅在 v1.7 + 中支持,并从 v1.10 开始升级为 beta 版本。

本地数据卷(Local Volume)代表一个本地存储设备,比如磁盘、分区或者目录等。主要的应用场景包括分布式存储和数据库等需要高性能和高可靠性的环境里。本地数据卷同时支持块设备和文件系统,通过 spec.local.path 指定;但对于文件系统来说,kubernetes 并不会限制该目录可以使用的存储空间大小。

本地数据卷只能以静态创建的 PV 使用。相对于 HostPath,本地数据卷可以直接以持久化的方式使用(它总是通过 NodeAffinity 调度在某个指定的节点上)。

另外,社区还提供了一个 local-volume-provisioner,用于自动创建和清理本地数据卷。

示例

StorageClass

  1. kind: StorageClass
  2. apiVersion: storage.k8s.io/v1
  3. metadata:
  4. name: local-storage
  5. provisioner: kubernetes.io/no-provisioner
  6. volumeBindingMode: WaitForFirstConsumer

创建一个调度到 hostname 为 example-node 的本地数据卷:

  1. # For kubernetes v1.10
  2. apiVersion: v1
  3. kind: PersistentVolume
  4. metadata:
  5. name: example-local-pv
  6. spec:
  7. capacity:
  8. storage: 100Gi
  9. accessModes:
  10. - ReadWriteOnce
  11. persistentVolumeReclaimPolicy: Delete
  12. storageClassName: local-storage
  13. local:
  14. path: /mnt/disks/ssd1
  15. nodeAffinity:
  16. required:
  17. nodeSelectorTerms:
  18. - matchExpressions:
  19. - key: kubernetes.io/hostname
  20. operator: In
  21. values:
  22. - example-node
  1. # For kubernetes v1.7-1.9
  2. apiVersion: v1
  3. kind: PersistentVolume
  4. metadata:
  5. name: example-local-pv
  6. annotations:
  7. "volume.alpha.kubernetes.io/node-affinity": '{
  8. "requiredDuringSchedulingIgnoredDuringExecution": {
  9. "nodeSelectorTerms": [
  10. { "matchExpressions": [
  11. { "key": "kubernetes.io/hostname",
  12. "operator": "In",
  13. "values": ["example-node"]
  14. }
  15. ]}
  16. ]}
  17. }',
  18. spec:
  19. capacity:
  20. storage: 5Gi
  21. accessModes:
  22. - ReadWriteOnce
  23. persistentVolumeReclaimPolicy: Delete
  24. storageClassName: local-storage
  25. local:
  26. path: /mnt/disks/ssd1

创建 PVC:

  1. kind: PersistentVolumeClaim
  2. apiVersion: v1
  3. metadata:
  4. name: example-local-claim
  5. spec:
  6. accessModes:
  7. - ReadWriteOnce
  8. resources:
  9. requests:
  10. storage: 5Gi
  11. storageClassName: local-storage

创建 Pod,引用 PVC:

  1. kind: Pod
  2. apiVersion: v1
  3. metadata:
  4. name: mypod
  5. spec:
  6. containers:
  7. - name: myfrontend
  8. image: nginx
  9. volumeMounts:
  10. - mountPath: "/var/www/html"
  11. name: mypd
  12. volumes:
  13. - name: mypd
  14. persistentVolumeClaim:
  15. claimName: example-local-claim

限制

  • 暂不支持一个 Pod 绑定多个本地数据卷的 PVC(计划 v1.9 支持)
  • 有可能导致调度冲突,比如 CPU 或者内存资源不足(计划 v1.9 增强)
  • 外部 Provisoner 在启动后无法正确检测挂载点的空间大小(需要 Mount Propagation,计划 v1.9 支持)

最佳实践

  • 推荐为每个存储卷分配独立的磁盘,以便隔离 IO 请求
  • 推荐为每个存储卷分配独立的分区,以便隔离存储空间
  • 避免重新创建同名的 Node,否则会导致新 Node 无法识别已绑定旧 Node 的 PV
  • 推荐使用 UUID 而不是文件路径,以避免文件路径误配的问题
  • 对于不带文件系统的块存储,推荐使用唯一 ID(如 /dev/disk/by-id/),以避免块设备路径误配的问题

参考文档