第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.requestsresources.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.requestsresources.limits——没有 limits 的 Pod 可以无限消耗节点内存,触发 OOM,导致节点上所有服务中断。一个起手的合理设置:requests: {memory: 256Mi, cpu: 250m}limits: {memory: 512Mi, cpu: 500m},之后根据实际使用量(kubectl top pods)调整。

资源管理的三个层次

  1. 设置 resources(为每个容器设置 requests/limits):防止 OOM,调度器能合理分配
  2. 设置 LimitRange(Namespace 级别默认值):防止遗漏 resources 的配置被运行
  3. 设置 ResourceQuota(Namespace 总资源上限):多团队集群防止某个 Namespace 耗尽所有资源

→ 第2章:AI帮我配置了Service但外网无法访问