本文发表时间超过一年。较早的文章可能包含过时内容。请检查页面信息自发布以来是否已失效。

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 Spec 中的此设置将影响调度器关于 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

此外,还可以为 kubelet 或系统保留 ephemeral-storage。例如,--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 社区的所有贡献者,他们帮助审查了项目的设计和实现,包括但不限于以下人员: