第十一篇:《资源管理:Requests/Limits、ResourceQuota、LimitRange》

在 Kubernetes 集群中,如果没有资源限制,一个恶意的或出现异常的容器可能会耗尽节点上的所有 CPU 和内存,导致其他 Pod 甚至节点本身不稳定。Kubernetes 提供了多层次的资源管理机制:容器级别的 requests 和 limits、命名空间级别的 ResourceQuota 以及 LimitRange。本文详细讲解这些概念,帮助你在保障应用性能的同时,维护集群的整体健康。

一、Requests 与 Limits:容器资源的"申请"与"上限"

每个容器可以指定 resources.requests 和 resources.limits。

requests:调度器基于此值决定将 Pod 放在哪个节点。它表示容器"保证"能获得的最小资源量。

limits:容器允许使用的最大资源量。超过 CPU 限制会限流(throttle),超过内存限制会触发 OOM Kill。

1.1 在 Pod 中配置

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: resource-demo
spec:
  containers:
  - name: app
    image: nginx
    resources:
      requests:
        memory: "128Mi"
        cpu: "250m"
      limits:
        memory: "256Mi"
        cpu: "500m"

CPU 单位:1 = 1 个 CPU 核心,500m = 0.5 个核心。

内存单位:Ki、Mi、Gi(2 的幂次),也可用 M、G(十进制,但推荐使用 Mi 等)。

1.2 为什么不设置 limits 有害?

如果只设置 requests 不设 limits,容器可以使用节点上所有可用资源,可能导致其他容器饥饿。

如果都不设置,容器可以无限使用资源,是典型的"吵闹邻居"问题。

最佳实践:总是设置 requests 和 limits,且 limits >= requests。

1.3 QoS(服务质量)类别

Kubernetes 根据 requests 和 limits 的组合将 Pod 分为三类,决定了资源紧张时驱逐的顺序:

QoS 类别 条件 驱逐优先级(最低→高)

Guaranteed 每个容器同时设置了 CPU 和内存的 requests 和 limits,且两者相等 最后驱逐

Burstable 至少一个容器设置了 requests,但并非 Guaranteed 中间

BestEffort 没有设置任何 requests 和 limits 最先驱逐

示例:

Guaranteed:requests.memory=256Mi, limits.memory=256Mi(CPU 同理)

Burstable:requests.cpu=250m 但无 limits,或 requests 与 limits 不等

BestEffort:完全不写 resources 字段

生产环境关键服务应使用 Guaranteed,以确保稳定性。

二、ResourceQuota:命名空间级别的资源总量限制

ResourceQuota 用来限制一个命名空间内所有 Pod 的累计资源使用量,防止某个命名空间耗尽集群资源。

2.1 创建 ResourceQuota

yaml 复制代码
apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-quota
  namespace: dev
spec:
  hard:
    requests.cpu: "4"
    requests.memory: "8Gi"
    limits.cpu: "8"
    limits.memory: "16Gi"
    persistentvolumeclaims: "10"
    pods: "20"

除了 CPU/内存,还可以限制 PVC 数量、Service 数量、ConfigMap 数量等。

当命名空间内资源请求总和超过配额时,新的 Pod 创建会失败(提示 exceeded quota)。

2.2 查看 ResourceQuota 使用情况

bash 复制代码
kubectl describe resourcequota -n dev

输出会显示当前使用量 / 总配额。

2.3 与 LimitRange 配合

如果命名空间设置了 ResourceQuota,通常要求每个 Pod 必须指定 requests/limits,否则无法创建。可以通过 LimitRange 自动设置默认值。

三、LimitRange:为 Pod 设置默认资源和范围约束

LimitRange 用于在命名空间级别为 Pod 或容器提供默认的 requests/limits,或者约束其取值范围。

3.1 创建 LimitRange

yaml 复制代码
apiVersion: v1
kind: LimitRange
metadata:
  name: dev-limits
  namespace: dev
