资源限制
学习目标
- 理解资源限制(limits)的概念和作用
- 掌握 CPU 和内存限制的行为差异
- 了解 OOM Killer 和 CPU 节流机制
核心概念
一句话解释
资源限制定义 Pod 可以使用的最大资源量,超过限制会被限制(CPU)或杀掉(内存)。
Requests 与 Limits 关系
┌─────────────────────────────────────────────────────────┐
│ 资源模型 │
├─────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────┐ │
│ │ 节点 CPU: 4 核, 内存: 8Gi │ │
│ │ │ │
│ │ ┌─────────────────────────────────┐ │ │
│ │ │ Pod A │ │ │
│ │ │ requests: cpu=500m, mem=256Mi │ │ │
│ │ │ limits: cpu=1, mem=512Mi │ │ │
│ │ │ │ │ │
│ │ │ ┌─────────────────────────┐ │ │ │
│ │ │ │ 实际使用: 0.8 CPU │ │ │ │
│ │ │ │ 实际使用: 300Mi 内存 │ │ │ │
│ │ │ └─────────────────────────┘ │ │ │
│ │ │ │ │ │
│ │ │ - 保证获得 500m CPU │ │ │
│ │ │ - 最多使用 1 CPU │ │ │
│ │ │ - 超过 1 CPU 会被节流 │ │ │
│ │ └─────────────────────────────────┘ │ │
│ └─────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘
YAML 语法
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: app
image: nginx
resources:
requests:
cpu: "500m"
memory: "256Mi"
limits:
cpu: "1000m"
memory: "512Mi"
CPU 限制行为
┌─────────────────────────────────────────────────────────┐
│ CPU 节流 │
├─────────────────────────────────────────────────────────┤
│ │
│ CPU 是可压缩资源 │
│ - 超过 limits 不会被杀掉 │
│ - 会被节流(throttled) │
│ │
│ 时间 ──────────────────────────────────────────────► │
│ │
│ 限制: 1 CPU │
│ ┌─────────────────────────────────────────┐ │
│ │ 请求: 1.5 CPU │ │
│ │ │ │
│ │ ████████████░░░░░░████████████░░░░░░░ │ │
│ │ 运行 1 CPU 节流 运行 1 CPU 节流 │ │
│ └─────────────────────────────────────────┘ │
│ │
│ 实际获得的 CPU 时间受限,但进程不会被杀掉 │
│ │
└─────────────────────────────────────────────────────────┘
内存限制行为
┌─────────────────────────────────────────────────────────┐
│ OOM Killer │
├─────────────────────────────────────────────────────────┤
│ │
│ 内存是不可压缩资源 │
│ - 超过 limits 会被 OOM Killer 杀掉 │
│ │
│ 内存使用 │
│ │ │
│ │ ┌─────────────────────────────────┐ limits: 512Mi │
│ │ │ │ │
│ │ │ ████████████████████ │ │
│ │ │ │ 实际使用 400Mi │ │ requests: 256Mi│
│ │ │ ████████████████████ │ │
│ │ │ │ │
│ │ └─────────────────────────────────┘ │
│ │ │
│ │ ┌─────────────────────────────────┐ limits: 512Mi │
│ │ │ │ │
│ │ │ ████████████████████████ │ │
│ │ │ │ 实际使用 600Mi │ │ │
│ │ │ ████████████████████████ │ OOM Killed! │
│ │ │ │ │
│ │ └─────────────────────────────────┘ │
│ │ │
│ └──────────────────────────────────────────────────────│
│ │
└─────────────────────────────────────────────────────────┘
QoS 类别
┌─────────────────────────────────────────────────────────┐
│ QoS 类别 │
├─────────────────────────────────────────────────────────┤
│ │
│ Guaranteed(保证) │
│ - requests == limits(所有容器) │
│ - 最高优先级,最后被杀掉 │
│ │
│ Burstable(可突发) │
│ - requests < limits(至少一个容器) │
│ - 中等优先级 │
│ │
│ BestEffort(尽力而为) │
│ - 没有设置 requests 和 limits │
│ - 最低优先级,最先被杀掉 │
│ │
│ 优先级:Guaranteed > Burstable > BestEffort │
│ │
└─────────────────────────────────────────────────────────┘
LimitRange 默认值
# 设置默认 limits
apiVersion: v1
kind: LimitRange
metadata:
name: default-limits
namespace: my-namespace
spec:
limits:
- default: # 默认 limits
cpu: "500m"
memory: "256Mi"
defaultRequest: # 默认 requests
cpu: "100m"
memory: "128Mi"
max: # 最大 limits
cpu: "2"
memory: "2Gi"
min: # 最小 requests
cpu: "50m"
memory: "64Mi"
type: Container
实践练习
练习 1:设置资源限制
# pod-limits.yaml
apiVersion: v1
kind: Pod
metadata:
name: limits-pod
spec:
containers:
- name: nginx
image: nginx
resources:
requests:
cpu: "250m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "256Mi"
kubectl apply -f pod-limits.yaml
kubectl describe pod limits-pod | grep -A 10 "Limits"
练习 2:观察 CPU 节流
# pod-cpu-throttle.yaml
apiVersion: v1
kind: Pod
metadata:
name: cpu-throttle
spec:
containers:
- name: stress
image: polinux/stress
command: ["stress"]
args: ["--cpu", "2"] # 尝试使用 2 核 CPU
resources:
limits:
cpu: "500m" # 限制为 0.5 核
kubectl apply -f pod-cpu-throttle.yaml
# 观察 CPU 使用率和节流情况
kubectl top pod cpu-throttle
练习 3:观察 OOM Killer
# pod-oom.yaml
apiVersion: v1
kind: Pod
metadata:
name: oom-pod
spec:
containers:
- name: stress
image: polinux/stress
command: ["stress"]
args: ["--vm", "1", "--vm-bytes", "300M"] # 尝试使用 300Mi 内存
resources:
limits:
memory: "128Mi" # 限制为 128Mi
kubectl apply -f pod-oom.yaml
# 观察 Pod 状态
kubectl get pod oom-pod -w
# 应该会被 OOM Killed
# 查看 Pod 状态和原因
kubectl describe pod oom-pod | grep -A 10 "Last State"
练习 4:查看 QoS 类别
# 不同 QoS 类别的 Pod
apiVersion: v1
kind: Pod
metadata:
name: guaranteed-pod
spec:
containers:
- name: nginx
image: nginx
resources:
requests:
cpu: "500m"
memory: "256Mi"
limits:
cpu: "500m"
memory: "256Mi"
---
apiVersion: v1
kind: Pod
metadata:
name: burstable-pod
spec:
containers:
- name: nginx
image: nginx
resources:
requests:
cpu: "250m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "256Mi"
---
apiVersion: v1
kind: Pod
metadata:
name: besteffort-pod
spec:
containers:
- name: nginx
image: nginx
kubectl apply -f qos-pods.yaml
# 查看 QoS 类别
kubectl get pods -o custom-columns=NAME:.metadata.name,QOS:.status.qosClass
练习 5:使用 LimitRange
# limitrange.yaml
apiVersion: v1
kind: LimitRange
metadata:
name: default-limits
spec:
limits:
- default:
cpu: "500m"
memory: "256Mi"
defaultRequest:
cpu: "100m"
memory: "128Mi"
type: Container
kubectl apply -f limitrange.yaml
# 创建不带资源设置的 Pod
kubectl run test-pod --image=nginx
# 查看 Pod 的资源设置(自动添加默认值)
kubectl get pod test-pod -o yaml | grep -A 10 resources
最佳实践
1. 始终设置 limits
- 防止单个 Pod 耗尽节点资源
- 特别是内存限制
2. requests 和 limits 的比例
- CPU: requests <= limits
- 内存: requests <= limits
- 建议 ratio: 1:2 到 1:4
3. 根据工作负载类型设置
- CPU 密集型:关注 CPU limits
- 内存密集型:关注内存 limits
4. 使用 LimitRange 强制限制
- 设置默认值
- 设置最大/最小值
5. 监控和调整
- 使用 kubectl top 查看实际使用
- 根据监控数据调整 limits
常见问题
1. Pod 被 OOM Killed
# 查看 Pod 状态
kubectl describe pod <pod-name> | grep -A 10 "Last State"
# 原因:内存使用超过 limits
# 解决:增加内存 limits 或优化应用内存使用
2. CPU 使用率低但应用响应慢
# 查看 CPU 节流情况
kubectl top pod <pod-name>
# 原因:CPU limits 过低导致节流
# 解决:增加 CPU limits
3. 不设置 limits 会怎样?
# CPU: 可以使用节点所有可用 CPU(共享)
# 内存: 无限制,可能导致 OOM
# 建议:至少设置内存 limits
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
memory: "256Mi" # 至少设置内存限制
小结
| 要点 | 说明 |
|---|---|
| limits | Pod 可以使用的最大资源量 |
| CPU 超限 | 会被节流(throttled),不会被杀 |
| 内存超限 | 会被 OOM Killer 杀掉 |
| QoS 类别 | Guaranteed > Burstable > BestEffort |
| LimitRange | 设置默认和最大/最小值 |
| 最佳实践 | 始终设置内存 limits,合理设置 CPU limits |
练习编辑器
bash
Loading...