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

相关推荐
Zachery Pole5 小时前
CCF-CSP备战NO.7【队列】
算法
闪电悠米6 小时前
力扣hot100-48.旋转图像-转置翻转详解
算法·leetcode·职场和发展
满天星83035776 小时前
【算法】最长递增子序列(三种解法)
算法
啦啦啦啦啦zzzz7 小时前
算法:贪心算法
c++·算法·leetcode·贪心算法
清泓y8 小时前
RAG 技术
算法·ai
阿慧今天瘦了嘛8 小时前
计算机组成原理概述:从硬件到软件的桥梁
计算机网络·算法
网站优化(SEO)专家9 小时前
SEO核心算法拆解:网站排名快速提升的武林秘籍!
算法·搜索引擎·网站排名·核心算法
惊讶的猫9 小时前
CLGSI
人工智能·算法·机器学习
无限码力10 小时前
华为非AI方向笔试真题 7月15号【字符补全】
算法·华为·华为笔试真题·华为非ai笔试真题·华为笔试·华为笔试非ai真题
ysa05103010 小时前
【板子】二分答案(最大最小?)
c++·笔记·算法·板子