讲解
Kubernetes 调度靠 requests(请求):它是「这个容器保证需要多少资源」,调度器把节点上所有 Pod 的 requests 加起来,只把 Pod 放到「剩余可分配量 ≥ 请求量」的节点上——requests 是调度的唯一依据,也是超售控制的阀门。limits(限制)是运行时的天花板:CPU 超过 limit 会被限流(throttle,进程变慢但不死),内存超过 limit 会被 OOM Killer 直接杀掉(容器重启)。CPU 是可压缩资源,内存不可压缩——这个区别决定了两种超限后果的不同,务必记住。
不配 requests/limits 的 Pod 是最危险的:调度器当它「零请求」,可以无限堆叠到一台节点上,真到资源耗尽时,系统按 QoS 等级决定先杀谁。QoS 三级:Guaranteed(requests == limits 且 CPU、内存都配齐,最后被驱逐)、Burstable(配了部分,中间档)、BestEffort(什么都没配,资源紧张时第一个死)。生产服务至少要到 Burstable,关键服务追求 Guaranteed。
配套的两个集群级工具:LimitRange 在命名空间层面给「没写 requests/limits 的容器」补默认值和上下界,配合 ResourceQuota(第 15 章)让资源声明成为强约束。单位写法:CPU 的 1 = 1 个核,100m = 0.1 核;内存用 Mi/Gi。设置经验值:requests 按 P95 日常用量设,CPU limit 可以设得宽松(限流只是变慢)或不设,内存 limit 必须设且留足余量(超限就死)。观测实际用量用 kubectl top(依赖 metrics-server,第 21 章会再遇到)。
示例
一个把 requests/limits 写全的 Pod(QoS 会是 Burstable——requests 与 limits 不相等):
# wait: pod/ohmydocs-verify-sized
apiVersion: v1
kind: Pod
metadata:
name: ohmydocs-verify-sized
labels:
app: ohmydocs-verify-sized
spec:
containers:
- name: nginx
image: nginx:1.27-alpine
resources:
requests:
cpu: 100m
memory: 64Mi
limits:
cpu: 200m
memory: 128Mi
确认资源配置与 QoS 等级都被正确记录:
kubectl get pod ohmydocs-verify-sized -o jsonpath='资源配置: {.spec.containers[0].resources}'
echo
kubectl get pod ohmydocs-verify-sized -o jsonpath='QoS 等级: {.status.qosClass}'
echo
LimitRange 给命名空间补默认值:创建 LimitRange 后,没写 resources 的 Pod 会自动带上默认 requests/limits:
apiVersion: v1
kind: LimitRange
metadata:
name: ohmydocs-verify-defaults
spec:
limits:
- type: Container
default:
cpu: 200m
memory: 128Mi
defaultRequest:
cpu: 50m
memory: 32Mi
cat > no-resources.yaml <<EOF
apiVersion: v1
kind: Pod
metadata:
name: ohmydocs-verify-bare
spec:
containers:
- name: busybox
image: busybox:1.36
command: ["sleep", "300"]
EOF
kubectl apply -f no-resources.yaml
kubectl get pod ohmydocs-verify-bare -o jsonpath='自动补上的 resources: {.spec.containers[0].resources}'
echo
kubectl delete pod ohmydocs-verify-bare --wait
常见坑
- 内存 limit 贴着实际用量设:内存超限是 OOMKill 直接重启,峰值一抖就死;limit 要比峰值留 30% 以上余量,并用 HPA 或加副本扛峰值。
- CPU limit 设太低:CPU 超限不杀进程只是限流,但限流的延迟毛刺很难排查;延迟敏感服务常不设 CPU limit,只用 requests 保证调度。
- 只配 limit 不配 request:Kubernetes 会把 request 自动设成等于 limit(QoS 变 Guaranteed 的同时调度变苛刻),要清楚自己在要什么。
- 凭感觉写数值:先配宽松值上线,用 kubectl top / 监控观察真实用量,再收敛 requests——脱离观测的数字都是猜的。
小结
requests 决定调度、limits 决定运行时天花板;CPU 超限限流、内存超限 OOMKill;QoS 三级决定驱逐顺序;LimitRange 补默认值、ResourceQuota 管总量。应用资源观建立完毕,下一章看另一类负载:Job 与 CronJob。