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

相关推荐
Tisfy1 小时前
LeetCode 2095.删除链表的中间节点:两次遍历 / 一次遍历(快慢指针)
算法·leetcode·链表·题解·双指针
Irissgwe1 小时前
AVL树详解
数据结构·c++·算法·二叉树·c·二叉搜索树·avl
凌波粒1 小时前
LeetCode--131.分割回文串(回溯算法)
算法·leetcode·职场和发展
北域码匠2 小时前
奇偶归并排序:并行计算的排序利器
数据结构·算法·c#·排序算法
成都易yisdong2 小时前
上海某平面坐标系与CGCS2000坐标互转详解(含全域拟合点、实战案例、保密规范)
大数据·人工智能·算法
2601_961845152 小时前
花生十三网课网盘|百度网盘|下载
数据结构·算法·链表·贪心算法·排序算法·线性回归·动态规划
快手技术2 小时前
征集令|快手探索者LLM-Rec挑战赛正式发布!
算法
Yvonne爱编码2 小时前
JAVA EE初阶---DAY 2 计算机网络
java·开发语言·计算机网络·算法·java-ee·php
workflower3 小时前
基于机器学习的设备故障预测分析方法
人工智能·算法·机器学习·设计模式·语言模型·自然语言处理·重构