Files
juwan-backend/docs/email-task-deployment-troubleshooting.md
T

3.7 KiB
Raw Blame History

Email Task 部署故障排查与修复记录

1. 问题现象

部署 email-task 时出现调度失败:

Warning  FailedScheduling  0/1 nodes are available: 1 Insufficient memory.
no new claims to deallocate, preemption: 0/1 nodes are available:
1 No preemption victims found for incoming pod.

表现为:

  • Deployment 期望副本无法全部就绪
  • Pod 长时间 Pending

2. 排查思路

按以下顺序排查:

  1. 看部署配置是否过高请求requests/limits + replicas
  2. 看节点可分配资源和已分配资源(确认是否真的是内存不足)
  3. 看滚动策略是否会额外拉起新 PodmaxSurge 可能放大内存压力)
  4. 看容器健康检查是否匹配服务类型(任务型服务不一定监听端口)

3. 关键排查命令

3.1 查看节点可分配资源

kubectl get nodes -o custom-columns=NAME:.metadata.name,ALLOCATABLE_CPU:.status.allocatable.cpu,ALLOCATABLE_MEM:.status.allocatable.memory

3.2 查看部署与 Pod 状态

kubectl -n juwan get deploy email-task -o wide
kubectl -n juwan get pods -l app=email-task -o wide
kubectl -n juwan describe pod -l app=email-task

3.3 查看节点资源分配占比

kubectl describe node minikube

关注输出中的 Allocated resources

  • memory requests 已接近节点上限(本次约 97%

3.4 查看部署策略与探针配置

kubectl -n juwan get deploy email-task -o yaml
kubectl -n juwan logs deploy/email-task --tail=120

4. 根因分析

本次是组合问题

  1. 内存请求过高 + 副本过多

    • 原始配置:replicas=3
    • 每个 Pod 请求 memory=512Mi
    • 单节点场景下,叠加现有业务后无法继续调度
  2. 滚动更新默认 maxSurge=25%

    • 更新时可能额外起新 Pod,进一步触发内存不足
  3. 探针不匹配服务行为

    • 原配置为 tcpSocket:8080 探针
    • 实际 email-task 是任务型服务,日志显示启动后并未提供该端口服务
    • 导致 Readiness/Liveness 持续失败

5. 修复方案

仅修改文件:

  • deploy/k8s/service/email/email.yaml

5.1 降低资源请求与副本基线

  • replicas: 3 -> 1
  • requests.cpu: 500m -> 100m
  • requests.memory: 512Mi -> 128Mi
  • limits.cpu: 1000m -> 500m
  • limits.memory: 1024Mi -> 512Mi

5.2 调整 HPA 基线与上限

  • 两个 HPACPU / Memory)统一:
    • minReplicas: 3 -> 1
    • maxReplicas: 10 -> 3

5.3 调整滚动发布策略

  • strategy.rollingUpdate.maxSurge: 0
  • strategy.rollingUpdate.maxUnavailable: 1

目的:避免滚动期间额外拉起 Pod 造成瞬时内存不足。

5.4 移除不适配的 8080 TCP 探针

移除:

  • readinessProbe.tcpSocket:8080
  • livenessProbe.tcpSocket:8080

6. 修复执行命令

kubectl apply -f deploy/k8s/service/email/email.yaml
kubectl -n juwan rollout restart deploy/email-task
kubectl -n juwan rollout status deploy/email-task --timeout=180s
kubectl -n juwan get pods -l app=email-task -o wide
kubectl -n juwan describe pods -l app=email-task | Select-String -Pattern 'FailedScheduling|Unhealthy|Warning|Events|Node:'

7. 修复结果

  • Deployment 滚动成功
  • 新 Pod 成功调度并 Running
  • 无新的 FailedSchedulingUnhealthy 事件

8. 后续建议

  1. 若要恢复多副本,先按节点容量逐步上调(建议先 2 副本并观测)。
  2. 为任务型服务设计更合适的健康检查方式:
    • 可考虑 exec 探针或业务自检端点。
  3. 在单节点开发环境中统一降低默认 requests,防止多个服务叠加后调度失败。
  4. 如需高可用,建议扩容节点而不是仅依赖压缩资源。