处理资源耗尽错误

目录

Overview

本指南介绍如何防止 Alauda Container Platform 节点出现内存(OOM)或磁盘空间耗尽的情况。节点的稳定运行至关重要,尤其是对于内存和磁盘等不可压缩资源。资源耗尽可能导致节点不稳定。

管理员可以配置驱逐策略,监控节点并在稳定性受损之前回收资源。

本文档涵盖 Alauda Container Platform 如何处理资源耗尽场景,包括资源回收、Pod 驱逐、Pod 调度和内存杀手(OOM Killer)。同时提供示例配置和最佳实践。

NOTE

如果节点启用了交换内存(swap),则无法检测内存压力。请禁用 swap 以启用基于内存的驱逐。

配置驱逐策略

驱逐策略允许节点在资源不足时终止 Pod,以回收所需资源。策略由驱逐信号和阈值组成,可在节点配置中或通过命令行设置。驱逐分为:

  • 硬驱逐:当阈值被超过时立即执行。
  • 软驱逐:在采取行动前有宽限期。

合理配置驱逐策略有助于节点主动防止资源耗尽。

NOTE


当 Pod 被驱逐时,Pod 中的所有容器都会被终止,PodPhase 状态变为 Failed。

对于磁盘压力,节点监控 nodefs(根文件系统)和 imagefs(容器镜像存储)。

  • nodefs/rootfs:用于本地磁盘卷、日志及其他存储(如 /var/lib/kubelet)。
  • imagefs:容器运行时使用的镜像和可写层存储(例如 Docker overlay2 驱动的 /var/lib/docker/overlay2,CRI-O 的 /var/lib/containers/storage)。
NOTE


如果没有本地存储隔离(临时存储)或 XFS 配额(volumeConfig),则无法限制 Pod 的磁盘使用。

在节点配置中创建驱逐策略

要设置驱逐阈值,请编辑节点配置映射中的 eviction-hardeviction-soft

硬驱逐示例:

kubeletArguments:
  eviction-hard:
    - memory.available<100Mi
    - nodefs.available<10%
    - nodefs.inodesFree<5%
    - imagefs.available<15%
    - imagefs.inodesFree<10%
  1. 驱逐类型:使用 eviction-hard 表示硬驱逐阈值。
  2. 每个驱逐阈值格式为 <eviction_signal><operator><quantity>,例如 memory.available<500Minodefs.available<10%
NOTE

inodesFree 必须使用百分比值,其他参数可使用百分比或数值。

软驱逐示例:

kubeletArguments:
  eviction-soft:
    - memory.available<100Mi
    - nodefs.available<10%
    - nodefs.inodesFree<5%
    - imagefs.available<15%
    - imagefs.inodesFree<10%
  eviction-soft-grace-period:
    - memory.available=1m30s
    - nodefs.available=1m30s
    - nodefs.inodesFree=1m30s
    - imagefs.available=1m30s
    - imagefs.inodesFree=1m30s
  1. 驱逐类型:使用 eviction-soft 表示软驱逐阈值。
  2. 每个驱逐阈值格式为 <eviction_signal><operator><quantity>,例如 memory.available<500Minodefs.available<10%
  3. 软驱逐的宽限期。建议保留默认值以获得最佳性能。

修改后重启 kubelet 服务使配置生效:

$ systemctl restart kubelet

驱逐信号

节点可根据以下信号触发驱逐:

节点状态驱逐信号描述
MemoryPressurememory.available可用内存低于阈值
DiskPressurenodefs.available节点根文件系统空间低于阈值
nodefs.inodesFree空闲 inode 低于阈值
imagefs.available镜像文件系统空间低于阈值
imagefs.inodesFreeimagefs 中空闲 inode 低于阈值
  • inodesFree 必须以百分比形式指定。
  • 内存计算不包括可回收的非活动文件内存。
  • 不要在容器内使用 free -m 命令。

节点每 10 秒监控一次这些文件系统。专用的卷或日志文件系统不被监控。

NOTE


在因磁盘压力驱逐 Pod 之前,节点会先执行容器和镜像垃圾回收。

驱逐阈值

驱逐阈值触发资源回收。当阈值达到时,节点报告压力状态,阻止新 Pod 调度,直到资源被回收。

  • 硬阈值:立即采取行动。
  • 软阈值:宽限期后采取行动。

阈值格式为:

<eviction_signal><operator><quantity>

示例:

  • memory.available<1Gi
  • memory.available<10%

节点每 10 秒评估一次阈值。

硬驱逐阈值

无宽限期,立即执行驱逐。

示例:

