K8S 存储:emptyDir、hostPath、local详解

发布于:2025-04-01 ⋅ 阅读:(22) ⋅ 点赞:(0)

1. emptyDir

定义与特性

emptyDir 是一种临时存储卷,其生命周期与Pod相同。当Pod被创建时,emptyDir 会在节点上生成一个空目录;当Pod被删除时,该目录及其数据会被永久清除。它主要用于同一Pod内多个容器间的临时数据共享,无需依赖外部存储系统。

工作原理

当Pod被调度到节点上时,Kubernetes的kubelet组件会在节点本地文件系统中创建一个临时目录,该目录被挂载到Pod中指定的容器路径。Pod删除时,目录及数据会被清除。

典型使用场景

  • 临时缓存:如容器应用处理任务时,需临时存储中间计算结果,供其他容器后续处理。任务完成或Pod重启后,数据无需保留。

  • 日志共享:同一Pod内,前端服务容器生成日志,日志分析容器实时读取日志进行分析。

  • 临时文件交换:多个容器间需临时交换文件,如配置文件生成容器与使用容器间的文件传递。

注意事项

  • 数据临时性:明确emptyDir数据不持久,勿用于需要长期保存的数据存储。若需持久化,应选择PVC、HostPath等其他存储方案。

  • 存储位置:emptyDir存储在节点本地,若Pod因节点故障迁移,原节点上的emptyDir数据无法跟随迁移。

  • 资源消耗:尽管emptyDir适合临时存储,仍需关注其对节点磁盘空间的占用,避免因大量临时数据导致节点磁盘满溢。

挂载定义

在 Pod 的 YAML 配置中,可以通过以下方式定义 emptyDir

apiVersion: v1
kind: Pod
metadata:
  name: volume-emptydir
spec:
  containers:
  - name: nginx
    image: nginx:1.14-alpine
    volumeMounts:
    - name: logs-volume
      mountPath: /var/log/nginx
  - name: busybox
    image: busybox:1.30
    command: ["/bin/sh", "-c", "tail -f /logs/access.log"]
    volumeMounts:
    - name: logs-volume
      mountPath: /logs
  volumes:
  - name: logs-volume
    emptyDir: {}

在这个例子中,emptyDir 被挂载到两个容器中,用于共享日志数据。

挂载选项

emptyDir 支持一些可选的挂载选项,用于控制其行为:

  • medium:指定存储介质,可以是 ""(默认,使用磁盘)或 Memory(使用内存)。

  • sizeLimit:指定存储大小限制(仅在 medium=Memory 时有效)。

volumes:
- name: cache-volume
  emptyDir:
    medium: Memory
    sizeLimit: 1Gi
  • 内存介质:对于需要高性能的临时存储,可以使用内存介质:

    volumes:
    - name: cache-volume
      emptyDir:
        medium: Memory
  • 大小限制:为内存介质的 emptyDir 设置大小限制,避免内存耗尽:

    volumes:
    - name: cache-volume
      emptyDir:
        medium: Memory
        sizeLimit: 1Gi

2. hostPath

定义与特性

hostPath 是一种存储卷类型,允许Pod直接访问宿主机(Node)上的文件或目录。通过hostPath,Pod内的容器可以挂载宿主机的文件系统,读取或写入其中的数据。

工作原理

在Pod的配置中,通过hostPath定义挂载点,并指定如何使用宿主机上的路径。Kubernetes会根据配置将宿主机的文件或目录挂载到Pod中。

典型使用场景

  • 访问宿主机上的日志文件。

  • 运行需要宿主机设备访问权限的应用,如Docker或Kubelet。

  • 共享宿主机与Pod之间的数据。

注意事项

  • 安全风险:挂载宿主机的关键目录(如/etc/var/root/proc等)可能导致宿主机被破坏,应避免此类操作。

  • 调度影响:使用hostPath时,Pod会被调度到特定的节点上,这可能会影响Pod的调度灵活性。

  • 不适用于分布式环境:由于hostPath直接依赖于宿主机的文件系统,它不适用于分布式环境(如多节点集群),因为它只能访问特定Node上的存储。

