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

## 1. 问题现象

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

```text
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. **看滚动策略是否会额外拉起新 Pod**（`maxSurge` 可能放大内存压力）
4. **看容器健康检查是否匹配服务类型**（任务型服务不一定监听端口）

---

## 3. 关键排查命令

### 3.1 查看节点可分配资源

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

### 3.2 查看部署与 Pod 状态

```powershell
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 查看节点资源分配占比

```powershell
kubectl describe node minikube
```

关注输出中的 `Allocated resources`：

- `memory requests` 已接近节点上限（本次约 97%）

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

```powershell
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 基线与上限

- 两个 HPA（CPU / 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. 修复执行命令

```powershell
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`
- 无新的 `FailedScheduling` 与 `Unhealthy` 事件

---

## 8. 后续建议

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