K8s-kubernetes(二)资源限制-详细介绍

K8s如何合理规定对象资源使用

基本概念

  • Kubernetes中,占用资源最小单元单个Pod
  • Kubernetes中,资源占用 主要针对服务器CPU内存

为什么要做资源限制

  • 对于Kubernetes集群而言,所有Pod都会占用K8s集群所在服务器的资源,如果不做资源控制,则很有可能出现某些Pod无限制占用资源(CPU、内存),导致系统崩溃

资源限制设置方式

Pod、Container级别控制

关键参数:request、limits
  • request参数

    • controller做调度时,创建Pod最低资源占用标准
  • limits参数

    • 单个Pod运行时的资源占用上限 --真正限制资源可用到多少
    • 当容器试图使用超过limits指定的CPU时会被 CFS 限流 ;试图使用超过limits指定的内存时会被 OOM Killer 杀掉并重启
使用示例
yml 复制代码
	apiVersion: v1
	kind: Pod
	metadata:
	  name: demo-pod
	spec:
	  containers:
	  - name: app
	    image: nginx:latest
	    resources: # k8s中定义资源规格的关键字,主要针对CPU和内存
	      requests: # Pod最低的资源占用。调度器在将Pod指派给某个节点时,会检查该节点"可分配资源"是否满足request要求
	        cpu: "100m"        # 0.1 核
	        memory: "128Mi"    # 128 MB
	      limits: # Pod运行时的最大资源使用上限,
	        cpu: "500m"        # 0.5 核(上限)
	        memory: "256Mi"    # 256 MB(上限)

命名空间级别控制

关键策略对象:LimitRange
  • 在命名空间级别,可以使用LimitRange 给整个命名空间设置默认值/最大值
  • LimitRange不仅仅是默认值 的概念,也是一道硬性检查
    • 默认值 :如果 Pod 或容器未显式声明 requests 或 limits,LimitRange 会自动注入默认值
    • 硬性检查 :如果Pod或容器显式声明了request或者limits,但是不在 LimitRange的允许范围内不允许创建Pod
使用示例
yml 复制代码
apiVersion: v1
kind: LimitRange  #LimitRange类型对象
metadata:
  name: cpu-mem-limit #LimitRange对象名称
  namespace: dev #该策略适用的命名空间
spec: #定义策略具体规则
  limits: #limits为一个列表,可以包含多个限制策略
  - type: Container #表示该限制针对的是容器级别,而不是Pod或其他级别
    min: #指定容器资源的最小值,如果容器请求的资源低于这个值,K8s 会拒绝创建
      cpu: 100m #最少请求 0.1 个 CPU 核心
      memory: 128Mi #最少请求128M内存
    max: #超过这个值的容器会被拒绝创建
      cpu: 1 #最大请求1个CPU核心
      memory: 1Gi #最大请求1G内存
    default: #默认配置,当容器和Pod没有显式声明resources.limits,自动使用这里配置的默认值
      cpu: 500m #当容器和Pod没有显式声明resources.limits,默认resources.limits.cpu=500m
      memory: 512Mi #当容器和Pod没有显式声明resources.limits,默认resources.limits.memory=512Mi 
    defaultRequest: #默认配置,当容器和Pod没有显式声明resources.request,默认的requests数量,request: Pod最低的资源占用。调度器在将Pod指派给某个节点时,会检查该节点"可分配资源"是否满足request要求
      cpu: 200m
      memory: 256Mi
    maxLimitRequestRatio: #限制比例:限制与请求的最大比例,控制 limit/request 的最大比例。作用:防止用户设置过高的 limit 而请求很低的资源,防止节点资源被过度使用或者其他Pod的资源无法保证
      cpu: 2 # CPU的限制值不能超过请求值的2倍。如果请求是250M内存,则限制不能超过500M。如果超过这个比例,Pod 会被拒绝创建

命名空间/集群级别总量限制

关键对象:ResourceQuota
  • ResourceQuota 是一种命名空间级别硬限制 机制,作用是给每个命名空间设定资源总量红线
  • 一旦配额用满 ,任何导致超配的对象创建都会被拒绝,包括通过Deployment、StatefulSet等控制器间接创建的Pod
ResourceQuota作用范围
  • ResourceQuota控制的是集群节点级别的总量,还是命名空间的总量?
    • ResourceQuota控制的是单个命名空间 资源的总量
    • 如果希望控制集群节点级别,需要多命名空间+ResourceQuota集群级策略(如 ClusterPolicy、PodNodeSelector、多集群联邦)来实现
ResourceQuota和LimitRange有什么区别
  • ResourceQuota 限制的是整个命名空间 资源的总量
  • LimitRange 限制的是这个命名空间内,单个资源限制量默认值
  • 两者需要结合使用才能达到最佳效果
使用示例
  1. 确保准入控制器已启用
    • 大多数发行版默认已包含 --enable-admission-plugins=ResourceQuota;若手动搭建,需在 kube-apiserver 启动参数里加入
  2. 编写YML并应用
yml 复制代码
apiVersion: v1
kind: ResourceQuota #类型为ResourceQuota
metadata:
  name: team-a-quota #名称
  namespace: team-a #作用的命名空间
spec:
  hard: #hard 是一个 map,key 是被限制的资源类型,value 是字符串形式的硬性上限
    requests.cpu: "20" #该命名空间内所有 非终止状态 Pod 的 spec.containers[*].resources.requests.cpu 之和 ≤ 20 CPU(= 20 核)
    requests.memory: 40Gi #所有 Pod 的 requests.memory 总和 ≤ 40 GiB
    limits.cpu: "40" #所有 Pod 的 limits.cpu 总和 ≤ 40 核
    limits.memory: 80Gi #所有 Pod 的 limits.memory 总和 ≤ 80 GiB
    pods: "50" #命名空间里当前存在的 Pod 对象数量 ≤ 50 个(Running / Pending / Succeeded 都算,Failed 或 Completed 且 TTL 已过的不算)
    persistentvolumeclaims: "10" #PVC 对象总数 ≤ 10 个
    count/deployments.apps: "15" #apps/v1 组下的 Deployment 对象 ≤ 15 个
  1. 查看配额使用/剩余
bash 复制代码
kubectl describe quota <ResourceQuota名称> -n <命名空间>

引申问题1:LimitRange限制了容器最大使用资源,如果使用中超过这个限制,会发生什么

  • 结论
    • 最终表现是容器会被OOMKilled
  • 原因
    • LimitRange 属于准入控制 ,即在Pod创建/更新 时作限制校验 ,如果超出或低于限制要求,则不允许创建
    • Pod创建完后LimitRange任务结束,不再发挥作用
    • 实际的运行时限制,是由cgroup 和 kubelet 负责 ,限制的方式也不是拒绝分配,而是直接杀掉

引申问题2:如果容器资源一旦超限就OOMKilled,如何保证应用稳定性?

  1. 预估
    • 在配置上线前,充分压测评估出最大峰值
    • 给足安全余量,一般要在压测峰值上再加20%-50%作为安全余量
  2. 观察
    • 上线后持续观察,并设置预警措施
  3. 调优
    • 发现不足就及时调大,并滚动升级
    • 垂直扩容(加大limit限制值)
    • 水平扩容(拆业务、分片、增加副本数,降低单实例负载)
    • 应用层优化(减少缓存大小、调整GC参数、使用内存池、对象复用)**
  4. 兜底
    • 保证即使有实例被OOMKilled,其余实例还可以承载流量

引申问题3:LimitRange 和 ResourceQuota 对已有 Pod 有什么影响

这是一个非常重要的问题,涉及 Kubernetes 中资源限制策略的生效范围和时效性

✅ 1. LimitRange 对已有 Pod 的影响
  • 不会影响已存在的 Pod
  • LimitRange 只在 新创建的 Pod 或容器 时生效。
  • 它的作用是在 Pod 创建时:
    • 自动补全 resources.requestsresources.limits
    • 验证资源是否在允许范围内。

🔍 如果已有 Pod 的资源配置超过了 LimitRange 的 max 限制

  • 不会强制修改或终止这些 Pod。
  • 它们会继续运行,直到被手动删除或更新。
  • 只有在重新创建或更新 Pod 时,才会触发 LimitRange 的验证。

✅ 2. ResourceQuota 对已有 Pod 的影响
  • 不会强制终止或修改已存在的 Pod
  • ResourceQuota 是针对命名空间资源总量的限制。
  • 它在创建新资源时检查是否超过配额。

🔍 如果已有资源已经超过了配额限制

  • 不会影响这些资源的运行。
  • 无法再创建新的资源,直到资源使用量低于配额。

🧠 举个例子

假设你在 dev 命名空间中设置了如下配额:

yaml 复制代码
limits.cpu: "4"

而已有 Pod 总共使用了 5 个 CPU:

  • ✅ 已有 Pod 不会被删除或停止。
  • ❌ 新 Pod 无法创建,除非已有 Pod 被删除或资源使用量降低。

📌 总结
特性 LimitRange ResourceQuota
是否影响已有 Pod ❌ 不影响 ❌ 不影响
是否影响新建 Pod ✅ 生效 ✅ 生效
是否强制修改已有资源 ❌ 不会 ❌ 不会
是否阻止新资源创建 ✅(不符合规则) ✅(超出配额)

✅ 建议做法
  • 在设置 LimitRangeResourceQuota 前,先评估当前命名空间资源使用情况。
  • 使用 kubectl describe quotakubectl top pod 查看资源使用。
  • 如果想让"老 Pod"也受新限制,只能人工或自动化地做:手动滚动重启 Deployment/StatefulSet → 新 Pod 走新规则。
  • 配合策略引擎(如 Kyverno)实现更强的资源治理。

注意事项

  1. LimitRange 和 ResourceQuota设置前,已有存在的pod,这部分Pod不会不受影响
  2. 一个命名空间建议只创建一个
  3. 多租户集群,防止某个用户的 Pod 占用过多资源
  4. CICD环境,限制测试 Pod 的最大资源,防止资源争抢
  5. 为未声明资源的容器自动分配合理默认值,避免调度失败
相关推荐
钱彬 (Qian Bin)8 分钟前
项目实践14—全球证件智能识别系统(切换回SQLite数据库并基于Docker实现离线部署和日常管理)
运维·docker·容器·fastapi·证件识别
sld1681 小时前
打破云服务“绑定”局限,打造高适配性、强管控力的混合云架构新范式
微服务·云原生·架构
VermiliEiz1 小时前
二进制文件部署k8s方式(4)
云原生·容器·kubernetes
openFuyao2 小时前
参与openFuyao嘉年华,体验开源开发流程,领视频年卡会员
人工智能·云原生·开源·开源软件·多样化算力
牛奔2 小时前
docker compose up 命令,默认配置文件自动查找规则
java·spring cloud·docker·容器·eureka
BigBigHang2 小时前
【docker】离线设备安装镜像
运维·docker·容器
学好statistics和DS2 小时前
Docker文件与本地文件,系统
运维·docker·容器
liuc03172 小时前
docker下安装SearXNG
运维·docker·容器
oMcLin2 小时前
如何在CentOS 8上配置并优化Docker与Kubernetes结合的容器集群,提升微服务部署效率?
docker·kubernetes·centos
DencyCheng3 小时前
Nacos 的全面价值分析:从多角色视角到多架构场景的深度解析
微服务·架构