spec:
  limits:
  - default:                # 如果 Pod 未指定 limits,使用此默认值
      cpu: "500m"
      memory: "512Mi"
    defaultRequest:         # 如果 Pod 未指定 requests,使用此默认值
      cpu: "250m"
      memory: "256Mi"
    max:                    # 允许的最大值
      cpu: "2"
      memory: "4Gi"
    min:                    # 允许的最小值
      cpu: "100m"
      memory: "128Mi"
    type: Container

type 可以是 Container 或 Pod(Pod 级别限制不常用)。

创建 LimitRange 后,后续创建的 Pod 如果未指定资源,会自动注入默认值;如果指定了超出 max/min 范围的值,API Server 会拒绝创建。

3.2 查看 LimitRange

bash 复制代码
kubectl describe limitrange -n dev

四、实战:配置一个带资源约束的命名空间

假设我们为开发团队创建一个 dev 命名空间,限制总资源不超过 4 核 CPU、8G 内存,同时要求每个容器至少 128Mi 内存,最多 1G 内存,未指定则使用默认值。

步骤:

bash 复制代码
kubectl create namespace dev

创建 limit-range.yaml:

yaml 复制代码
apiVersion: v1
kind: LimitRange
metadata:
  name: dev-limits
  namespace: dev
spec:
  limits:
  - default:
      cpu: "500m"
      memory: "512Mi"
    defaultRequest:
      cpu: "250m"
      memory: "256Mi"
    max:
      cpu: "1"
      memory: "1Gi"
    min:
      cpu: "100m"
      memory: "128Mi"
    type: Container

创建 resource-quota.yaml:

yaml 复制代码
apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-quota
  namespace: dev
spec:
  hard:
    requests.cpu: "4"
    requests.memory: "8Gi"
    limits.cpu: "8"
    limits.memory: "16Gi"
    pods: "10"

应用配置:

bash 复制代码
kubectl apply -f limit-range.yaml -f resource-quota.yaml

测试 Pod:

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: test
  namespace: dev
spec:
  containers:
  - name: app
    image: nginx
复制代码
# 未指定 resources,会使用 LimitRange 默认值

创建后查看配额:

bash 复制代码
kubectl get resourcequota -n dev

五、最佳实践总结

每个容器都要设置 requests 和 limits,至少设置 memory limits(防止内存泄漏拖垮节点)。

为命名空间配置 ResourceQuota,在多租户环境下尤为重要。

为命名空间配置 LimitRange,强制用户提交的资源在合理范围内,并提供默认值。

关键服务使用 Guaranteed QoS(requests = limits)。

定期监控资源使用:kubectl top nodes、kubectl top pods。

避免在同一个命名空间混用 Guaranteed 和 BestEffort,可能导致资源挤占。

六、常见问题

七、小结

资源管理是 Kubernetes 生产化的重要一环。通过 requests / limits 控制单容器资源,ResourceQuota 限制命名空间总量,LimitRange 提供默认值和范围约束,你可以构建一个稳定、公平的多租户集群。

相关推荐
Jerry39 分钟前
LeetCode 707. 设计链表
算法
C语言小火车1 小时前
C++ 堆排序深度精讲:基于完全二叉树的选择排序进化,最坏情况 O(n log n) 的稳定王者
开发语言·c++·算法·排序算法·堆排序
kebidaixu1 小时前
两轮BMS AFE SH367306 I2C 读写时序
算法
智能排队系统_头部供应商1 小时前
RK3588边缘网关改造银行排队系统实战
算法
Fabarta1 小时前
从 0 实现 ChatGPT 风格的流式对话 UI
算法·架构
手写码匠2 小时前
手写 AI 上下文压缩系统:从零实现 Prompt 压缩与选择性上下文管理
人工智能·深度学习·算法·aigc
EAI-Robotics2 小时前
机器人操作鲁棒性:当机械手遇上真实世界的不确定性
人工智能·算法·机器人
Tairitsu_H3 小时前
[LC优选算法#17] 链表 | 合并 K 个升序链表 | K个⼀组翻转链表
数据结构·算法·链表
_olone3 小时前
Luogu P2704 [NOI2001] 炮兵阵地
c++·算法·状压dp
kebidaixu4 小时前
两轮BMS 防打火策略详解
算法