资源管理 - Requests & Limits
资源管理 - Requests & Limits
为什么需要资源管理
在 Kubernetes 中,如果不限制资源:
- 资源争抢:一个 Pod 占用所有资源
- 性能下降:节点资源耗尽导致所有 Pod 变慢
- 不可预测:无法保证应用性能
- 成本失控:资源浪费
Requests 和 Limits
Requests(资源请求)
调度器用于选择节点的最小资源保证。
Limits(资源限制)
容器运行时的最大资源限制。
基础配置
apiVersion: v1
kind: Pod
metadata:
name: resource-demo
spec:
containers:
- name: app
image: nginx
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
含义:
- 保证至少分配 64Mi 内存和 0.25 核 CPU
- 最多使用 128Mi 内存和 0.5 核 CPU
CPU 资源
单位说明
- 1 CPU = 1000m (millicores)
- 500m = 0.5 核
- 100m = 0.1 核
resources:
requests:
cpu: "1" # 1 核心
cpu: "1000m" # 1 核心(等价)
cpu: "500m" # 0.5 核心
cpu: "100m" # 0.1 核心
CPU 限制行为
超出 Limits:
- 进程被限流(throttled)
- 不会被杀死
- 响应变慢
# 查看 CPU 限流
kubectl top pod <pod-name>
示例:CPU 密集型应用
apiVersion: apps/v1
kind: Deployment
metadata:
name: cpu-intensive
spec:
replicas: 2
selector:
matchLabels:
app: cpu-intensive
template:
metadata:
labels:
app: cpu-intensive
spec:
containers:
- name: app
image: cpu-app:v1
resources:
requests:
cpu: "1"
memory: "512Mi"
limits:
cpu: "2"
memory: "1Gi"
内存资源
单位说明
resources:
requests:
memory: "128Mi" # 128 MiB
memory: "1Gi" # 1 GiB
memory: "1024Mi" # 1024 MiB = 1 GiB
memory: "128M" # 128 MB (1000进制)
memory: "1G" # 1 GB (1000进制)
推荐使用:Mi、Gi(1024进制)
内存限制行为
超出 Limits:
- Pod 被 OOMKilled(Out Of Memory Killed)
- Pod 会自动重启(如果 restartPolicy 允许)
# 查看 OOM 事件
kubectl describe pod <pod-name>
# 输出
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning OOMKilled 1m kubelet Container killed due to OOM
示例:内存密集型应用
apiVersion: apps/v1
kind: Deployment
metadata:
name: memory-intensive
spec:
replicas: 1
selector:
matchLabels:
app: memory-intensive
template:
metadata:
labels:
app: memory-intensive
spec:
containers:
- name: app
image: memory-app:v1
resources:
requests:
cpu: "500m"
memory: "2Gi"
limits:
cpu: "1"
memory: "4Gi"
QoS(服务质量等级)
Kubernetes 根据 requests 和 limits 自动分配 QoS 等级。
1. Guaranteed(最高优先级)
条件:
- 每个容器都设置了 requests 和 limits
- requests 等于 limits
resources:
requests:
cpu: "500m"
memory: "512Mi"
limits:
cpu: "500m"
memory: "512Mi"
特点:
- 资源有保证
- 最后被驱逐
- 适合关键应用
2. Burstable(中等优先级)
条件:
- 至少一个容器设置了 requests 或 limits
- 不满足 Guaranteed 条件
resources:
requests:
cpu: "250m"
memory: "256Mi"
limits:
cpu: "1"
memory: "1Gi"
特点:
- 可以使用额外资源
- 中等驱逐优先级
- 适合一般应用
3. BestEffort(最低优先级)
条件:
- 没有设置任何 requests 和 limits
# 没有 resources 配置
特点:
- 可以使用所有空闲资源
- 首先被驱逐
- 适合批处理任务
查看 QoS
kubectl describe pod <pod-name> | grep "QoS Class"
# 输出
QoS Class: Guaranteed
LimitRange
为 Namespace 设置资源默认值和限制。
创建 LimitRange
apiVersion: v1
kind: LimitRange
metadata:
name: cpu-mem-limit-range
namespace: dev
spec:
limits:
# 容器级别
- type: Container
default:
cpu: "500m"
memory: "512Mi"
defaultRequest:
cpu: "100m"
memory: "128Mi"
max:
cpu: "2"
memory: "2Gi"
min:
cpu: "50m"
memory: "64Mi"
maxLimitRequestRatio:
cpu: 4
memory: 4
# Pod 级别
- type: Pod
max:
cpu: "4"
memory: "4Gi"
效果:
- 未指定资源的 Pod 自动应用 default 值
- 超出 max 的 Pod 无法创建
- 低于 min 的 Pod 无法创建
- limits/requests 比例不能超过 maxLimitRequestRatio
ResourceQuota
限制 Namespace 的总资源使用。
创建 ResourceQuota
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-quota
namespace: dev
spec:
hard:
# CPU 和内存
requests.cpu: "10"
requests.memory: "20Gi"
limits.cpu: "20"
limits.memory: "40Gi"
# Pod 数量
pods: "50"
# 存储
persistentvolumeclaims: "10"
requests.storage: "100Gi"
kubectl describe resourcequota compute-quota -n dev
# 输出
Name: compute-quota
Namespace: dev
Resource Used Hard
-------- ---- ----
limits.cpu 5 20
limits.memory 10Gi 40Gi
pods 20 50
requests.cpu 2.5 10
requests.memory 5Gi 20Gi
按 QoS 限制
apiVersion: v1
kind: ResourceQuota
metadata:
name: qos-quota
namespace: dev
spec:
hard:
pods: "50"
scopeSelector:
matchExpressions:
- operator: In
scopeName: PriorityClass
values:
- high
实战示例
数据库 Pod
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: mysql
replicas: 3
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.0
resources:
requests:
cpu: "1"
memory: "2Gi"
limits:
cpu: "2"
memory: "4Gi"
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secret
key: password
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 50Gi
Web 应用
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp
spec:
replicas: 5
selector:
matchLabels:
app: webapp
template:
metadata:
labels:
app: webapp
spec:
containers:
- name: webapp
image: webapp:v1
resources:
requests:
cpu: "200m"
memory: "256Mi"
limits:
cpu: "500m"
memory: "512Mi"
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
批处理任务
apiVersion: batch/v1
kind: Job
metadata:
name: batch-job
spec:
template:
spec:
containers:
- name: worker
image: batch-worker:v1
resources:
requests:
cpu: "500m"
memory: "1Gi"
limits:
cpu: "2"
memory: "4Gi"
restartPolicy: OnFailure
监控资源使用
Metrics Server
安装:
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
查看资源使用:
# 节点资源
kubectl top nodes
# 输出
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
node-1 2500m 62% 8Gi 50%
node-2 1800m 45% 6Gi 37%
# Pod 资源
kubectl top pods
# 输出
NAME CPU(cores) MEMORY(bytes)
webapp-abc123 250m 128Mi
webapp-def456 180m 96Mi
# 指定 namespace
kubectl top pods -n kube-system
# 排序
kubectl top pods --sort-by=cpu
kubectl top pods --sort-by=memory
资源使用趋势
# 持续监控
watch kubectl top pods
# 查看容器资源
kubectl top pod <pod-name> --containers
最佳实践
1. 始终设置 Requests
resources:
requests:
cpu: "100m"
memory: "128Mi"
原因:
- 确保调度器正确放置 Pod
- 避免节点过载
2. 合理设置 Limits
resources:
limits:
cpu: "1"
memory: "512Mi"
原则:
- limits 应该是 requests 的 2-4 倍
- 避免设置过高的 limits
3. 避免 BestEffort
生产环境应避免不设置资源的 Pod。
4. 分层设置资源
集群 → Namespace (ResourceQuota) → Pod (Resources)
5. 监控和调优
# 定期检查资源使用
kubectl top nodes
kubectl top pods
# 调整资源配置
kubectl set resources deployment webapp \
--requests=cpu=200m,memory=256Mi \
--limits=cpu=500m,memory=512Mi
6. 使用垂直 Pod 自动扩缩容(VPA)
自动调整 requests 和 limits:
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: webapp-vpa
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: webapp
updatePolicy:
updateMode: "Auto"
常见问题
Pod 一直 Pending
kubectl describe pod <pod-name>
# 可能原因
Events:
Warning FailedScheduling 1m scheduler 0/3 nodes are available: insufficient cpu
解决:
- 降低 requests
- 增加节点
- 删除不需要的 Pod
Pod 频繁 OOMKilled
kubectl describe pod <pod-name>
Events:
Warning OOMKilled 1m kubelet Container killed due to OOM
解决:
- 增加 memory limits
- 优化应用内存使用
- 检查内存泄漏
CPU 限流
应用变慢,但未崩溃:
# 检查 CPU 使用
kubectl top pod <pod-name>
# 如果接近或超过 limits,增加 CPU 限制
小结
资源管理是 Kubernetes 集群稳定运行的基础:
核心概念:
- Requests:最小保证
- Limits:最大限制
- QoS:服务质量等级
关键配置:
- LimitRange:默认值和范围
- ResourceQuota:总量限制
最佳实践:
- 始终设置 requests
- 合理设置 limits
- 监控资源使用
- 定期优化配置
QoS 优先级:
Guaranteed > Burstable > BestEffort
下一章我们将学习调度策略,控制 Pod 的调度行为。