当前位置:  首页>> 技术小册>> Kubernetes中文教程(三)

本文档描述 Kubernetes 中的 临时卷(Ephemeral Volume)
建议先了解[卷],特别是 PersistentVolumeClaim 和 PersistentVolume。

有些应用程序需要额外的存储,但并不关心数据在重启后是否仍然可用。
例如,缓存服务经常受限于内存大小,而且可以将不常用的数据转移到比内存慢的存储中,对总体性能的影响并不大。

另有些应用程序需要以文件形式注入的只读数据,比如配置数据或密钥。

临时卷 就是为此类用例设计的。因为卷会遵从 Pod 的生命周期,与 Pod 一起创建和删除,
所以停止和重新启动 Pod 时,不会受持久卷在何处可用的限制。

临时卷在 Pod 规约中以 内联 方式定义,这简化了应用程序的部署和管理。

临时卷的类型

Kubernetes 为了不同的用途,支持几种不同类型的临时卷:

  • [emptyDir]:
    Pod 启动时为空,存储空间来自本地的 kubelet 根目录(通常是根磁盘)或内存
  • [configMap]、
    [downwardAPI]、
    [secret]:
    将不同类型的 Kubernetes 数据注入到 Pod 中
  • [CSI 临时卷]:
    类似于前面的卷类型,但由专门[支持此特性]
    的指定
    [CSI 驱动程序]提供
  • [通用临时卷]:
    它可以由所有支持持久卷的存储驱动程序提供

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

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

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

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

CSI 临时卷

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

从概念上讲,CSI 临时卷类似于 configMapdownwardAPIsecret 类型的卷:
在各个本地节点管理卷的存储,并在 Pod 调度到节点后与其他本地资源一起创建。
在这个阶段,Kubernetes 没有重新调度 Pod 的概念。卷创建不太可能失败,否则 Pod 启动将会受阻。
特别是,这些卷 支持[感知存储容量的 Pod 调度]。
它们目前也没包括在 Pod 的存储资源使用限制中,因为 kubelet 只能对它自己管理的存储强制执行。

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

  1. kind: Pod
  2. apiVersion: v1
  3. metadata:
  4. name: my-csi-app
  5. spec:
  6. containers:
  7. - name: my-frontend
  8. image: busybox:1.28
  9. volumeMounts:
  10. - mountPath: "/data"
  11. name: my-csi-inline-vol
  12. command: [ "sleep", "1000000" ]
  13. volumes:
  14. - name: my-csi-inline-vol
  15. csi:
  16. driver: inline.storage.kubernetes.io
  17. volumeAttributes:
  18. foo: bar

volumeAttributes 决定驱动程序准备什么样的卷。每个驱动程序的属性不尽相同,没有实现标准化。
有关进一步的说明,请参阅每个 CSI 驱动程序的文档。

CSI 驱动程序限制

CSI 临时卷允许用户直接向 CSI 驱动程序提供 volumeAttributes,它会作为 Pod 规约的一部分。
有些 volumeAttributes 通常仅限于管理员使用,允许这一类 volumeAttributes 的 CSI 驱动程序不适合在内联临时卷中使用。
例如,通常在 StorageClass 中定义的参数不应通过使用内联临时卷向用户公开。

如果集群管理员需要限制在 Pod 规约中作为内联卷使用的 CSI 驱动程序,可以这样做:

  • 从 CSIDriver 规约的 volumeLifecycleModes 中删除 Ephemeral,这可以防止驱动程序被用作内联临时卷。
  • 使用[准入 Webhook]
    来限制如何使用此驱动程序。

通用临时卷

通用临时卷类似于 emptyDir 卷,因为它为每个 Pod 提供临时数据存放目录,
在最初制备完毕时一般为空。不过通用临时卷也有一些额外的功能特性:

  • 存储可以是本地的,也可以是网络连接的。
  • 卷可以有固定的大小,Pod 不能超量使用。
  • 卷可能有一些初始数据,这取决于驱动程序和参数。
  • 支持典型的卷操作,前提是相关的驱动程序也支持该操作,包括
    [快照]、
    [克隆]、
    [调整大小]和
    [存储容量跟踪])。

示例:

  1. kind: Pod
  2. apiVersion: v1
  3. metadata:
  4. name: my-app
  5. spec:
  6. containers:
  7. - name: my-frontend
  8. image: busybox:1.28
  9. volumeMounts:
  10. - mountPath: "/scratch"
  11. name: scratch-volume
  12. command: [ "sleep", "1000000" ]
  13. volumes:
  14. - name: scratch-volume
  15. ephemeral:
  16. volumeClaimTemplate:
  17. metadata:
  18. labels:
  19. type: my-frontend-volume
  20. spec:
  21. accessModes: [ "ReadWriteOnce" ]
  22. storageClassName: "scratch-storage-class"
  23. resources:
  24. requests:
  25. storage: 1Gi

生命周期和 PersistentVolumeClaim

关键的设计思想是在 Pod 的卷来源中允许使用
[卷申领的参数]。
PersistentVolumeClaim 的标签、注解和整套字段集均被支持。
创建这样一个 Pod 后,
临时卷控制器在 Pod 所属的命名空间中创建一个实际的 PersistentVolumeClaim 对象,
并确保删除 Pod 时,同步删除 PersistentVolumeClaim。

如上设置将触发卷的绑定与/或制备,相应动作或者在

使用即时卷绑定时立即执行,
或者当 Pod 被暂时性调度到某节点时执行 。
对于通用的临时卷,建议采用后者,这样调度器就可以自由地为 Pod 选择合适的节点。
对于即时绑定,调度器则必须选出一个节点,使得在卷可用时,能立即访问该卷。

就[资源所有权]而言,
拥有通用临时存储的 Pod 是提供临时存储 的 PersistentVolumeClaim 的所有者。
当 Pod 被删除时,Kubernetes 垃圾收集器会删除 PVC,
然后 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” 的卷,这两者均会生成名为
“pod-a-scratch” 的 PVC),或者在 Pod 和手工创建的 PVC 之间可能出现冲突。

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

当同一个命名空间中命名 Pod 和卷时,要小心,以防止发生此类冲突。

安全

启用 GenericEphemeralVolume 特性会有一些副作用,用户能创建 Pod 就能间接地创建 PVC,
即使他们没有权限直接创建 PVC。
集群管理员必须意识到这一点。
如果这不符合他们的安全模型,他们应该使用[准入 Webhook]
拒绝包含通用临时卷的对象,例如 Pod。

正常的 [PVC 的名字空间配额]
仍然有效,因此即使允许用户使用这种新机制,他们也不能使用它来规避其他策略。

kubelet 管理的临时卷

参阅[本地临时存储]。

CSI 临时卷

  • 有关设计的更多信息,参阅
    [Ephemeral Inline CSI volumes KEP]。
  • 本特性下一步开发的更多信息,参阅
    [enhancement tracking issue #596]。

通用临时卷

  • 有关设计的更多信息,参阅
    [Generic ephemeral inline volumes KEP]。

该分类下的相关小册推荐: