ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

【Kubernetes从入门到精通】第31篇:LimitRange——给你的Namespace画个“圈“

【Kubernetes从入门到精通】第31篇:LimitRange——给你的Namespace画个“圈“ 上一篇【第30篇】oS——K8s的“三六九等“资源优先级下一篇【第32篇】ResourceQuota——多团队共享集群的公平秤摘要上两篇咱们把requests/limits和QoS掰碎讲了你学会了怎么给Pod配资源和资源紧张时谁先死。但问题来了在一个多人共享的集群里你怎么保证每个人都会乖乖给Pod配资源有的同事抄了个网上的YAML就deploy什么resources都没写——结果搞出个BestEffort Pod资源紧张时第一个被杀有的同事写requests: cpu: 1m, limits: cpu: 100Gi——比例离谱到姥姥家了。LimitRange就是来管这茬的。它作用在Namespace级别像一个管理员一样盯着每个Pod创建——你忘了写requests我给你补个默认值。你requests设太小最小值不允许。你limits/requests比例太大直接拒绝创建。这篇文章从LimitRange的四种限制项Min/Max/Default/DefaultRequest讲起再到MaxLimitRequestRatio的精妙设计最后实战给两个团队分别画圈——开发环境宽松点生产环境严格点。一、LimitRange解决什么问题——“管不住的手”1.1 没有LimitRange的世界有多乱【没有LimitRange时——法外之地】 Namespace: production号称生产环境 ┌─────────────────────────────────────────────────────────┐ │ │ │ 张三创建的Pod 李四创建的Pod │ │ ┌───────────────────┐ ┌───────────────────┐ │ │ │ resources: {} │ │ resources: │ │ │ │ → BestEffort │ │ requests: │ │ │ │ → 没任何保护 │ │ cpu: 1m │ │ │ │ → OOM时第一个死 │ │ memory: 1Mi │ │ │ └───────────────────┘ │ limits: │ │ │ │ cpu: 100000m │ │ │ 王五创建的Pod │ memory: 1Ti │ │ │ ┌───────────────────┐ │ → 比例失衡 │ │ │ │ resources: │ └───────────────────┘ │ │ │ requests: │ │ │ │ cpu: 100m │ │ │ │ limits: │ 结果 │ │ │ cpu: 10000m │ • BestEffort Pod随时被杀 │ │ │ → limits大爆炸 │ • 1m request占位但不干活 │ │ │ → 可能抢占资源 │ • 10000m limit可能压死其他Pod │ │ └───────────────────┘ │ └─────────────────────────────────────────────────────────┘ Scheduler看了直摇头你们这个Namespace怎么啥配置都有啊1.2 LimitRange怎么管——“四条规矩”【LimitRange的四种限制——给每个Pod上箍】 ┌─────────────────────────────────────────────────────────┐ │ LimitRange 四条规矩 │ │ │ │ 1. Min最小值 │ │ ┌─────────────────────────────────────────────┐ │ │ │ requests.cpu 至少 100m别想拿1m糊弄我 │ │ │ │ limits.memory 至少 128Mi太低没有意义 │ │ │ └─────────────────────────────────────────────┘ │ │ │ │ 2. Max最大值 │ │ ┌─────────────────────────────────────────────┐ │ │ │ limits.cpu 最多 4000m别写100000m扛不住 │ │ │ │ requests.memory 最多 16Gi控制单个Pod │ │ │ └─────────────────────────────────────────────┘ │ │ │ │ 3. Default默认值——没设limits时的自动填充 │ │ ┌─────────────────────────────────────────────┐ │ │ │ 忘了写limits.cpu帮你填500m │ │ │ │ 忘了写limits.memory帮你填512Mi │ │ │ └─────────────────────────────────────────────┘ │ │ │ │ 4. DefaultRequest默认值——没设requests时的自动填充 │ │ ┌─────────────────────────────────────────────┐ │ │ │ 忘了写requests.cpu帮你填200m │ │ │ │ 忘了写requests.memory帮你填256Mi │ │ │ └─────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────┘二、LimitRange的四种限制详解2.1 完整配置示例——“四条规矩一次写清楚”apiVersion:v1kind:LimitRangemetadata:name:production-limitsnamespace:production# ← 作用域只管这个Namespacespec:limits:# # 第1条限制Container级别的资源# -type:Container# Min——资源不能低于这个值min:cpu:100m# 至少 0.1 核memory:128Mi# 至少 128Mi 内存# Max——资源不能超过这个值max:cpu:4000m# 最多 4 核memory:16Gi# 最多 16Gi 内存# Default——没写limits时自动补这个default:cpu:500m# 默认最多用 0.5 核memory:512Mi# 默认最多用 512Mi# DefaultRequest——没写requests时自动补这个defaultRequest:cpu:200m# 默认保证 0.2 核memory:256Mi# 默认保证 256Mi# MaxLimitRequestRatio——limits最多是requests的几倍maxLimitRequestRatio:cpu:4# CPU: limits/requests ≤ 4memory:2# 内存: limits/requests ≤ 2# 合法requests500m, limits2000m → ratio4 ✓# 非法requests100m, limits2000m → ratio20 ✗被拒绝# # 第2条限制Pod级别的资源所有容器总和# -type:Podmax:cpu:8000m# 整个Pod最多8核所有容器总和memory:32Gi# 整个Pod最多32Gi# # 第3条限制PVC存储大小# -type:PersistentVolumeClaimmin:storage:1Gi# PVC最少申请1Gimax:storage:100Gi# PVC最多申请100Gi2.2 各限制项的执行效果# 场景1Pod忘了写resources——自动补默认值kubectl apply-f-EOF apiVersion: v1 kind: Pod metadata: name: no-resources spec: containers: - name: nginx image: nginx # 什么resources都没写 EOF# 查看效果——LimitRange自动填充了kubectl get pod no-resources-oyaml|grep-A10resources# resources:# limits:# cpu: 500m ← 自动补的 default# memory: 512Mi ← 自动补的 default# requests:# cpu: 200m ← 自动补的 defaultRequest# memory: 256Mi ← 自动补的 defaultRequest# 场景2requests低于min——拒绝创建kubectl apply-f-EOF apiVersion: v1 kind: Pod metadata: name: too-small spec: containers: - name: nginx image: nginx resources: requests: cpu: 10m # ← 低于 min 的 100m memory: 64Mi # ← 低于 min 的 128Mi EOF# 结果Pod创建失败# Error: Pod too-small is invalid:# spec.containers[0].resources.requests[cpu]:# Invalid value: 10m: must be greater than or equal to cpu limit# 场景3limits/requests比例超限——拒绝创建kubectl apply-f-EOF apiVersion: v1 kind: Pod metadata: name: ratio-violation spec: containers: - name: nginx image: nginx resources: requests: cpu: 100m limits: cpu: 10000m # ← 100倍MaxLimitRequestRatio4 EOF# Error: ratio violation: cpu limit/request ratio of 100 exceeds max of 4要点Default和DefaultRequest只在用户没写那个字段时才生效。如果用户写了requests但没写limits——limits会用default补requests保持用户写的值。如果用户写了limits但没写requests——requests会用defaultRequest补如果defaultRequest≤limits的话。2.3 验证LimitRange的生效# 查看Namespace下的LimitRangekubectl get limitrange-nproduction# NAME CREATED AT# production-limits 2026-07-28T10:00:00Z# 查看详情kubectl describe limitrange production-limits-nproduction# Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio# ---- -------- --- --- --------------- ------------- -----------------------# Container cpu 100m 4000m 200m 500m 4# Container memory 128Mi 16Gi 256Mi 512Mi 2# 查看Namespace下的所有LimitRange注解Pod创建后会带上这些信息kubectl get pod my-pod-nproduction-oyaml|grep-A5annotations# annotations:# kubernetes.io/limit-ranger: LimitRanger plugin set: cpu request for container app2.4 对比表四种限制项的语义限制项作用对象用户没写时用户写了但不符合时典型用途minrequests/limits的最小值不作用拒绝创建防止占坑小Pod——requests1m骗过Schedulermaxrequests/limits的最大值不作用拒绝创建防止单个Pod吃掉所有资源defaultlimits的默认值自动填充不作用用户写了就用用户的防止BestEffort Pod——至少有个limitsdefaultRequestrequests的默认值自动填充不作用防止漏设requests导致的调度偏差maxLimitRequestRatiolimits/requests的比例上限不作用拒绝创建防止极度不平衡配置三、MaxLimitRequestRatio——“别想钻空子”3.1 为什么要限制比例【没有MaxLimitRequestRatio时——聪明人怎么钻空子】 场景集群管理者说所有Pod必须设requests和limits 聪明人的做法 ┌─────────────────────────────────────────────────┐ │ resources: │ │ requests: │ │ cpu: 1m # ← 拿1m糊弄Scheduler │ │ memory: 1Mi │ │ limits: │ │ cpu: 8000m # ← 实际可以用8核 │ │ memory: 32Gi │ │ │ │ 效果Scheduler看Node剩了3500m │ │ 1m vs 3500m → 调上来 │ │ 实际运行时用了8000m → 其他Pod全throttle │ └─────────────────────────────────────────────────┘ 有了MaxLimitRequestRatio之后 ┌─────────────────────────────────────────────────┐ │ maxLimitRequestRatio: │ │ cpu: 4 # limits最多是requests的4倍 │ │ memory: 2 # 内存最多2倍 │ │ │ │ requests: 1m, limits: 8000m → ratio: 8000 ✗ │ │ requests: 2000m, limits: 8000m → ratio: 4 ✓ │ └─────────────────────────────────────────────────┘3.2 ratio的合理配置# 不同环境的推荐比率---# 生产环境——严格apiVersion:v1kind:LimitRangemetadata:name:strict-limitsnamespace:productionspec:limits:-type:ContainermaxLimitRequestRatio:cpu:3# ← 生产环境保守最多3倍memory:1.5# ← 内存更严格最多1.5倍# 意味着如果你要配request为1Gi内存limits最多1.5Gi# 原因生产环境内存超售不能太大否则OOM风险高---# 开发环境——宽松apiVersion:v1kind:LimitRangemetadata:name:relaxed-limitsnamespace:developmentspec:limits:-type:ContainermaxLimitRequestRatio:cpu:10# ← 开发环境允许10倍memory:4# ← 内存允许4倍# 原因开发环境burst需求大资源利用率不用太精确四、实战——多租户资源限制方案4.1 方案设计——“给每个团队画不一样的圈”【多租户Namespace资源规划】 集群总资源20核CPU, 64Gi内存4台4C/16Gi Node ┌─────────────────────────────────────────────────────────┐ │ │ │ ┌───────────────────────┐ ┌───────────────────────┐ │ │ │ Namespace: team-a │ │ Namespace: team-b │ │ │ │ (核心业务团队) │ │ (数据分析团队) │ │ │ │ │ │ │ │ │ │ LimitRange: │ │ LimitRange: │ │ │ │ • min: 100m/128Mi │ │ • min: 50m/64Mi │ │ │ │ • max: 4C/16Gi │ │ • max: 4C/32Gi │ │ │ │ • default: 500m/512Mi │ │ • default: 1C/2Gi │ │ │ │ • defaultReq:200m/256Mi│ │ • defaultReq:500m/1Gi │ │ │ │ • ratio: 2/1.5 │ │ • ratio: 4/2 │ │ │ │ │ │ │ │ │ │ 风格小而精致 │ │ 风格大而粗放 │ │ │ │ 服务多但每个不占太多 │ │ 任务少但每个要很多资源 │ │ │ └───────────────────────┘ └───────────────────────┘ │ │ │ │ ┌───────────────────────┐ ┌───────────────────────┐ │ │ │ Namespace: dev │ │ Namespace: staging │ │ │ │ (开发测试) │ │ (预发布) │ │ │ │ │ │ │ │ │ │ LimitRange: │ │ LimitRange: │ │ │ │ • min: 10m/32Mi │ │ • min: 50m/64Mi │ │ │ │ • max: 2C/4Gi │ │ • max: 4C/16Gi │ │ │ │ • default: 200m/256Mi │ │ • default: 500m/512Mi │ │ │ │ • defaultReq:100m/128Mi│ │ • defaultReq:200m/256Mi│ │ │ │ • ratio: 10/4 │ │ • ratio: 4/2 │ │ │ │ │ │ │ │ │ │ 风格尽量省资源 │ │ 风格接近生产 │ │ │ └───────────────────────┘ └───────────────────────┘ │ └─────────────────────────────────────────────────────────┘4.2 完整配置代码# # team-a 的 LimitRange核心业务团队# apiVersion:v1kind:LimitRangemetadata:name:team-a-limitsnamespace:team-aspec:limits:-type:Containermin:cpu:100mmemory:128Mimax:cpu:4000m# 最多4核——防止单个Pod吃太多memory:16Gidefault:cpu:500mmemory:512MidefaultRequest:cpu:200mmemory:256MimaxLimitRequestRatio:cpu:2# CPU严格——防止超售太多memory:1.5# 内存更严格——OOM很可怕-type:Podmax:cpu:8000m# 整个Pod(含Sidecar)最多8核memory:32Gi---# # team-b 的 LimitRange数据分析团队# apiVersion:v1kind:LimitRangemetadata:name:team-b-limitsnamespace:team-bspec:limits:-type:Containermin:cpu:50m# 允许更小的Podmemory:64Mimax:cpu:4000mmemory:32Gi# 数据任务需要更多内存default:cpu:1000m# 默认给大点——数据任务CPU需求高memory:2Gi# 默认给2Gi——数据任务内存需求也高defaultRequest:cpu:500mmemory:1GimaxLimitRequestRatio:cpu:4# 宽松点——数据任务需要burstmemory:2---# # dev 的 LimitRange开发环境尽量省资源# apiVersion:v1kind:LimitRangemetadata:name:dev-limitsnamespace:devspec:limits:-type:Containermin:cpu:10m# 开发环境可以用很小memory:32Mimax:cpu:2000m# 开发环境限制上限memory:4Gidefault:cpu:200mmemory:256MidefaultRequest:cpu:100mmemory:128MimaxLimitRequestRatio:cpu:10# 开发环境放开ratio——burst随便用memory:4# 应用配置kubectl apply-fteam-a-limits.yaml kubectl apply-fteam-b-limits.yaml kubectl apply-fdev-limits.yaml# 验证各Namespace的LimitRangekubectl get limitrange --all-namespaces# NAMESPACE NAME CREATED AT# team-a team-a-limits 2026-07-28T10:00:00Z# team-b team-b-limits 2026-07-28T10:00:00Z# dev dev-limits 2026-07-28T10:00:00Z# 测试在team-a里创建违反LimitRange的Podkubectl apply-nteam-a-f-EOF apiVersion: v1 kind: Pod metadata: name: bad-pod spec: containers: - name: nginx image: nginx resources: requests: cpu: 5m # ← 低于team-a的min(100m) EOF# Error from server (Forbidden): error when creating STDIN:# pods bad-pod is forbidden: minimum cpu usage per Container is 100m,# but request is 5m要点LimitRange的Default和DefaultRequest有个重要特性——它们只在API Server接受创建请求时生效修改LimitRange不对已有Pod产生任何影响。如果你想让已有Pod也按新规矩来得重建它们删除让Deployment重建。五、LimitRange常用操作速查# 查看Namespace下的所有LimitRangekubectl get limitrange-nproduction# 查看详细配置kubectl describe limitrange production-limits-nproduction# 导出为YAML备份/迁移用kubectl get limitrange production-limits-nproduction-oyamlbackup.yaml# 修改LimitRangekubectl edit limitrange production-limits-nproduction# 删除LimitRangekubectl delete limitrange production-limits-nproduction# 查看Pod是否被LimitRange修改过kubectl describe pod my-pod-nproduction|grep-ilimit# 或者看 annotations:kubectl get pod my-pod-nproduction-ojsonpath{.metadata.annotations}# {kubernetes.io/limit-ranger:LimitRanger plugin set: cpu, memory...}# 测试干跑一个Pod看看会不会被LimitRange拒绝kubectl apply-fmy-pod.yaml --dry-runserver-nproduction# 如果配置不合规这里就会报错不会实际创建本篇小结LimitRange是Namespace级别的资源管理员自动纠偏、强制约束四种限制Min下限、Max上限、Default自动补limits、DefaultRequest自动补requests——每种管不同的事MaxLimitRequestRatio是防止钻空子的利器——防止有人用极小request极大limit绕过调度Default和DefaultRequest的妙用只要用户忘了写resourcesLimitRange就自动补——确保每个Pod至少是Burstable不同环境不同策略生产严格ratio≤2-3、开发宽松ratio可达10按团队需求定制只管新建Pod——修改LimitRange不影响已有Pod要生效就得重建LimitRange管的是单个Pod怎么配资源但集群管理者还需要整个Namespace能用多少资源——接下来咱们聊ResourceQuota多团队共享集群的公平秤。上一篇【第30篇】oS——K8s的“三六九等“资源优先级下一篇【第32篇】ResourceQuota——多团队共享集群的公平秤
返回列表