返回首页

资源配额 / OOMKilled / RBAC / 调度排障

📅 创建于 2026-05-08 🔄 更新于 2026-05-13 📝 571 字

资源配额 / OOMKilled / RBAC / 调度排障

OOMKilled

现象: Pod 退出码 137(SIGKILL),Reason 为 OOMKilled。

快速定位

# 确认 OOMKilled
kubectl describe pod <name> -n <ns> | grep -E "Last State|Reason|Exit Code"

# 检查资源限制
kubectl get pod <name> -n <ns> \
  -o jsonpath='{.spec.containers[*].resources.limits.memory}'

# 检查节点内存
kubectl top nodes
free -h

OOMKill 的底层机制

Linux OOM Killer 根据进程的 oom_score 选择要杀掉的进程。 Kubernetes 通过 oom_score_adj(由 kubelet 按 QoS 等级设置)控制 OOM 优先级:

QoS 等级 oom_score_adj OOM 优先级
Guaranteed -997 最低(最难杀)
Burstable min(max(2, 1000 - 1000×memoryRequest/nodeMemory), 999) 中等
BestEffort 1000 最高(最先杀)

内存的 Burstable QoS 陷阱(重要)

当内存 Request < Limit 时,Pod 处于 Burstable QoS。OOM Killer 用 Request 值(而非 Limit 值) 计算 oom_score,导致反直觉现象:

  • Pod A (Burstable):requests: 2Gi, limits: 4Gi,实际只用 512Mi
  • Pod B (Guaranteed):requests: 512Mi, limits: 512Mi,实际只用 512Mi

Node 内存紧张时,Pod A 反而更容易被 OOMKill——尽管它的 Request 更大。

结论: 内存强烈建议设置 Request = Limit,使 Pod 进入 Guaranteed QoS, oom_score_adj 固定为 -997,最不容易被 OOMKill。

更多细节参见 k8s-resource-limits-configuration

修复方案

  1. 增大 memory limits(如果是正常业务增长)kubectl patch deployment
  2. 检查内存泄漏(使用 kubectl top pod 观察趋势)
  3. 设 Guaranteed QoS:让内存 Request = Limit
  4. 优化应用内存使用
  5. Java: JVM -Xmx 设为容器 limit 的 75-80%
  6. Go: 设 GOMEMLIMIT 环境变量(Go 1.19+)
  7. 增加节点内存或扩容节点

ResourceQuota 与 LimitRange

LimitRange:Namespace 级默认资源限制

当 Pod 未设置 resources 时自动生效默认值:

apiVersion: v1
kind: LimitRange
metadata:
  name: default-limits
  namespace: my-app
spec:
  limits:
    - type: Container
      default:                # 未设 limits 时的默认值
        cpu: "100m"
        memory: "128Mi"
      defaultRequest:          # 未设 requests 时的默认值
        cpu: "100m"
        memory: "128Mi"
      min:                     # 最小允许值
        cpu: "10m"
        memory: "16Mi"
      max:                     # 最大允许值
        cpu: "4"
        memory: "8Gi"
      maxLimitRequestRatio:    # limit/request 比例上限
        cpu: 10
        memory: 10

ResourceQuota:限制 Namespace 总资源

apiVersion: v1
kind: ResourceQuota
metadata:
  name: production-quota
  namespace: production
spec:
  hard:
    requests.cpu: "10"
    requests.memory: "20Gi"
    limits.cpu: "20"
    limits.memory: "40Gi"
    pods: "50"

排查命令

# 查看 Namespace 资源配额
kubectl describe resourcequota -n <namespace>
kubectl get resourcequota -n <namespace> -o yaml

# 查看 LimitRange
kubectl describe limitrange -n <namespace>

常见问题

  • ResourceQuota 超限 → 新 Pod 无法创建(Events 显示 quota 相关错误)
  • LimitRange 默认值生效 → 未设 resources 的 Pod 自动获得默认配置
  • LimitRange max 值过低 → Pod 请求超限无法创建
  • LimitRange 的 maxLimitRequestRatio → 限制 limit/request 比例,防止过度超售

详细配置指南参见 k8s-resource-limits-configuration。面试速查参见 k8s-interview-100-questions


RBAC 权限问题

现象: "forbidden" 错误。

# 测试权限
kubectl auth can-i <verb> <resource> \
  --as=system:serviceaccount:<ns>:<sa-name>

# 检查 ServiceAccount
kubectl get sa <name> -n <ns> -o yaml

# 检查 Role/ClusterRole 和绑定
kubectl get role,rolebinding -n <ns>
kubectl describe role <name> -n <ns>
kubectl describe rolebinding <name> -n <ns>

修复: 创建正确的 Role + RoleBinding 并关联到 ServiceAccount。


调度失败 — Taint 与 Toleration

现象: Pod 满足资源条件但不满足污点条件。

# 查看节点污点
kubectl get node <name> -o jsonpath='{.spec.taints}'

# 查看 Pod 容忍
kubectl get pod <name> -n <ns> -o jsonpath='{.spec.tolerations}'

常见污点:

  • node.kubernetes.io/not-ready:NoExecute
  • node.kubernetes.io/unreachable:NoExecute
  • node-role.kubernetes.io/control-plane:NoSchedule

修复:

  • 添加 Tolerations 到 Pod
  • 移除节点污点:kubectl taint node <name> <key>:NoSchedule-

生产操作安全规范

操作前必查清单:

  1. 影响范围确认 — 操作会影响哪些 Pod/用户/业务?
  2. 配置备份kubectl get <res> <name> -n <ns> -o yaml > backup.yaml
  3. 回滚方案 — 准备好回滚命令
  4. 执行窗口 — 业务低峰期
  5. 通知相关方 — 提前通知业务方和值班人员

高风险操作(警惕):

  • 删除 Namespace(不可逆)
  • 修改 RBAC 权限(可能丢失集群管理权限)
  • 删除 StorageClass(PV 无法恢复)
  • 修改 etcd 数据
  • 大规模删除 Pod

关联页面

页面关联点
docker-production-pitfallsDocker 原生 OOMKill 与资源限制视角
k8s-resource-limits-configurationK8s 资源限制详细配置指南
jvm-container-oom-offheap-troubleshootingJVM 堆外内存(DirectByteBuffer/Metaspace/线程栈)导致容器 OOMKi
k8s-capacity-planning-qos-cost-optimizationK8s 容量规划方法论与成本优化 — 从流量到资源预算的完整框架,含 QoS 策略、弹性伸缩协同、落
k8s-pod-pending-troubleshooting-guidePod Pending 排障指南 — 7 个排查方向(资源不足/污点/亲和性/存储/配额/选择器/端
k8s-scheduling-strategy-guideK8s 调度策略完整指南(nodeSelector/Affinity/Taint/Topology/PriorityClass)