临时卷

本文档介绍了 Kubernetes 中的临时卷 (Ephemeral Volumes)。建议先熟悉 ,特别是 PersistentVolumeClaim 和 PersistentVolume 的概念。

有些应用程序需要额外的存储空间,但并不关心这些数据在重启后是否持久化。例如,缓存服务通常受到内存大小的限制,可以将不常用的数据移动到速度比内存慢的存储中,且对整体性能的影响很小。

其他应用程序则期望在文件中存在一些只读的输入数据,例如配置文件或密钥。

临时卷就是为这些用例设计的。由于卷遵循 Pod 的生命周期,并随 Pod 一起创建和删除,因此 Pod 可以停止和重启,而无需受限于某些持久卷的可用性位置。

临时卷在 Pod 规范中内联 (inline) 指定,这简化了应用程序的部署和管理。

临时卷类型

Kubernetes 支持多种不同用途的临时卷:

  • emptyDir:在 Pod 启动时为空,存储来自 kubelet 的本地基础目录(通常是根磁盘)或 RAM。
  • configMap, downwardAPI, secret:将不同类型的 Kubernetes 数据注入 Pod。
  • image:允许直接将容器镜像文件或工件挂载到 Pod 中。
  • CSI 临时卷:类似于上述卷类型,但由特殊的 CSI 驱动程序提供,这些驱动程序专门支持此功能
  • 通用临时卷:可以由所有支持持久卷的存储驱动程序提供。

emptyDirconfigMapdownwardAPIsecret 作为本地临时存储提供。它们由每个节点上的 kubelet 管理。

CSI 临时卷必须由第三方 CSI 存储驱动程序提供。

通用临时卷可以由第三方 CSI 存储驱动程序提供,也可以由任何支持动态预配的其他存储驱动程序提供。一些 CSI 驱动程序是专门为 CSI 临时卷编写的,不支持动态预配:因此这些驱动程序不能用于通用临时卷。

使用第三方驱动程序的优势在于它们可以提供 Kubernetes 本身不支持的功能,例如具有不同于 kubelet 所管理磁盘的性能特性的存储,或注入不同的数据。

CSI 临时卷

功能状态: Kubernetes v1.25 [稳定]

说明

只有一部分 CSI 驱动程序支持 CSI 临时卷。Kubernetes CSI 驱动程序列表显示了哪些驱动程序支持临时卷。

从概念上讲,CSI 临时卷类似于 configMapdownwardAPIsecret 卷类型:存储是在每个节点上本地管理的,并且在 Pod 被调度到节点后与其他本地资源一起创建。此时,Kubernetes 没有重新调度 Pod 的概念。卷的创建必须尽量避免失败,否则 Pod 启动会卡住。特别是,这些卷不支持感知存储容量的 Pod 调度。目前它们也不包含在 Pod 的存储资源使用限制中,因为 kubelet 只能对它自己管理的存储强制执行这些限制。

以下是使用 CSI 临时存储的 Pod 清单示例:

kind: Pod
apiVersion: v1
metadata:
  name: my-csi-app
spec:
  containers:
    - name: my-frontend
      image: busybox:1.28
      volumeMounts:
      - mountPath: "/data"
        name: my-csi-inline-vol
      command: [ "sleep", "1000000" ]
  volumes:
    - name: my-csi-inline-vol
      csi:
        driver: inline.storage.kubernetes.io
        volumeAttributes:
          foo: bar

volumeAttributes 决定了驱动程序准备什么卷。这些属性特定于每个驱动程序,且未标准化。请参阅每个 CSI 驱动程序的文档以获取进一步说明。

CSI 驱动程序限制

CSI 临时卷允许用户在 Pod 规范中直接向 CSI 驱动程序提供 volumeAttributes。如果一个 CSI 驱动程序允许通常限制给管理员的 volumeAttributes,则它不适合在内联临时卷中使用。例如,通常在 StorageClass 中定义的参数不应通过使用内联临时卷暴露给用户。

需要限制允许在 Pod 规范中用作内联卷的 CSI 驱动程序的集群管理员可以执行以下操作:

  • 从 CSIDriver 规范的 volumeLifecycleModes 中移除 Ephemeral,这将阻止该驱动程序被用作内联临时卷。
  • 使用准入控制器 (Admission Webhook) 来限制该驱动程序的使用方式。

通用临时卷

