--- title: 临时卷 content_type: concept weight: 50 --- 本文档描述 Kubernetes 中的 _临时卷(Ephemeral Volume)_。 建议先了解[卷](/zh/docs/concepts/storage/volumes/),特别是 PersistentVolumeClaim 和 PersistentVolume。 有些应用程序需要额外的存储,但并不关心数据在重启后仍然可用,既是否被持久地保存。 例如,缓存服务经常受限于内存大小,将不常用的数据转移到比内存慢、但对总体性能的影响很小的存储中。 另有些应用程序需要以文件形式注入的只读数据,比如配置数据或密钥。 _临时卷_ 就是为此类用例设计的。因为卷会遵从 Pod 的生命周期,与 Pod 一起创建和删除, 所以停止和重新启动 Pod 时,不会受持久卷在何处可用的限制。 临时卷在 Pod 规范中以 _内联_ 方式定义,这简化了应用程序的部署和管理。 ### 临时卷的类型 {#types-of-ephemeral-volumes} Kubernetes 为了不同的目的,支持几种不同类型的临时卷: - [emptyDir](/zh/docs/concepts/storage/volumes/#emptydir): Pod 启动时为空,存储空间来自本地的 kubelet 根目录(通常是根磁盘)或内存 - [configMap](/zh/docs/concepts/storage/volumes/#configmap)、 [downwardAPI](/zh/docs/concepts/storage/volumes/#downwardapi)、 [secret](/zh/docs/concepts/storage/volumes/#secret): 将不同类型的 Kubernetes 数据注入到 Pod 中 - [CSI 临时卷](/zh/docs/concepts/storage/volumes/#csi-ephemeral-volumes): 类似于前面的卷类型,但由专门[支持此特性](https://kubernetes-csi.github.io/docs/drivers.html) 的指定 [CSI 驱动程序](https://github.com/container-storage-interface/spec/blob/master/spec.md)提供 - [通用临时卷](#generic-ephemeral-volumes): 它可以由所有支持持久卷的存储驱动程序提供 `emptyDir`、`configMap`、`downwardAPI`、`secret` 是作为 [本地临时存储](/zh/docs/concepts/configuration/manage-resources-containers/#local-ephemeral-storage) 提供的。它们由各个节点上的 kubelet 管理。 CSI 临时卷 *必须* 由第三方 CSI 存储驱动程序提供。 通用临时卷 *可以* 由第三方 CSI 存储驱动程序提供,也可以由支持动态配置的任何其他存储驱动程序提供。 一些专门为 CSI 临时卷编写的 CSI 驱动程序,不支持动态供应:因此这些驱动程序不能用于通用临时卷。 使用第三方驱动程序的优势在于,它们可以提供 Kubernetes 本身不支持的功能, 例如,与 kubelet 管理的磁盘具有不同运行特征的存储,或者用来注入不同的数据 ### CSI 临时卷 {#csi-ephemeral-volumes} {{< feature-state for_k8s_version="v1.16" state="beta" >}} 该特性需要启用参数 `CSIInlineVolume` [特性门控(feature gate)](/zh/docs/reference/command-line-tools-reference/feature-gates/)。 该参数从 Kubernetes 1.16 开始默认启用。 {{< note >}} 只有一部分 CSI 驱动程序支持 CSI 临时卷。Kubernetes CSI [驱动程序列表](https://kubernetes-csi.github.io/docs/drivers.html) 显示了支持临时卷的驱动程序。 {{< /note >}} 从概念上讲,CSI 临时卷类似于 `configMap`、`downwardAPI` 和 `secret` 类型的卷: 其存储在每个节点本地管理,并在将 Pod 调度到节点后与其他本地资源一起创建。 在这个阶段,Kubernetes 没有重新调度 Pods 的概念。卷创建不太可能失败,否则 Pod 启动将会受阻。 特别是,这些卷 *不* 支持[感知存储容量的 Pod 调度](/zh/docs/concepts/storage/storage-capacity/)。 它们目前也没包括在 Pod 的存储资源使用限制中,因为 kubelet 只能对它自己管理的存储强制执行。 下面是使用 CSI 临时存储的 Pod 的示例清单: ```yaml kind: Pod apiVersion: v1 metadata: name: my-csi-app spec: containers: - name: my-frontend image: busybox 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 驱动程序的文档。 作为一个集群管理员,你可以使用 [PodSecurityPolicy](/zh/docs/concepts/policy/pod-security-policy/) 来控制在 Pod 中可以使用哪些 CSI 驱动程序, 具体则是通过 [`allowedCSIDrivers` 字段](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#podsecuritypolicyspec-v1beta1-policy) 指定。 ### 通用临时卷 {#generic-ephemeral-volumes} {{< feature-state for_k8s_version="v1.19" state="alpha" >}} 这个特性需要启用 `GenericEphemeralVolume` [特性门控](/zh/docs/reference/command-line-tools-reference/feature-gates/)。 因为这是一个alpha特性,默认禁用。 通用临时卷类似于 `emptyDir` 卷,但更加灵活: - 存储可以是本地的,也可以是网络连接的。 - 卷可以有固定的大小,pod不能超量使用。 - 卷可能有一些初始数据,这取决于驱动程序和参数。 - 当驱动程序支持,卷上的典型操作将被支持,包括([快照](/zh/docs/concepts/storage/volume-snapshots/)、[克隆](/zh/docs/concepts/storage/volume-pvc-datasource/)、[调整大小](/zh/docs/concepts/storage/persistent-volumes/#expanding-persistent-volumes-claims)和[存储容量跟踪](/zh/docs/concepts/storage/storage-capacity/))。 示例: ```yaml kind: Pod apiVersion: v1 metadata: name: my-app spec: containers: - name: my-frontend image: busybox 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 {#lifecycle-and-persistentvolumeclaim} 关键的设计思想是在 Pod 的卷来源中允许使用 [卷申领的参数](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#ephemeralvolumesource-v1alpha1-core)。 PersistentVolumeClaim 的标签、注解和整套字段集均被支持。 创建这样一个 Pod 后, 临时卷控制器在 Pod 所属的命名空间中创建一个实际的 PersistentVolumeClaim 对象, 并确保删除 Pod 时,同步删除 PersistentVolumeClaim。 如上设置将触发卷的绑定与/或准备操作,相应动作或者在 {{< glossary_tooltip text="StorageClass" term_id="storage-class" >}} 使用即时卷绑定时立即执行, 或者当 Pod 被暂时性调度到某节点时执行 (`WaitForFirstConsumer` 卷绑定模式)。 对于常见的临时卷,建议采用后者,这样调度器就可以自由地为 Pod 选择合适的节点。 对于即时绑定,调度器则必须选出一个节点,使得在卷可用时,能立即访问该卷。 就[资源所有权](/zh/docs/concepts/workloads/controllers/garbage-collection/#owners-and-dependents)而言, 拥有通用临时存储的 Pod 是提供临时存储 (ephemeral storage) 的 PersistentVolumeClaim 的所有者。 当 Pod 被删除时,Kubernetes 垃圾收集器会删除 PVC, 然后 PVC 通常会触发卷的删除,因为存储类的默认回收策略是删除卷。 你可以使用带有 `retain` 回收策略的 StorageClass 创建准临时 (quasi-ephemeral) 本地存储: 该存储比 Pod 寿命长,在这种情况下,你需要确保单独进行卷清理。 当这些 PVC 存在时,它们可以像其他 PVC 一样使用。 特别是,它们可以被引用作为批量克隆或快照的数据源。 PVC对象还保持着卷的当前状态。 ### PersistentVolumeClaim 的命名 {#persistentvolumeclaim-naming} 自动创建的 PVCs 的命名是确定的:此名称是 Pod 名称和卷名称的组合,中间由连字符(`-`)连接。 在上面的示例中,PVC 将命名为 `my-app-scratch-volume` 。 这种确定性命名方式使得与 PVC 交互变得更容易,因为一旦知道 Pod 名称和卷名,就不必搜索它。 这种确定性命名方式也引入了潜在的冲突, 比如在不同的 Pod 之间(名为 “Pod-a” 的 Pod 挂载名为 "scratch" 的卷, 名为 "pod" 的 Pod 挂载名为 “a-scratch” 的卷,这两者均会生成名为 "pod-a-scratch" 的PVC), 或者在 Pod 和手工创建的 PVC 之间。 以下冲突会被检测到:如果 PVC 是为 Pod 创建的,那么它只用于临时卷。 此检测基于所有权关系。现有的 PVC 不会被覆盖或修改。 但这并不能解决冲突,因为如果没有正确的 PVC,Pod 就无法启动。 {{< caution >}} 当命名 Pods 和卷出现在同一个命名空间中时,要小心,以防止发生此类冲突。 {{< /caution >}} ### 安全 {#security} 启用 GenericEphemeralVolume 特性会导致那些没有 PVCs 创建权限的用户, 在创建 Pods 时,被允许间接的创建 PVCs。 集群管理员必须意识到这一点。 如果这不符合他们的安全模型,他们有两种选择: - 通过特性门控显式禁用该特性,可以避免将来的 Kubernetes 版本默认启用时带来混乱。 - 当`卷`列表不包含 `ephemeral` 卷类型时,使用 [Pod 安全策略](/zh/docs/concepts/policy/pod-security-policy/)。 在一个命名空间中,用于 PVCs 的常规命名空间配额仍然适用, 因此即使允许用户使用这种新机制,他们也不能使用它来规避其他策略。 ## {{% heading "whatsnext" %}} ### kubelet 管理的临时卷 {#ephemeral-volumes-managed-by-kubelet} 参阅[本地临时存储](/zh/docs/concepts/configuration/manage-resources-containers/#local-ephemeral-storage)。 ### CSI 临时卷 {#csi-ephemeral-volumes} - 有关设计的更多信息,参阅 [Ephemeral Inline CSI volumes KEP](https://github.com/kubernetes/enhancements/blob/ad6021b3d61a49040a3f835e12c8bb5424db2bbb/keps/sig-storage/20190122-csi-inline-volumes.md)。 - 本特性下一步开发的更多信息,参阅 [enhancement tracking issue #596](https://github.com/kubernetes/enhancements/issues/596)。 ### 通用临时卷 {#generic-ephemeral-volumes} - 有关设计的更多信息,参阅 [Generic ephemeral inline volumes KEP](https://github.com/kubernetes/enhancements/blob/master/keps/sig-storage/1698-generic-ephemeral-volumes/README.md)。 - 本特性下一步开发的更多信息,参阅 [enhancement tracking issue #1698](https://github.com/kubernetes/enhancements/issues/1698).