第十一篇:《资源管理: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 提供默认值和范围约束,你可以构建一个稳定、公平的多租户集群。

相关推荐
Eloudy几秒前
预词力:LLM 的唯一形式化能力
人工智能·算法·agent
依然鸣18 分钟前
PTA团体程序设计天梯赛L1真题讲解L1-085-088
数据结构·c++·经验分享·算法·深度优先·pat考试
听取WA声一片(无恶意)1 小时前
CSP-J/S 初赛图论完全讲义
算法·csp-s初赛·csp-j初赛
Brilliantwxx1 小时前
【算法从零到千】【51-54】逆序对(分治+递归算法)
数据结构·算法·排序算法
小星星闪亮登场1 小时前
2026河南萌新联赛第四场--南阳理工学院
数据结构·算法·贪心算法·动态规划·哈希算法·广度优先
土司大王1 小时前
LeetCode hot100——两数之和
数据结构·算法·leetcode
luj_17681 小时前
大航海时代:沉浸式财商实战沙盒
c语言·开发语言·网络·经验分享·算法
Navigator_Z2 小时前
LeetCode //C - 1200. Minimum Absolute Difference
c语言·算法·leetcode
wabs6662 小时前
关于字符串【力扣344.反转字符串的思考】
数据结构·算法·leetcode
民乐团扒谱机3 小时前
【微实验】谐波乘积谱(HPS)算法深度解析:原理、数学与代码实现
开发语言·人工智能·python·算法·语音识别·音乐