Nacos 残留实例应急处理 SOP
场景:K8s 发版后,旧 Pod IP 仍残留在 Nacos,未正常摘除
一、问题时间线复盘
gantt
title 2026-06-10 故障时间线
dateFormat HH:mm
axisFormat %H:%M
section 发布阶段
K8s 开始滚动发布 : milestone, m1, 20:49, 0m
发布完成 : done, 20:49, 20:54
section 异常阶段
旧Pod存活并重连Nacos : crit, 20:54, 22:00
运维手动Nacos下线 : milestone, m2, 22:00, 0m
旧Pod进程继续运行 : crit, 22:00, 23:22
section 清理阶段
旧Pod连接断开 : milestone, m3, 23:22, 0m
Nacos清理过期metadata : done, 23:22, 23:24
二、根因分析
K8s 发版时会向旧 Pod 发送 SIGTERM,正常情况下应用收到信号后退出,Nacos 心跳随之停止,实例自动摘除。
本次异常路径如下:
K8s 发送 SIGTERM → Pod 未正常退出 → 进程持续存活 → 持续向 Nacos 发心跳 → 旧实例长期残留 → 上游流量仍路由到旧 Pod ⚠️
可能原因:
- 应用未正确处理
SIGTERM,进程没有响应信号退出 terminationGracePeriodSeconds配置过长,K8s 等待期间进程一直活着- 容器运行时(containerd)异常,容器进程泄漏到宿主机,K8s 层面误认为 Pod 已删除
三、应急处理 SOP
🚨 发现 Nacos 残留异常实例后,按以下步骤处理:
① 立即止血
- Nacos 控制台找到该实例,手动点击下线
- ⏱ 第一优先级,防止上游继续路由流量到旧 Pod
② 查 K8s Pod 状态
bash
kubectl get pods -n prod -o wide | grep <异常IP>
根据结果分三种情况处理:
| 结果 | 说明 | 处理方式 |
|---|---|---|
Pod 处于 Terminating |
卡住未退出 | 强制删除(见下方命令) |
Pod 处于 Running |
完全未被终止 | 强制删除(见下方命令) |
| 找不到 Pod | K8s 层面已删,进程泄漏到宿主机 | 跳到第③步宿主机排查 |
bash
# Terminating 或 Running 时,强制删除
kubectl delete pod <pod-name> -n prod --force --grace-period=0
③ SSH 到宿主机
从上一步 kubectl get pods 结果中找到 NODE 列,拿到宿主机 IP,ssh 上去:
bash
ssh <node-ip>
④ 定位残留进程
bash
# 用业务端口查找进程(比随机端口可靠)
ss -tlnp | grep <业务端口>
# 确认该进程属于哪个容器
cat /proc/<PID>/cgroup
⑤ 确认后强杀
bash
kill -9 <PID>
⚠️ kill 前务必通过 cgroup 确认是目标容器进程,避免误杀。
⑥ 收尾确认
- 回到 Nacos 控制台,确认该实例已彻底消失
- 记录事件时间、操作人、处理过程,留存备查
✅ 处理完毕
四、关键命令速查
☸️ K8s 侧
bash
# 按 IP 查 Pod
kubectl get pods -n prod -o wide | grep <IP>
# 查 Pod 详情
kubectl describe pod <pod-name> -n prod
# 强制删除
kubectl delete pod <pod-name> -n prod --force --grace-period=0
🖥️ 宿主机侧
bash
# 查业务端口对应进程
ss -tlnp | grep <业务端口>
# 确认进程的容器归属
cat /proc/<PID>/cgroup
# 强制杀进程
kill -9 <PID>
五、根本性解决方案
📋 短期
- 建立本 SOP 流程,形成团队共识
- 每次发版后人工核查 Nacos 实例数是否符合预期
🔧 中期
- 应用注册 ShutdownHook,收到
SIGTERM后主动调 Nacos 接口下线自身,不依赖心跳超时被动摘除 - 合理配置
terminationGracePeriodSeconds,给应用足够但不过长的优雅退出时间
🚀 长期
- Nacos 实例数变更接入自动告警,发版后异常残留第一时间通知,不依赖人工发现
- 发版流水线增加后置检查步骤,自动验证旧实例已全部摘除,否则阻断发布
六、端口说明
| 端口类型 | 示例 | 说明 |
|---|---|---|
| 业务端口 | 8082 |
服务对外提供接口,排查进程用这个 |
| Nacos 客户端随机端口 | 60674 |
应用连接 Nacos 时的本地 ephemeral port,每次随机分配,不固定 |
| Nacos 服务端端口 | 8848 |
Nacos 服务器监听端口 |