本文发表于一年多前。旧文章可能包含过时内容。请检查页面中的信息自发布以来是否已变得不正确。

Kubernetes 1.25:本地存储容量隔离达到 GA

本地临时存储容量隔离功能在 Kubernetes 1.7 中作为 Alpha 特性引入,并在 1.9 中进入 Beta 阶段。随着 Kubernetes 1.25 的发布,我们很高兴地宣布该功能正式发布(GA)。

Pod 使用本地临时存储作为临时空间、缓存和日志。本地临时存储的生命周期不会超过单个 Pod 的生命周期。它通过容器的可写层、日志目录和 EmptyDir 卷暴露给 Pod。在该特性引入之前,存在一些与本地存储核算和隔离不足相关的问题,例如 Pod 不知道有多少本地存储可用,也无法请求有保障的本地存储。本地存储是一种尽力而为的资源,Pod 可能会因为其他 Pod 占满本地存储而被驱逐。

本地存储容量隔离功能允许用户像管理 CPU 和内存一样管理本地临时存储。它为 Pod 之间的共享存储提供了容量隔离支持,这样,如果 Pod 对共享存储的消耗超过限制,可以通过驱逐 Pod 来严格限制其对共享资源的消耗。它还允许为资源预留设置临时存储请求。共享的 ephemeral-storage 的限制和请求类似于内存和 CPU 的消耗。

如何使用本地存储容量隔离

本地临时存储的典型配置是将所有不同类型的临时本地数据(emptyDir 卷、可写层、容器镜像、日志)都放在一个文件系统中。通常,/var/lib/kubelet 和 /var/log 都在系统的根文件系统上。如果用户以不同的方式配置本地存储,kubelet 可能无法正确测量磁盘使用情况并使用此功能。

为本地临时存储设置请求和限制

你可以指定 ephemeral-storage 来管理本地临时存储。Pod 的每个容器可以指定以下一项或两项:

  • spec.containers[].resources.limits.ephemeral-storage
  • spec.containers[].resources.requests.ephemeral-storage

在下面的示例中,Pod 有两个容器。第一个容器请求 8GiB 的本地临时存储,限制为 12GiB。第二个容器请求 2GiB 的本地存储,但没有设置限制。因此,该 Pod 总共请求 10GiB (8GiB+2GiB) 的本地临时存储,并强制执行 12GiB 的本地临时存储限制。它还将 emptyDir 的 sizeLimit 设置为 5GiB。Pod 规约中的此设置将影响调度器如何做出调度 Pod 的决策,以及 kubelet 如何驱逐 Pod。

apiVersion: v1
kind: Pod
metadata:
  name: frontend
spec:
  containers:
  - name: app
    image: images.my-company.example/app:v4
    resources:
      requests:
        ephemeral-storage: "8Gi"
      limits:
        ephemeral-storage: "12Gi"
    volumeMounts:
    - name: ephemeral
      mountPath: "/tmp"
  - name: log-aggregator
    image: images.my-company.example/log-aggregator:v6
    resources:
      requests:
        ephemeral-storage: "2Gi"
    volumeMounts:
    - name: ephemeral
      mountPath: "/tmp"
  volumes:
    - name: ephemeral
      emptyDir: {}
        sizeLimit: 5Gi

首先,调度器确保被调度容器的资源请求总和小于节点容量。在这种情况下,只有当节点可用的临时存储(可分配资源)超过 10GiB 时,该 Pod 才能被分配到该节点。

其次,在容器级别,由于其中一个容器设置了资源限制,kubelet 驱逐管理器将测量此容器的磁盘使用情况,并在第一个容器的存储使用量超过其限制(12GiB)时驱逐该 Pod。在 Pod 级别,kubelet 通过将该 Pod 中所有容器的限制相加来计算出 Pod 的总存储限制。在这种情况下,Pod 级别的总存储使用量是所有容器磁盘使用量与 Pod 的 emptyDir 卷之和。如果此总使用量超过 Pod 的总存储限制(12GiB),则 kubelet 也会标记该 Pod 进行驱逐。

最后,在此示例中,emptyDir 卷将其 sizeLimit 设置为 5Gi。这意味着如果此 Pod 的 emptyDir 使用的本地存储超过 5GiB,该 Pod 将被从节点上驱逐。

为本地临时存储设置资源配额和 LimitRange

此功能为存储添加了两个资源配额。请求和限制对命名空间中所有容器的总请求/限制设置约束。

  • requests.ephemeral-storage
  • limits.ephemeral-storage
apiVersion: v1
kind: ResourceQuota
metadata:
  name: storage-resources
spec:
  hard:
    requests.ephemeral-storage: "10Gi"
    limits.ephemeral-storage: "20Gi"

与 CPU 和内存类似,管理员可以使用 LimitRange 为命名空间设置默认容器的本地存储请求/限制,和/或最小/最大资源约束。

apiVersion: v1
kind: LimitRange
metadata:
  name: storage-limit-range
spec:
  limits:
  - default:
      ephemeral-storage: 10Gi
    defaultRequest:
      ephemeral-storage: 5Gi
    type: Container

此外,可以指定 ephemeral-storage 为 kubelet 或系统保留。例如,--system-reserved=[cpu=100m][,][memory=100Mi][,][ephemeral-storage=10Gi][,][pid=1000] --kube-reserved=[cpu=100m][,][memory=100Mi][,][ephemeral-storage=5Gi][,][pid=1000]。如果你的集群节点根磁盘容量为 100Gi,在设置 system-reserved 和 kube-reserved 值后,可用的可分配临时存储将变为 85Gi。调度器将使用此信息根据每个节点的请求和可分配资源来分配 Pod。驱逐管理器也将使用可分配资源来确定 Pod 驱逐。更多详细信息请参阅为系统守护进程预留计算资源

我如何参与?

这个项目,和所有 Kubernetes 项目一样,是许多来自不同背景的贡献者共同努力的结果。

我们非常感谢Kubernetes Storage SIG 和 CSI 社区中所有帮助审查该项目设计和实现的贡献者,包括但不限于以下人员: