2. 资源模型基础:Kubernetes 资源模型(CPU、内存、临时存储)的 Request 与 Limit 语义

在 Kubernetes 集群中,资源模型是调度器、kubelet 以及节点压力驱逐等核心组件协同工作的基石。理解 CPU、内存和临时存储的 Request 与 Limit 语义,是诊断和优化 CrashLoop 故障域的第一步。错误的资源设定往往直接导致 Pod 被 OOM Kill 或节点磁盘压力驱逐,从而引发无限重启循环。

2.1 核心语义:Request 与 Limit 的双重含义

Kubernetes 为每种可压缩资源(CPU)和不可压缩资源(内存、临时存储)定义了两种 QoS 相关的声明:

属性 调度保证 运行时限制 典型 CrashLoop 影响
Request 调度器依据该值选择满足容量要求的节点 CPU 使用 CFS 配额按比例分配;内存不做硬限制(仅作为调度依据) Request 设置过高导致节点资源碎片,Pod 无法被调度
Limit 不参与调度决策 CPU 通过 CFS 周期强制上限;内存通过 cgroup memory.max 硬限制 Limit 设置过低导致进程频繁 OOM Kill,触发 CrashLoop
关键认知: Request 是“预留承诺”,Limit 是“硬性天花板”。对于内存和临时存储,一旦进程使用量超过 Limit,内核会立即发送 SIGKILL,这是 CrashLoop 场景中最常见的直接原因之一。

2.2 三种资源的差异化行为

2.2.1 CPU:可压缩资源

CPU 是唯一可压缩的资源。当进程争抢超过 Limit 时,内核会通过 CFS 节流(throttle)限制其时间片,进程不会被杀掉,但会变慢。因此 CPU Limit 设置不当通常不会直接导致 CrashLoop,但可能引发应用超时或健康检查失败,间接导致重启。

2.2.2 内存:不可压缩资源

内存是 CrashLoop 故障域中最关键的资源。当进程内存使用量超过 Limit 时,cgroup OOM killer 会立即终止进程。如果 Pod 的 restartPolicy 为 Always 或 OnFailure,kubelet 会重启容器,形成“启动→OOM→重启”的死循环。

2.2.3 临时存储:节点级压力

临时存储(ephemeral-storage)用于 emptyDir、日志、容器可写层。当 Pod 的临时存储使用量超过 Limit 时,kubelet 不会立即杀死容器,但会标记该 Pod 为 EvictionCandidate。一旦节点磁盘使用率达到驱逐阈值,kubelet 会优先驱逐超出 Limit 的 Pod,导致其进入 CrashLoop。

实践陷阱: 很多团队只关注 CPU 和内存,忽略了临时存储的 Request/Limit 配置。在日志密集或写临时文件频繁的场景下,临时存储 Limit 不足会触发节点级驱逐,且驱逐后 Pod 被调度到其他节点可能再次因磁盘压力被驱逐,形成跨节点的 CrashLoop 扩散。

2.3 资源模型与 QoS 等级的关系

Request 和 Limit 的组合决定了 Pod 的 QoS 等级,不同等级在节点压力驱逐时具有不同的优先级:

QoS 等级 配置条件 驱逐优先级 CrashLoop 风险
Guaranteed 所有容器 Request == Limit(且不为 0) 最低(最后被驱逐) 低(资源有硬保证)
Burstable 至少一个容器 Request < Limit,且非 BestEffort 中等 中(突发流量可能超 Limit)
BestEffort 所有容器均未设置 Request 和 Limit 最高(最先被驱逐) 高(无任何资源保证)
故障域优化建议: 对于生产环境的关键业务 Pod,应尽量使用 Guaranteed QoS(即 Request == Limit)。这不仅能避免因资源争抢导致的 OOM,还能在节点压力时获得最低的驱逐优先级,从而显著降低 CrashLoop 的发生概率。

2.4 资源模型与 CrashLoop 的关联流程

下图展示了从资源 Limit 配置不当到 CrashLoop 的完整故障链路:

资源 Limit 不当导致 CrashLoop 的故障链路 资源 Limit 不当 → CrashLoop 故障链路 1. 资源 Limit 配置过低 2. 进程内存/磁盘使用超 Limit 3. OOM Kill / 节点驱逐 4. kubelet 重启容器 → CrashLoop 关键指标 • container_memory_working_set_bytes • container_oom_events_total • kubelet_eviction_stats

2.5 典型 CrashLoop 资源配置示例

以下是一个因内存 Limit 过低导致 CrashLoop 的典型配置及修复对比:

# ❌ 错误配置:Limit 过低,且 Request 与 Limit 差距过大(Burstable QoS)
apiVersion: v1
kind: Pod
metadata:
  name: crashloop-demo
spec:
  containers:
  - name: app
    image: myapp:latest
    resources:
      requests:
        memory: "256Mi"      # 调度预留
        cpu: "500m"
      limits:
        memory: "128Mi"      # ❌ Limit 小于 Request,且远低于实际需求
        cpu: "1000m"
# ✅ 修复配置:基于实际压测数据设置,且 Request == Limit(Guaranteed QoS)
apiVersion: v1
kind: Pod
metadata:
  name: crashloop-demo-fixed
spec:
  containers:
  - name: app
    image: myapp:latest
    resources:
      requests:
        memory: "512Mi"      # 基于压测的稳态值
        cpu: "1000m"
      limits:
        memory: "512Mi"      # ✅ 与 Request 一致,避免 OOM
        cpu: "1000m"
避坑指南: 永远不要将内存 Limit 设置为低于 Request 的值。Kubernetes 调度器只检查 Request,如果 Limit 小于 Request,Pod 虽然能被调度,但运行时实际可用内存比调度时承诺的还少,极易触发 OOM。这是 CrashLoop 场景中常见的“调度成功但运行失败”陷阱。

2.6 资源模型优化的核心原则

  • 先压测,后定值: 使用 stress 工具或生产流量回放,获取 CPU、内存、临时存储的 P99 使用量,作为 Request 的基准。
  • Limit 与 Request 对齐: 对于内存和临时存储,优先使用 Guaranteed QoS(Request == Limit),消除 OOM 和驱逐风险。
  • 临时存储不可忽视: 为每个容器显式设置 ephemeral-storage 的 Request 和 Limit,避免被节点级驱逐波及。
  • 监控先行: 部署 Prometheus 并采集 container_memory_working_set_bytes 和 container_oom_events_total,在 CrashLoop 发生前预警。
故障域视角总结: 资源模型是 CrashLoop 故障域的第一道防线。正确的 Request 保证调度可行性,正确的 Limit 防止运行时被杀。两者共同决定了 Pod 的 QoS 等级,进而影响节点压力下的驱逐顺序。在后续章节中,我们将基于此模型,深入分析 CrashLoop 场景下的具体诊断工具和优化策略。