临时卷

本文档描述了 Kubernetes 中的临时卷(ephemeral volumes)。建议熟悉卷(volumes),特别是 PersistentVolumeClaim 和 PersistentVolume。

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

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

临时卷正是为此类用例而设计的。由于卷的生命周期跟随 Pod,并与 Pod 一起创建和删除,因此可以在不依赖某个持久卷是否可用的情况下停止和重启 Pod。

临时卷在 Pod 规约中内联指定,简化了应用部署和管理。

临时卷的类型

Kubernetes 支持几种不同类型的临时卷,以满足不同的目的:

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

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

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

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

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

CSI 临时卷

特性状态: Kubernetes v1.25 [stable]

从概念上讲,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 临时卷允许用户将 volumeAttributes 作为 Pod 规约的一部分直接提供给 CSI 驱动程序。对于那些通常仅限管理员使用的 volumeAttributes,如果 CSI 驱动程序允许普通用户提供这些属性,则该驱动程序不适合用作内联临时卷。例如,通常在 StorageClass 中定义的参数不应通过使用内联临时卷暴露给用户。

需要限制哪些 CSI 驱动程序允许在 Pod 规约中用作内联卷的集群管理员,可以通过以下方式实现:

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

通用临时卷

特性状态: Kubernetes v1.23 [stable]

通用临时卷类似于 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 使用立即卷绑定,则会立即触发;如果使用 WaitForFirstConsumer 卷绑定模式,则会在 Pod 暂定调度到节点时触发。后者对于通用临时卷是推荐的,因为这样调度器可以自由地为 Pod 选择一个合适的节点。而使用立即绑定,调度器被迫选择一个在卷可用后能访问该卷的节点。

资源所有权方面,具有通用临时存储的 Pod 是提供该临时存储的 PersistentVolumeClaim(s) 的所有者。当 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 之间的潜在冲突。

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

安全

使用通用临时卷允许用户即使没有直接创建 PVC 的权限,也可以通过创建 Pod 来间接创建 PVC。集群管理员必须了解这一点。如果这不符合其安全模型,他们应使用准入 Webhook 来拒绝包含通用临时卷的 Pod 等对象。

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

下一步

由 kubelet 管理的临时卷

参见本地临时存储

CSI 临时卷

通用临时卷

最后修改于 2024 年 9 月 14 日 太平洋标准时间 上午 12:01:更新 ephemeral-volumes.md (f04a552825)