功能状态: Kubernetes v1.23 [稳定]

通用临时卷在某种意义上类似于 emptyDir 卷,因为它们为每个 Pod 提供了一个在预配后通常为空的暂存数据目录。但它们也可能具有额外的功能:

  • 存储可以是本地的,也可以是网络附加的。
  • 卷可以具有 Pod 无法超过的固定大小。
  • 卷可能具有一些初始数据,具体取决于驱动程序和参数。
  • 假设驱动程序支持,卷的典型操作都是支持的,包括快照克隆调整大小存储容量跟踪

示例

kind: Pod
apiVersion: v1
metadata:
  name: my-app
spec:
  containers:
    - name: my-frontend
      image: busybox:1.28
      volumeMounts:
      - mountPath: "/scratch"
        name: scratch-volume
      command: [ "sleep", "1000000" ]
  volumes:
    - name: scratch-volume
      ephemeral:
        volumeClaimTemplate:
          metadata:
            labels:
              type: my-frontend-volume
          spec:
            accessModes: [ "ReadWriteOnce" ]
            storageClassName: "scratch-storage-class"
            resources:
              requests:
                storage: 1Gi

生命周期与 PersistentVolumeClaim

关键的设计思想是允许在 Pod 的卷源内使用卷声明参数。支持标签、注解和 PersistentVolumeClaim 的整套字段。当创建这样的 Pod 时,临时卷控制器会在与 Pod 相同的命名空间中创建一个实际的 PersistentVolumeClaim 对象,并确保在 Pod 被删除时该 PersistentVolumeClaim 也被删除。

如果 StorageClass 使用立即卷绑定,或者当 Pod 被暂定调度到某个节点上时(WaitForFirstConsumer 卷绑定模式),这会触发卷绑定和/或预配。对于通用临时卷,建议使用后者,因为这样调度程序可以自由选择适合 Pod 的节点。如果使用立即绑定,调度程序在卷可用后被迫选择能够访问该卷的节点。

资源所有权方面,拥有通用临时存储的 Pod 是提供该临时存储的 PersistentVolumeClaim 的所有者。当 Pod 被删除时,Kubernetes 垃圾收集器会删除 PVC,这通常会触发卷的删除,因为存储类的默认回收策略是删除卷。你可以使用回收策略为 retain 的 StorageClass 创建准临时本地存储:存储的生命周期超过 Pod 的生命周期,在这种情况下,你需要确保卷清理是单独进行的。

只要这些 PVC 存在,它们就可以像任何其他 PVC 一样使用。特别是,它们可以用作卷克隆或快照中的数据源。PVC 对象还保存了卷的当前状态。

PersistentVolumeClaim 命名

自动创建的 PVC 的命名是确定性的:名称是 Pod 名称和卷名称的组合,中间用连字符 (-) 连接。在上面的示例中,PVC 名称将为 my-app-scratch-volume。这种确定性命名使得与 PVC 的交互更容易,因为一旦知道了 Pod 名称和卷名称,就不必去搜索它。

这种确定性命名也在不同 Pod 之间(例如名为 "pod-a" 的 Pod 使用卷 "scratch",而另一个名为 "pod" 的 Pod 使用卷 "a-scratch",两者最终都会得到相同的 PVC 名称 "pod-a-scratch")以及 Pod 和手动创建的 PVC 之间引入了潜在冲突。

这种冲突是可以检测到的:只有当 PVC 是为该 Pod 创建时,它才会被用于临时卷。这种检查基于所有权关系。现有的 PVC 不会被覆盖或修改。但这并不能解决冲突,因为没有正确的 PVC,Pod 就无法启动。

注意

在同一命名空间内命名 Pod 和卷时要小心,以避免这些冲突。

安全

使用通用临时卷允许用户在能够创建 Pod 的情况下间接创建 PVC,即使他们没有直接创建 PVC 的权限。集群管理员必须意识到这一点。如果这不符合他们的安全模型,他们应该使用准入控制器来拒绝包含通用临时卷的 Pod 等对象。

正常的 PVC 命名空间配额仍然适用,因此即使允许用户使用这种新机制,他们也无法利用它来规避其他策略。

接下来

由 kubelet 管理的临时卷

参见本地临时存储

CSI 临时卷

通用临时卷


最后修改于 2025 年 10 月 5 日 下午 9:09 PST:将临时存储内容从容器资源页面移出 (b94586af73)