本地临时存储

本地临时存储

节点拥有本地临时存储,其底层由本地挂载的可写设备提供支持,有时也由 RAM 提供。 "临时(Ephemeral)"意味着对数据的持久性没有长期保证。

Pod 使用临时本地存储作为临时数据空间、缓存和日志。 kubelet 可以使用本地临时存储为 Pod 提供临时数据空间,将 emptyDir挂载到容器中。

kubelet 还使用这种存储来存放节点级别的容器日志、 容器镜像和运行中容器的可写层。

注意:

如果节点发生故障,其临时存储中的数据可能会丢失。 你的应用程序不能期望从本地临时存储获得任何性能 SLA(例如磁盘 IOPS)。

说明:

要使资源配额在 ephemeral-storage 上生效,需要做两件事:

  • 管理员在某命名空间中设置 ephemeral-storage 的资源配额。
  • 用户需要在 Pod 规约中为 ephemeral-storage 资源指定限制。

如果用户没有在 Pod 规约中指定 ephemeral-storage 资源限制, 则 ephemeral-storage 上的资源配额不会被强制执行。

Kubernetes 允许你跟踪、预留和限制 Pod 可以消耗的本地临时存储量。

本地临时存储的配置

Kubernetes 支持以下方式在节点上配置本地临时存储:

在此配置中,你将所有不同类型的临时本地数据 (emptyDir 卷、可写层、容器镜像、日志)放入一个文件系统。

kubelet 还会写入节点级别的容器日志, 并将其视为与临时本地存储类似。

kubelet 将日志写入其配置的日志目录(默认为 /var/log)中的文件; 并有一个用于其他本地存储数据的基础目录(默认为 /var/lib/kubelet)。

通常,/var/lib/kubelet/var/log 都位于系统根文件系统上, kubelet 的设计就是基于这种布局考虑的。

你的节点可以拥有任意数量的其他文件系统,这些文件系统不用于 Kubernetes。

你在节点上使用一个文件系统来存放运行中 Pod 的临时数据,例如日志和 emptyDir 卷。 你也可以将此文件系统用于其他数据,例如与 Kubernetes 无关的系统日志;它甚至可以是根文件系统。

kubelet 还将节点级别的容器日志写入第一个文件系统, 并将其视为与临时本地存储类似。

你还使用一个单独的文件系统,由不同的逻辑存储设备提供支持。 在此配置中,容器运行时将容器镜像层和可写层都存储在第二个文件系统上。 请在容器运行时中配置此存储位置,而不是在 kubelet 中配置。

第一个文件系统不存放任何镜像层或可写层。

你的节点可以拥有任意数量的其他文件系统,这些文件系统不用于 Kubernetes。

在此配置中,容器镜像层位于单独的文件系统上,而容器可写层与 kubelet 的临时数据(例如日志和 emptyDir 卷)位于同一文件系统上。

此布局需要支持 containerfs 驱逐信号。有关特性门控和支持此布局的容器运行时的详细信息, 参阅节点压力驱逐

节点压力驱逐页面将这些观察到的文件系统称为 nodefsimagefscontainerfs。这些名称并不总是意味着单独的挂载点。

当你使用本地临时存储的受支持配置之一来设置节点时,kubelet 可以测量本地存储的使用情况。

如果你使用的是其他配置,则 kubelet 不会对本地临时存储应用资源限制。

说明:

kubelet 将 tmpfs emptyDir 卷作为容器内存使用量来跟踪,而不是作为本地临时存储来跟踪。

说明:

kubelet 只能通过受支持的布局在其观察到的文件系统上跟踪临时存储。 如果你在这些布局之外的路径(例如 /var/lib/kubelet/var/log 或容器运行时存储目录)下挂载额外的文件系统, kubelet 可能无法正确报告临时存储的使用情况。

为本地临时存储设置 requests 和 limits

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

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

ephemeral-storage 的 limits 和 requests 以字节量为单位进行衡量。 你可以使用纯整数或使用以下后缀之一作为定点数来表示存储量: E、P、T、G、M、k。你也可以使用二进制幂的等价形式:Ei、Pi、Ti、Gi、Mi、Ki。 例如,以下数量都表示大致相同的值:

  • 128974848
  • 129e6
  • 129M
  • 123Mi

注意后缀的大小写。如果你请求 400m 的 ephemeral-storage,这是对 0.4 字节的请求。 输入此值的人可能想请求 400 mebibytes(400Mi)或 400 megabytes(400M)。

