bigywater.tech
Kubernetes · 40

LimitRange:默认值和上下限怎么注入

没写 resources 的 Pod 是怎么得到 requests 和 limits 的?默认值太离谱会怎样?越界的请求怎么被拒绝?这篇建一个 LimitRange,把默认值、部分指定、越界拒绝、PVC 范围以及“改了之后只影响新 Pod”这几件事逐个跑出来,还撞上了一个默认值与比例冲突的坑。

ratio is 5.000000
默认 limit/request 的比例超过 maxLimitRequestRatio 时,连什么都没写的 Pod 也被拒绝
request = limit
只写了 limits.cpu 时,requests.cpu 取同样的值(200m)而不是 defaultRequest
只影响新 Pod
修改 LimitRange 的默认值之后,已有的 Pod 保持原样

默认值与它自己的约束

实测 · 本机执行输出
  默认 limit cpu 500m、默认 request cpu 100m(比例 5,而 maxLimitRequestRatio 是 4):创建 Pod plain 退出码 1;Error from server (Forbidden): error when creating "STDIN": pods "plain" is forbidden: cpu max limit to request ratio per Container is 4, but provided ratio is 5.000000
  把默认 limit 改成 cpu 400m(比例 4)之后:
  Pod plain(没写 resources):requests={'cpu': '100m', 'memory': '128Mi'} limits={'cpu': '400m', 'memory': '256Mi'} qos=Burstable
  注解:{'kubernetes.io/limit-ranger': 'LimitRanger plugin set: cpu, memory request for container c; cpu, memory limit for container c'}

LimitRange 声明:容器默认 limit cpu 500m / memory 256Mi,默认 request cpu 100m / memory 128Mi,maxLimitRequestRatio cpu 为 4。结果什么都没写的 Pod 被拒了:cpu max limit to request ratio per Container is 4, but provided ratio is 5.000000——补默认值发生在变更准入,补完的结果还要过校验。把默认 limit 改成 400m(比例 4)之后,Pod 被补成 requests {cpu: 100m, memory: 128Mi}、limits {cpu: 400m, memory: 256Mi},QoS 是 Burstable,注解 kubernetes.io/limit-ranger 记着补了哪几项。

部分指定

实测 · 本机执行输出
  only-limit-cpu  写了 {limits: {cpu: 200m}}  →  requests={'cpu': '200m', 'memory': '128Mi'} limits={'cpu': '200m', 'memory': '256Mi'} qos=Burstable
  only-req-mem    写了 {requests: {memory: 100Mi}}  →  requests={'cpu': '100m', 'memory': '100Mi'} limits={'cpu': '400m', 'memory': '256Mi'} qos=Burstable
  full            写了 {requests: {cpu: 100m, memory: 100Mi}, limits: {cpu: 300m, memory: 200Mi}}  →  requests={'cpu': '100m', 'memory': '100Mi'} limits={'cpu': '300m', 'memory': '200Mi'} qos=Burstable

只写 limits.cpu: 200m,requests.cpu 也变成 200m(request 缺省取 limit 的值,不再用 defaultRequest),memory 的 request 补 128Mi、limit 补 256Mi;只写 requests.memory: 100Mi,cpu 的 request 补 100m、limit 补 400m,memory limit 补 256Mi;四项都写全则一个都不改。逐容器、逐资源地补缺。

越界会被拒

实测 · 本机执行输出
  cpu 请求 2 核(max 是 1):退出码 1;Error from server (Forbidden): error when creating "STDIN": pods "too-big" is forbidden: maximum cpu usage per Container is 1, but limit is 2
  memory 请求 10Mi(min 是 64Mi):退出码 1;Error from server (Forbidden): error when creating "STDIN": pods "too-small" is forbidden: minimum memory usage per Container is 64Mi, but request is 10Mi
  cpu limit/request = 9(最大 4):退出码 1;Error from server (Forbidden): error when creating "STDIN": pods "big-ratio" is forbidden: cpu max limit to request ratio per Container is 4, but provided ratio is 9.000000
  memory limit 1Gi(max 是 512Mi):退出码 1;Error from server (Forbidden): error when creating "STDIN": pods "mem-over" is forbidden: maximum memory usage per Container is 512Mi, but limit is 1Gi

准入时逐条校验:cpu 2 核超过 max 1(maximum cpu usage per Container is 1, but limit is 2);memory request 10Mi 低于 min 64Mi;cpu limit 900m / request 100m 的比例 9 超过 4;memory limit 1Gi 超过 512Mi。报错都写明了限制值和提交的值。

PVC 与已有对象

实测 · 本机执行输出
  PVC pvc-ok(storage 500Mi):退出码 0;persistentvolumeclaim/pvc-ok created
  PVC pvc-big(storage 5Gi):退出码 1;Error from server (Forbidden): error when creating "STDIN": persistentvolumeclaims "pvc-big" is forbidden: maximum storage usage per PersistentVolumeClaim is 1Gi, but request is 5Gi
  PVC pvc-small(storage 1Mi):退出码 1;Error from server (Forbidden): error when creating "STDIN": persistentvolumeclaims "pvc-small" is forbidden: minimum storage usage per PersistentVolumeClaim is 10Mi, but request is 1Mi
  把 LimitRange 的默认 limit 改成 cpu 800m / memory 400Mi(默认 request cpu 改成 200m)之后:已有的 Pod old 仍是 requests={'cpu': '100m', 'memory': '128Mi'} limits={'cpu': '400m', 'memory': '256Mi'}(没变:True);新建的 Pod new 是 requests={'cpu': '200m', 'memory': '128Mi'} limits={'cpu': '800m', 'memory': '400Mi'}

LimitRange 的 type: PersistentVolumeClaim 约束 storage:5Gi 超过 1Gi、1Mi 低于 10Mi 都被拒绝,500Mi 通过。LimitRange 只在对象创建时起作用:把默认 limit 改成 800m / 400Mi 之后,已有的 Pod old 保持原来的值,新建的 Pod 才拿到新默认值。所以改了 LimitRange 不会“修正”已经在运行的 Pod。

分步演示

LimitRange
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / kind(Docker 里的单节点或多节点真实集群,节点是 Docker Desktop 虚拟机里的容器)/ kubectl;用空的 kubeconfig 之外的独立 kubeconfig,不碰用户自己的集群;计时用 date +%s%N / kubectl 事件时间戳,数字每次运行会有小幅抖动。三节点 kind 集群 kx-main(Kubernetes v1.37.0);命名空间 k34 里的 LimitRange:Container 默认 limit cpu 500m→400m / memory 256Mi,默认 request cpu 100m / memory 128Mi,min cpu 50m / memory 64Mi,max cpu 1 / memory 512Mi,cpu 比例上限 4;PersistentVolumeClaim storage 10Mi~1Gi;Pod 用 busybox:1.36,创建后读 spec 与 status.qosClass,被拒绝的错误信息取自 kubectl apply 的输出;实验后删除命名空间;每种情形各一次
    • 没有验证:type: Pod 的 LimitRange(Pod 级别的总量约束);init 容器的默认值补法;LimitRange 对 Deployment 创建本身的影响(Deployment 创建成功,Pod 在 ReplicaSet 创建时才被拒绝,见下一篇的类似现象);多个 LimitRange 同时存在时的合并规则;ephemeral-storage 的 default / max;与 ResourceQuota 的配合(下一篇)
    京ICP备2026067502号-1京公网安备11010502063487号