kubeletArguments:
  eviction-hard:
    - memory.available<500Mi
    - nodefs.available<500Mi
    - nodefs.inodesFree<5%
    - imagefs.available<100Mi
    - imagefs.inodesFree<10%

默认硬驱逐阈值

kubeletArguments:
  eviction-hard:
    - memory.available<100Mi
    - nodefs.available<10%
    - nodefs.inodesFree<5%
    - imagefs.available<15%

软驱逐阈值

软阈值需要宽限期。可选设置最大 Pod 终止宽限期(eviction-max-pod-grace-period)。

示例:

kubeletArguments:
  eviction-soft:
    - memory.available<500Mi
    - nodefs.available<500Mi
    - nodefs.inodesFree<5%
    - imagefs.available<100Mi
    - imagefs.inodesFree<10%
  eviction-soft-grace-period:
    - memory.available=1m30s
    - nodefs.available=1m30s
    - nodefs.inodesFree=1m30s
    - imagefs.available=1m30s
    - imagefs.inodesFree=1m30s

配置可调度资源

通过设置 system-reserved 为系统守护进程保留资源,控制节点可用于调度的资源量。只有当 Pod 超出其请求资源时才会触发驱逐。

  • Capacity:节点的总资源。
  • Allocatable:可用于调度的资源。

示例:

kubeletArguments:
  eviction-hard:
    - "memory.available<500Mi"
  system-reserved:
    - "memory=1.5Gi"

可通过节点摘要 API 确定合适的值。

修改后重启 kubelet:

$ systemctl restart kubelet

防止节点状态振荡

为避免软驱逐阈值上下振荡,设置 eviction-pressure-transition-period

示例:

kubeletArguments:
  eviction-pressure-transition-period:
    - 5m

默认值为 5 分钟。修改后重启服务。

回收节点级资源

当满足驱逐条件时,节点会先回收资源,再驱逐用户 Pod。

  • 有 imagefs
    • 达到 nodefs 阈值时:删除死亡的 Pod/容器。
    • 达到 imagefs 阈值时:删除未使用的镜像。
  • 无 imagefs
    • 达到 nodefs 阈值时:先删除死亡的 Pod/容器,再删除未使用的镜像。

Pod 驱逐

当阈值和宽限期满足时,节点驱逐 Pod,直到信号低于阈值。

Pod 按服务质量(QoS)和资源消耗排序驱逐。

QoS 等级描述
Guaranteed优先驱逐资源消耗最高的 Pod。
Burstable优先驱逐相对于请求资源消耗最高的 Pod。
BestEffort优先驱逐资源消耗最高的 Pod。

只有当系统守护进程超过保留资源或只剩 Guaranteed Pod 时,才会驱逐 Guaranteed Pod。

磁盘资源为 BestEffort 类型,Pod 按 QoS 和磁盘使用量逐个驱逐以回收磁盘空间。

服务质量与内存杀手(OOM Killer)

如果在内存回收前发生系统 OOM,OOM Killer 会介入。

OOM 分数根据 QoS 设置:

QoS 等级oom_score_adj 值
Guaranteed-998
Burstablemin(max(2, 1000 - (1000 * memoryRequestBytes) / machineMemoryCapacityBytes), 999)
BestEffort1000

OOM Killer 会终止分数最高的容器。优先终止 QoS 最低且内存使用最高的容器。容器可能根据节点策略重启。

调度器与资源耗尽状态

调度器在调度 Pod 时会考虑节点状态。

节点状态调度器行为
MemoryPressure不调度 BestEffort Pod。
DiskPressure不调度任何新 Pod。

示例场景

运维希望:

  • 节点内存为 10Gi。
  • 为系统守护进程保留 10%。
  • 在利用率达到 95% 时驱逐 Pod。

计算:

  • capacity = 10Gi
  • system-reserved = 1Gi
  • allocatable = 9Gi

若要在可用内存低于 10% 持续 30 秒时触发软驱逐,或低于 5% 时立即驱逐:

  • system-reserved = 2Gi
  • allocatable = 8Gi

配置示例:

kubeletArguments:
  system-reserved:
    - "memory=2Gi"
  eviction-hard:
    - "memory.available<.5Gi"
  eviction-soft:
    - "memory.available<1Gi"
  eviction-soft-grace-period:
    - "memory.available=30s"

此配置防止调度后立即出现内存压力和驱逐。

推荐实践

守护进程集与资源耗尽处理

由守护进程集创建的 Pod 被驱逐后会立即重建。守护进程集应避免使用 BestEffort Pod,采用 Guaranteed QoS 以降低被驱逐风险。