在以下示例中,Pod 有两个容器。每个容器的本地临时存储 request 为 2GiB。 每个容器的本地临时存储 limit 为 4GiB。因此,Pod 的本地临时存储 request 为 4GiB, limit 为 8GiB。该 limit 中的 500Mi 可以被 emptyDir 卷占用。

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

带 ephemeral-storage requests 的 Pod 如何被调度

当你创建 Pod 时,Kubernetes 调度器为 Pod 选择一个运行节点。 每个节点都有可为 Pod 提供的本地临时存储的最大量。有关更多信息, 请参阅节点可分配资源

调度器确保已调度容器的资源请求总和小于节点的容量。

临时存储消耗管理

如果 kubelet 将本地临时存储作为资源进行管理,则 kubelet 会在以下方面测量存储使用量:

  • emptyDir 卷,不包括基于 tmpfsemptyDir
  • 存放节点级日志的目录
  • 可写入的容器层

如果 Pod 使用的临时存储超过了你允许的量,kubelet 会设置驱逐信号,触发 Pod 驱逐。

对于容器级别的隔离,如果容器的可写层和日志使用量超过其存储限制,kubelet 会将 Pod 标记为驱逐。

对于 Pod 级别的隔离,kubelet 通过对该 Pod 中容器的限制求和来计算出整个 Pod 的存储限制。 在这种情况下,如果所有容器的本地临时存储使用量加上 Pod 的 emptyDir 卷的总和超过了整个 Pod 的存储限制,则 kubelet 也会将 Pod 标记为驱逐。

注意:

如果 kubelet 没有测量本地临时存储,那么超过本地存储限制的 Pod 不会因违反本地存储资源限制而被驱逐。

但是,如果用于可写容器层、节点级别日志或 emptyDir 卷的文件系统空间不足, 节点会污点自身以表示本地存储不足, 此污点会触发对任何未特别容忍该污点的 Pod 的驱逐。

请参阅临时本地存储的受支持配置

kubelet 支持以不同方式测量 Pod 存储使用量:

kubelet 执行定期、计划的检查,扫描每个 emptyDir 卷、容器日志目录和可写容器层。

扫描会测量已使用的空间量。

说明:

项目配额是操作系统级别的功能,用于管理文件系统上的存储使用量。借助 Kubernetes, 你可以启用项目配额来监控存储使用量。确保节点上为 emptyDir 卷提供支持的文件系统支持项目配额。 例如,XFS 和 ext4fs 提供项目配额。

说明:

项目配额允许你监控存储使用量;它们不会强制执行限制。

Kubernetes 使用从 1048576 开始的项目 ID。正在使用的 ID 注册在 /etc/projects/etc/projid 中。如果此范围内的项目 ID 在系统上用于其他目的,则这些项目 ID 必须注册在 /etc/projects/etc/projid 中,以便 Kubernetes 不会使用它们。

配额比目录扫描更快、更准确。当一个目录被分配给某个项目时,在该目录下创建的所有文件都会在该项目中创建, 内核只需跟踪该项目中文件正在使用多少块。如果一个文件被创建并删除,但仍有打开的文件描述符, 它会继续占用空间。配额跟踪会准确记录该空间,而目录扫描会忽略已删除文件使用的存储。

要使用配额来跟踪 Pod 的资源使用量,Pod 必须位于用户名字空间中。 在用户名字空间内,内核限制对文件系统上 projectID 的更改,确保配额计算的存储指标的可靠性。

如果你想使用项目配额,你应该:

  • kubelet 配置中使用 featureGates 字段启用 LocalStorageCapacityIsolationFSQuotaMonitoring=true 特性门控

  • 确保 UserNamespacesSupport 特性门控已启用, 并且内核、CRI 实现和 OCI 运行时支持用户名字空间。

  • 确保根文件系统(或可选的运行时文件系统)已启用项目配额。所有 XFS 文件系统都支持项目配额。 对于 ext4 文件系统,你需要在文件系统未挂载时启用项目配额跟踪特性。

    # 对于,不挂载 /dev/block-device
    sudo tune2fs -O project -Q prjquota /dev/block-device
    
  • 确保根文件系统(或可选的运行时文件系统)在启用项目配额的情况下挂载。 对于 XFS 和 ext4fs,挂载选项名为 prjquota

如果你不想使用项目配额,你应该:

接下来

最后修改 August 19, 2026 at 9:09 AM PST: [zh] Add ephemeral-storage.md (35337960f9)