节点拥有本地临时存储,其底层由本地挂载的可写设备提供支持,有时也由 RAM 提供。 "临时(Ephemeral)"意味着对数据的持久性没有长期保证。
Pod 使用临时本地存储作为临时数据空间、缓存和日志。
kubelet 可以使用本地临时存储为 Pod 提供临时数据空间,将
emptyDir卷挂载到容器中。
kubelet 还使用这种存储来存放节点级别的容器日志、 容器镜像和运行中容器的可写层。
如果节点发生故障,其临时存储中的数据可能会丢失。 你的应用程序不能期望从本地临时存储获得任何性能 SLA(例如磁盘 IOPS)。
要使资源配额在 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 驱逐信号。有关特性门控和支持此布局的容器运行时的详细信息,
参阅节点压力驱逐。
节点压力驱逐页面将这些观察到的文件系统称为
nodefs、imagefs 和 containerfs。这些名称并不总是意味着单独的挂载点。
当你使用本地临时存储的受支持配置之一来设置节点时,kubelet 可以测量本地存储的使用情况。
如果你使用的是其他配置,则 kubelet 不会对本地临时存储应用资源限制。
kubelet 将 tmpfs emptyDir 卷作为容器内存使用量来跟踪,而不是作为本地临时存储来跟踪。
kubelet 只能通过受支持的布局在其观察到的文件系统上跟踪临时存储。
如果你在这些布局之外的路径(例如 /var/lib/kubelet、/var/log 或容器运行时存储目录)下挂载额外的文件系统,
kubelet 可能无法正确报告临时存储的使用情况。
你可以指定 ephemeral-storage 来管理本地临时存储。
Pod 的每个容器可以指定以下一项或两项:
spec.containers[].resources.limits.ephemeral-storagespec.containers[].resources.requests.ephemeral-storageephemeral-storage 的 limits 和 requests 以字节量为单位进行衡量。
你可以使用纯整数或使用以下后缀之一作为定点数来表示存储量:
E、P、T、G、M、k。你也可以使用二进制幂的等价形式:Ei、Pi、Ti、Gi、Mi、Ki。
例如,以下数量都表示大致相同的值:
128974848129e6129M123Mi注意后缀的大小写。如果你请求 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
当你创建 Pod 时,Kubernetes 调度器为 Pod 选择一个运行节点。 每个节点都有可为 Pod 提供的本地临时存储的最大量。有关更多信息, 请参阅节点可分配资源。
调度器确保已调度容器的资源请求总和小于节点的容量。
如果 kubelet 将本地临时存储作为资源进行管理,则 kubelet 会在以下方面测量存储使用量:
emptyDir 卷,不包括基于 tmpfs 的 emptyDir 卷如果 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
prjquota。如果你不想使用项目配额,你应该:
featureGates 字段禁用 LocalStorageCapacityIsolationFSQuotaMonitoring
特性门控。