Pod 资源配置:Limit 与 Request
你的 Pod 应该申请多少 CPU 和内存?如果申请太多,资源会浪费;如果申请太少,Pod 可能被 OOM Kill。
理解 Kubernetes 的资源模型,是合理分配资源的前提。
基本概念
Kubernetes 使用 Request(请求) 和 Limit(限制) 来管理资源:
yaml
apiVersion: v1
kind: Pod
spec:
containers:
- name: nginx
image: nginx:alpine
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "500m"Request vs Limit
┌─────────────────────────────────────────────────────────────────────┐
│ Request 和 Limit 的区别 │
│ │
│ Request(请求): │
│ - Pod 启动时需要的最小资源 │
│ - Kubernetes 调度器根据 Request 做调度决策 │
│ - 保证 Pod 至少能获得 Request 指定的资源 │
│ │
│ Limit(限制): │
│ - Pod 最多能使用的资源上限 │
│ - 超过 Limit 会触发限制(CPU 节流/内存 OOM) │
│ - 用于防止单个 Pod 耗尽节点资源 │
│ │
│ 节点资源分配: │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ 节点总资源 = Allocated (Pod Request) + System Reserved │ │
│ │ │ │
│ │ 调度时:Pod Request ≤ 节点可用资源 │ │
│ └──────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘资源单位
bash
# CPU 单位
cpu: "0.1" # 0.1 CPU = 100m(millicores)
cpu: "100m" # 100 millicores = 0.1 CPU
cpu: "1" # 1 CPU(等于一个 CPU 核心)
# 内存单位
memory: "128Mi" # 128 Mebibytes
memory: "128Mi" # 常用
memory: "1Gi" # 1 Gibibyte
memory: "1G" # 1 Gigabyte(近似值,不推荐)
memory: "1048576Ki" # KiB调度原理
Request 与调度
bash
# 调度器根据 Request 做调度决策
# 节点可分配资源 = 节点总量 - 已调度 Pod 的 Request - 系统预留
# 示例:节点有 4 核 CPU
kubectl describe node node-1
# 输出:
# Allocated resources:
# Resource Requests Limits
# cpu 2000m (50%) 0 (0%)
# memory 1Gi (25%) 0 (0%)
# 如果一个 Pod 申请 500m CPU
# 调度器会检查:节点是否有 500m 可用 CPU
# 有 → Pod 可能调度到此节点
# 无 → Pod 进入 PendingLimit Range 限制
可以为 Namespace 设置默认的 Request 和 Limit:
yaml
apiVersion: v1
kind: LimitRange
metadata:
name: default-limit
namespace: myapp
spec:
limits:
- type: Container
default:
memory: 256Mi
cpu: 200m
defaultRequest:
memory: 128Mi
cpu: 100m
max:
memory: 1Gi
cpu: 1
min:
memory: 64Mi
cpu: 50mbash
# Pod 未指定 resources 时,自动使用 LimitRange 的 default 值
kubectl apply -f limit-range.yaml
# 查看 LimitRange
kubectl get limitrange -n myapp
kubectl describe limitrange default-limit -n myappCPU 限制
CPU 如何节流
bash
# CPU 是可压缩资源
# Pod 使用超过 Request 但不超过 Limit 时,会被节流(throttled)
# Pod 使用超过 Limit 时,被强制节流到 Limit
# 示例:
resources:
requests:
cpu: 100m
limits:
cpu: 500m
# Pod 行为:
# - 正常使用:获得 100m CPU
# - 高负载:可以获得最多 500m CPU
# - 超过 500m:被节流到 500mCPU 节流示例
java
// Java 应用 CPU 节流表现
public class CPUIntensiveTask {
public static void main(String[] args) {
while (true) {
// 如果容器 CPU limit 是 500m
// 这个循环会被 Kubernetes 节流
doWork();
}
}
}内存限制
内存 OOM
bash
# 内存是不可压缩资源
# Pod 使用超过 Limit,会触发 OOM Kill
# 容器被杀死,restartCount 增加
# 查看 OOM 状态
kubectl describe pod myapp | grep -A 5 "Last State"
# 输出:
# Last State: Terminated
# Reason: OOMKilled
# Exit Code: 137
# Started: Mon, 01 Jan 2024 09:00:00 +0000
# Finished: Mon, 01 Jan 2024 09:30:00 +0000OOM 优先级
bash
# 内存不足时,Kubernetes 按以下顺序杀 Pod:
# 1. BestEffort Pod(未设置 resources)
# 2. Burstable Pod(Request < Limit)
# 3. Guaranteed Pod(Request == Limit)
# QoS 等级
kubectl get pod myapp -o jsonpath='{.status.qosClass}'
# Guaranteed Pod(最高优先级,不会被杀)
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "128Mi"
cpu: "100m" # request == limit资源配额
ResourceQuota
yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: my-quota
namespace: myapp
spec:
hard:
# 资源总量
requests.cpu: "4"
requests.memory: "8Gi"
limits.cpu: "8"
limits.memory: "16Gi"
# Pod 数量
pods: "10"
# PVC 数量
persistentvolumeclaims: "5"bash
# 查看配额使用情况
kubectl get resourcequota -n myapp
kubectl describe resourcequota my-quota -n myapp
# 输出:
# Namespace: myapp
# Resource Used Hard
# -------- ---- ----
# cpu 2 4
# memory 4Gi 8Gi
# pods 6 10资源设置最佳实践
设置 Request 和 Limit
yaml
# 推荐:同时设置 Request 和 Limit
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "500m"JVM 应用配置
yaml
# Java 应用需要特殊考虑
# JVM 默认会使用宿主机全部内存,需要配置
resources:
requests:
memory: "512Mi"
cpu: "500m"
limits:
memory: "512Mi"
cpu: "1"
env:
- name: JAVA_OPTS
value: "-Xmx384m -Xms256m -XX:+UseContainerSupport"
# JAVA_OPTS 说明:
# -Xmx: 最大堆内存(建议为 limit 的 75%)
# -Xms: 初始堆内存
# -XX:+UseContainerSupport: 让 JVM 感知容器限制Nginx 配置
yaml
# Nginx 默认启动多个 worker 进程
# 需要限制 worker 进程数
resources:
requests:
memory: "64Mi"
cpu: "50m"
limits:
memory: "128Mi"
cpu: "200m"
env:
- name: NGINX_WORKER_PROCESSES
value: "1"
- name: NGINX_WORKER_CONNECTIONS
value: "1024"常见语言配置
yaml
# Node.js
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "500m"
env:
- name: NODE_OPTIONS
value: "--max-old-space-size=200"
- name: NODE_ENV
value: "production"
# Python
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "500m"监控资源使用
bash
# 查看 Pod 资源使用
kubectl top pod
# 按命名空间查看
kubectl top pod -n myapp
# 查看节点资源
kubectl top node
# 查看 Pod 资源请求 vs 实际使用
kubectl describe node node-1 | grep -A 10 "Allocated resources"常见问题
Pod 处于 Pending
bash
# 原因:没有节点能满足 Pod 的 Request
kubectl describe pod myapp | grep -A 10 "Events"
# 解决方案:
# 1. 增加节点
# 2. 减少 Pod 的 Request
# 3. 清理不必要的 Pod容器被 OOM Kill
bash
# 查看是否被 OOM Kill
kubectl describe pod myapp | grep -A 5 "Last State"
# Reason: OOMKilled
# 解决方案:
# 1. 增加 memory limit
# 2. 优化应用内存使用
# 3. JVM 应用配置 -XmxCPU 被节流
bash
# CPU 节流查看
# Prometheus 查询
# rate(container_cpu_cfs_throttled_seconds_total[5m])
# 解决方案:
# 1. 增加 CPU limit
# 2. 使用更高效的算法资源设置检查表
markdown
# 部署前检查清单
## Request 设置
- [ ] 应用正常运行需要多少 CPU?
- [ ] 应用正常运行需要多少内存?
- [ ] 是否考虑了突发流量?
## Limit 设置
- [ ] 内存限制是否足够避免 OOM?
- [ ] CPU 限制是否考虑正常峰值?
- [ ] Limit 和 Request 的比例是否合理?
## JVM 应用
- [ ] JAVA_OPTS 是否配置了 -Xmx?
- [ ] 是否使用了 -XX:+UseContainerSupport?
- [ ] -Xmx 是否设置为 limit 的 75% 左右?
## 监控
- [ ] 是否设置了资源监控?
- [ ] 是否设置了资源告警?
- [ ] 是否定期审查资源使用情况?面试追问
- Request 和 Limit 的区别是什么?调度器用哪个做决策?
- 如果一个节点只剩 500m CPU 可用,两个都需要 500m CPU 的 Pod 能调度吗?
- CPU 和内存在资源管理上有什么区别?
- 什么是 QoS?Guaranteed、Burstable、BestEffort 的区别是什么?
- JVM 应用在容器中运行时,为什么需要特殊配置?
"合理的资源设置是保证应用稳定运行的基础。太紧会导致 OOM 和节流,太松会浪费资源。最佳实践是:观察 → 设置 Request → 设置 Limit → 持续调优。"