挂载定义

在 Pod 的 YAML 配置中,可以通过以下方式定义 hostPath

apiVersion: v1
kind: Pod
metadata:
  name: hostpath-example
spec:
  containers:
  - name: mycontainer
    image: nginx
    volumeMounts:
    - name: myvolume
      mountPath: /data
  volumes:
  - name: myvolume
    hostPath:
      path: /path/on/host
      type: DirectoryOrCreate

在上述事例中创建了一个名为 hostpath-example 的 Pod,其中包含一个名为 mycontainer 的容器。容器将访问宿主机上 /path/on/host 目录下的内容,并将这些内容挂载到容器的 /data 目录。

挂载选项

hostPath 支持一些可选的挂载选项,用于控制其行为:

  • path:指定宿主机上的路径。

  • type:可选,指定 hostPath 卷的类型。可用的类型包括:

    • DirectoryOrCreate:如果指定的路径不存在,则创建它作为目录。

    • Directory:如果指定的路径不存在,则不会创建。必须是一个已存在的目录。

    • FileOrCreate:如果指定的文件不存在,则创建它。

    • File:如果指定的文件不存在,则不会创建。必须是一个已存在的文件。

    • Socket:必须是已存在的 UNIX 套接字。

    • CharDevice:必须是已存在的字符设备。

    • BlockDevice:必须是已存在的块设备。

3. local

定义与特性

local 是一种较新的存储类型,允许用户通过标准PVC接口以简单且可移植的方式访问节点的本地存储资源。它目前还只是beta版,建议在k8s v1.10+以上的版本中使用。

  • 工作原理local存储通过PersistentVolume(PV)和PersistentVolumeClaim(PVC)来管理节点的本地存储资源。用户可以通过PVC申请使用存储资源,Kubernetes会自动匹配合适的PV。

  • 典型使用场景:适用于需要持久化存储的场景,如数据库存储、文件服务器等。

  • 注意事项

    • 需要正确配置PV和PVC,以确保存储资源的正确申请和使用。

    • local存储的持久性与节点的本地存储相关,若节点故障,存储的数据可能会丢失。

创建 PersistentVolume (PV)

local 存储需要通过静态方式创建 PersistentVolume,并指定 nodeAffinity,以确保 Kubernetes 调度器将 Pod 调度到正确的节点上。

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

创建 PersistentVolumeClaim (PVC)

创建一个 PersistentVolumeClaim,用于请求 local 存储资源。

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: static-pvc
spec:
  selector:
    matchLabels:
      app: static-pv
  accessModes:
    - ReadWriteOnce
  storageClassName: local-storage
  resources:
    requests:
      storage: 1Gi

创建 Pod 并挂载 PVC

在 Pod 的配置中,通过 PersistentVolumeClaim 挂载 local 存储。

apiVersion: v1
kind: Pod
metadata:
  name: static-pod
spec:
  containers:
    - image: mynginx:v1
      name: mynginx
      command:
        - "/bin/sh"
      args:
        - "-c"
        - "echo 'hello k8s local storage' > /mnt/SUCCESS && sleep 36000 || exit 1"
      volumeMounts:
        - mountPath: /mnt
          name: example-volume
  volumes:
    - name: example-volume
      persistentVolumeClaim:
        claimName: static-pvc

注意事项

  • 节点亲和性:必须设置 nodeAffinity,以便 Kubernetes 调度器将 Pod 调度到正确的节点上。

  • 存储类:建议创建一个 StorageClass,并设置 volumeBindingModeWaitForFirstConsumer,以确保在 Pod 调用时才绑定 PVC 和 PV。

  • 持久性local 存储的持久性取决于节点的本地存储,如果节点故障,存储的数据可能会丢失。

  • 动态配置local 存储不支持动态配置,需要手动创建 PV 和 PVC。