跳到正文
OpsKit

Kubernetes 资源计算器

换算毫核与内存后缀,按副本数相乘,并显示 kubelet 会判定的 QoS 等级。后缀对照表把 Mi 与 M 的差距摆到眼前——悄无声息的浪费和突如其来的 OOMKill 都出自这里。

示例工作负载

QoS 等级: BurstableCPU limit 是 request 的 5.0 倍内存 limit 是 request 的 2.0 倍
每个 Pod× 3 个副本
CPU request0.10.3
CPU limit0.51.5
内存 request128Mi384Mi
内存 limit256Mi768Mi

清单片段

resources:
  requests:
    cpu: 100m
    memory: 128Mi
  limits:
    cpu: 500m
    memory: 256Mi

# 3 replicas require
#   cpu    0.3 cores requested, 1.5 at the limit
#   memory 384Mi requested, 768Mi at the limit

Mi 不是 M

Kubernetes 同时接受二进制和十进制后缀,而两者大小并不相同。

后缀字节后缀字节差异
1Ki1,0241k1,000+2.4%
1Mi1,048,5761M1,000,000+4.9%
1Gi1,073,741,8241G1,000,000,000+7.4%

所以 1G 是 1G,1Gi 是 1Gi,相差约 7%。

全部在浏览器内完成. 这个页面是静态文件。你输入的内容只留在标签页里,不会发送到服务器,关闭即消失。所以粘贴真实的令牌或配置是安全的。

什么时候用得上

  • 确定 Deployment 规格时,需要知道副本数会占掉多少集群容量。
  • 搞清楚为什么本想设成 Guaranteed 却变成了 Burstable。
  • 把 docker-compose 的内存限制换算成清单文件需要的单位。

实际示例

毫核

输入
500m
结果
0.5 核

1000m 就是 1 核。request 写 100m 表示调度器预留十分之一个核。

花钱的后缀

输入
1000M 与 1Gi
结果
1,000,000,000 与 1,073,741,824 字节

本想写 Mi 却写成 M,容器拿到的内存会比预期少约 7%。

Guaranteed 等级

输入
requests == limits
结果
Guaranteed

只有 CPU 和内存的 request 都与 limit 完全相等时才成立。其余都是 Burstable,资源紧张时会更早被驱逐。

容易出错的地方

该写 Mi 时写成 M

512M 是 512,000,000 字节,512Mi 是 536,870,912 字节。两种写法都合法,所以不会有任何警告,只是 Pod 拿到的内存比数字看起来的少。

把 CPU limit 设得远高于 request

limit 是 request 的好几倍时,Pod 会先冲上去,等节点一忙就被狠狠限流。看起来像应用 bug 的延迟毛刺,很多其实是 CFS throttling。

干脆不写 request

没有 request 的 Pod 属于 BestEffort,节点吃紧时第一个被驱逐。它也没给调度器任何判断依据,节点会被填得很不均匀。

常见问题

request 和 limit 有什么区别?

request 是调度 Pod 时预留的量,limit 是运行时内核强制的上限。request 决定 Pod 落在哪里,limit 决定它何时被限流或被 OOMKill。

QoS 等级是怎么判定的?

所有容器的 CPU 和内存 request 都等于 limit 就是 Guaranteed;完全没有 request 和 limit 就是 BestEffort;介于两者之间的都是 Burstable。驱逐正是按这个顺序进行的。

到底该不该设 CPU limit?

很多团队只设内存 limit 而不限 CPU。超出内存 limit 会杀掉容器,超出 CPU limit 只是限流,而这种限流对延迟的伤害,往往比让 Pod 用掉空闲算力更大。

相关工具