第01章:AI生成的Deployment没有资源限制导致节点OOM
第01章:AI生成的Deployment没有资源限制导致节点OOM
“AI 帮你生成了一份 Deployment YAML,部署成功了,跑了两周没问题。然后某天流量高峰,某个 Pod 的内存无限增长,把整个节点的内存吃满,Node 进入 OOM(Out of Memory),上面所有 Pod 被强制驱逐,服务全部中断。原因:AI 生成的 Deployment 没有设置资源 limits。”
ℹ️ 版本说明:本章基于 Kubernetes 1.36.1。
1.1 AI默认会生成什么
# AI 通常给你的 Deployment(没有资源限制)
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 2
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: my-app:latest
ports:
- containerPort: 8080
这个配置缺少 resources.requests 和 resources.limits,导致:
- Pod 可以无限使用内存,直到节点 OOM
- Kubernetes 调度器无法合理分配 Pod 到节点(不知道 Pod 需要多少资源)
- 无法配置 HPA(水平扩容需要资源 requests 作为基准)
1.2 AI通常遗漏的4个坑
⚠️ 坑1:requests 和 limits 的区别
resources:
requests:
memory: "256Mi" # 调度时保留的资源(最少需要)
cpu: "250m" # 250m = 0.25 CPU 核
limits:
memory: "512Mi" # 最大允许使用(超过会被 OOMKilled)
cpu: "500m" # 超过时 CPU 被节流(throttled),不会 kill
- requests:调度时使用,告诉 k8s “这个 Pod 至少需要多少资源”
- limits:运行时使用,超过内存 limit → 容器被 OOMKilled;超过 CPU limit → CPU 被节流(但不 kill)
建议:内存 limits 设为 requests 的 2x,CPU limits 可以更大(CPU 节流不 kill 进程)。
⚠️ 坑2:LimitRange:Namespace 级别的默认资源限制
如果你忘记设置 resources,可以在 Namespace 里配置 LimitRange,让没有 resources 设置的 Pod 自动获得默认值:
apiVersion: v1
kind: LimitRange
metadata:
name: default-limits
namespace: production
spec:
limits:
- default: # 默认 limits(没设置时使用)
memory: 512Mi
cpu: 500m
defaultRequest: # 默认 requests(没设置时使用)
memory: 256Mi
cpu: 250m
type: Container
⚠️ 坑3:ResourceQuota:防止 Namespace 消耗所有资源
LimitRange 限制单个 Pod 的资源,ResourceQuota 限制整个 Namespace 的总资源:
apiVersion: v1
kind: ResourceQuota
metadata:
name: production-quota
namespace: production
spec:
hard:
requests.cpu: "10" # Namespace 总 CPU requests 上限
requests.memory: 20Gi # Namespace 总内存 requests 上限
limits.cpu: "20"
limits.memory: 40Gi
pods: "50" # 最多 50 个 Pod
⚠️ 坑4:VPA(垂直 Pod 自动扩缩)可以帮助设置合理的资源值
如果你不知道应该设置多少资源,可以用 VPA(Vertical Pod Autoscaler)的推荐模式:
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: my-app-vpa
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app
updatePolicy:
updateMode: "Off" # 只推荐,不自动修改
VPA 会分析 Pod 的历史资源使用,给出推荐值:
kubectl describe vpa my-app-vpa
# 查看 Recommendation 部分的 requests 建议值
1.3 更好的提示词
提示词 P01:生成带资源限制的生产级 Deployment
使用时机:为新应用生成 Deployment 配置
比默认多了什么:
- resources requests 和 limits
- pod affinity 和 anti-affinity
- 生产就绪的配置
帮我生成一个生产级别的 Kubernetes 1.36.1 Deployment,包含完整的资源限制配置。
应用信息:
- 应用名:[my-app]
- 镜像:[my-app:v1.2.3](注意:不用 latest)
- 端口:[8080]
- 副本数:[2]
- 应用类型:[Web API / Worker / Batch Job]
资源需求(如果不知道,帮我给出合理的默认值):
- 内存使用估计:[平均 200MB,峰值 400MB]
- CPU 使用估计:[轻量级 Web 服务]
配置要求:
1. resources.requests 和 resources.limits(内存 limits = 2× requests)
2. CPU requests(使用 millicores,250m 或 500m)
3. 至少 2 个副本(高可用)
4. PodAntiAffinity(避免所有副本在同一节点):
- preferredDuringScheduling(软约束)还是 required?
5. Pod disruption budget(确保更新时至少1个副本可用)
6. 标签规范(app、version、component)
同时给我:
- LimitRange YAML(为 Namespace 设置默认资源限制)
- 如何用 kubectl top pods 监控实际资源使用?
基于 Kubernetes 1.36.1。
提示词 P02:排查 OOMKilled 事件
使用时机:Pod 被 OOMKilled,需要找出根因
比默认多了什么:
- 完整的诊断步骤
- 如何确定合理的内存 limit 值
我的 Kubernetes Pod 一直被 OOMKilled,帮我诊断原因和设置合理的内存限制。
当前情况:
kubectl describe pod <pod-name> 输出:
[粘贴,重点是 Last State 和 OOMKilled 信息]
应用类型:[Python FastAPI / Node.js / Java Spring / 其他]
当前内存 limits 设置:[X Mi / 未设置]
诊断步骤:
1. 如何查看 Pod 被 OOMKilled 的历史:
- kubectl describe pod 里的 Last State
- kubectl logs --previous(查看上次崩溃的日志)
2. 如何查看当前内存使用量:
- kubectl top pod(需要 metrics-server)
- 如何从 Prometheus 查看内存历史使用曲线?
3. 如何确定合理的内存 limits:
- 正常负载下的内存使用
- 峰值内存使用(压测时)
- 建议 limits = 峰值 × 1.5(给 GC 留余地)
4. 有没有内存泄漏?
- 如何通过 kubectl top 判断内存是否在持续增长?
- 如何触发 Java/Python/Node.js 的堆转储用于分析?
基于 Kubernetes 1.36.1。
提示词 P03:完整的 Namespace 资源配额策略
使用时机:为多团队/多环境的 K8s 集群配置资源治理
比默认多了什么:
- LimitRange + ResourceQuota 配合使用
- 不同环境的资源策略
帮我为 Kubernetes 集群配置完整的资源配额策略,支持多个 Namespace(开发/测试/生产)。
集群资源总量:
- 节点数:[N 台]
- 每台节点:[16核 64GB]
Namespace 规划:
- production:关键生产服务,资源优先
- staging:预发布,资源次之
- development:开发测试,低资源上限
给我每个 Namespace 的:
1. ResourceQuota(总资源上限):
- CPU/内存 requests 上限
- CPU/内存 limits 上限
- Pod 数量上限
2. LimitRange(单个容器的默认值和上限):
- 默认 requests(没有设置 resources 时自动应用)
- 默认 limits
- 最大 limits(防止单个 Pod 申请过多)
3. 超出配额时的行为:
- 新 Pod 会被拒绝吗?
- 如何查看 Namespace 的资源使用情况?
4. 资源配额监控:
- kubectl describe resourcequota 的输出解读
- 如何设置接近配额时的告警?
基于 Kubernetes 1.36.1。
1.4 验收清单
| 检查项 | 验证方法 | AI辅助 |
|---|---|---|
| 所有 Deployment 有 resources 配置 | `kubectl get deployments -o yaml | grep -c resources` |
| 内存 limits ≥ 2× requests | 查看 YAML 里的数值比例 | 让 AI 检查现有配置 |
| Namespace 有 LimitRange | kubectl get limitrange -n <ns> |
用 P03 创建 LimitRange |
| PodAntiAffinity 已配置(多副本) | kubectl describe deployment 查看 affinity |
用 P01 添加 anti-affinity |
| 无 OOMKilled 事件(最近7天) | kubectl get events --field-selector reason=OOMKilling |
用 P02 排查 |
| metrics-server 已安装 | kubectl top pods 有输出 |
让 AI 提供 metrics-server 安装步骤 |
1.5 本章小结
如果你只记一件事:每个 Kubernetes Deployment 都必须设置 resources.requests 和 resources.limits——没有 limits 的 Pod 可以无限消耗节点内存,触发 OOM,导致节点上所有服务中断。一个起手的合理设置:requests: {memory: 256Mi, cpu: 250m},limits: {memory: 512Mi, cpu: 500m},之后根据实际使用量(kubectl top pods)调整。
资源管理的三个层次:
- 设置 resources(为每个容器设置 requests/limits):防止 OOM,调度器能合理分配
- 设置 LimitRange(Namespace 级别默认值):防止遗漏 resources 的配置被运行
- 设置 ResourceQuota(Namespace 总资源上限):多团队集群防止某个 Namespace 耗尽所有资源
→ 第2章:AI帮我配置了Service但外网无法访问