🔌 端口冲突排查与解决

故障时间:2026-07-08
环境:Kubernetes 集群(k8s-sealos 1.30.14,单 Master 节点)
故障现象:Prometheus Node Exporter 无法启动,Pod 状态 CrashLoopBackOff


故障现象

prometheus-node-exporter Pod 处于 CrashLoopBackOff 状态,无法正常提供服务。

$ kubectl get pods -n monitor
NAME                                         READY   STATUS             RESTARTS       AGE
prometheus-node-exporter-97lkv               0/1     CrashLoopBackOff   13 (88s ago)   24m
...

排查步骤

Step 1:查看 Pod 日志

首先查看 CrashLoopBackOff Pod 的日志,确定报错原因:

kubectl logs -n monitor prometheus-node-exporter-97lkv --tail=50

日志关键信息:

ts=2026-07-08T09:20:16.878Z caller=node_exporter.go:199 level=info msg="Listening on" address=0.0.0.0:9100
ts=2026-07-08T09:20:16.879Z caller=node_exporter.go:202 level=error err="listen tcp 0.0.0.0:9100: bind: address already in use"

🔍 关键发现0.0.0.0:9100 端口已被占用,node_exporter 无法绑定到该地址。

Step 2:检查端口占用情况

在目标节点上查看端口 9100 的占用状态:

netstat -antulp | grep 9100

输出:

tcp  0  0  127.0.0.1:9100  →  127.0.0.1:2379   ESTABLISHED  114243/kube-apiserv
tcp  0  0  127.0.0.1:2379  →  127.0.0.1:9100   ESTABLISHED  114224/etcd

🔍 关键发现kube-apiserver(PID 114243)正在使用本地 9100 端口作为客户端源端口,与 etcd(PID 114224,监听 2379)建立连接。

Step 3:分析端口冲突原因

组件 角色 端口 说明
kube-apiserver 客户端 127.0.0.1:9100(源端口) 作为客户端连接 etcd 时,内核分配了 9100 作为临时源端口
etcd 服务端 127.0.0.1:2379(目标端口) 正常监听在 2379 端口
node_exporter 服务端 0.0.0.0:9100(监听端口) 需要绑定 9100 端口对外暴露 metrics

根因分析

  1. Linux 内核在分配临时端口(ephemeral port)时,默认范围是 32768-60999(可通过 /proc/sys/net/ipv4/ip_local_port_range 查看)。
  2. 但在某些情况下(如端口范围被修改、或端口恰好未被占用),内核可能将 9100 分配给 kube-apiserver 作为连接 etcd 的源端口。
  3. node_exporter 尝试绑定 0.0.0.0:9100 时,发现该端口已被 kube-apiserver 占用(即使是作为客户端源端口),导致绑定失败。

⚠️ 关键点:Linux 中一个端口只要被任何 socket 使用(无论是作为服务端监听还是作为客户端源端口),其他进程就无法再绑定该端口。


本次故障解决方法

处理步骤

由于 kube-apiserveretcd 均为 Kubernetes 控制面核心组件,由 kubelet 以静态 Pod 方式管理,强制终止后会自动重启。重启后内核会重新分配源端口,从而释放 9100 端口。

执行命令

# 根据 netstat 查到的 PID 强制终止占用端口的进程
sudo kill -9 114224 114243

📋 PID 对应关系

  • 114224 → etcd
  • 114243 → kube-apiserver

原理说明

处理前:
┌─────────────────────────────────────────────────────────┐
│  kube-apiserver (PID 114243)                            │
│  源端口: 127.0.0.1:9100 ──────────┐                    │
│                                    │ TCP 连接           │
│  etcd (PID 114224)                │                    │
│  监听: 127.0.0.1:2379 ◄───────────┘                    │
│                                                         │
│  node_exporter                                         │
│  尝试绑定 0.0.0.0:9100 ❌ 失败!端口已被占用            │
└─────────────────────────────────────────────────────────┘

处理后(kubelet 自动重启控制面组件):
┌─────────────────────────────────────────────────────────┐
│  kube-apiserver (新 PID)                                │
│  源端口: 127.0.0.1:4xxxx ──────────┐                   │
│                                     │ TCP 连接          │
│  etcd (新 PID)                     │                   │
│  监听: 127.0.0.1:2379 ◄────────────┘                   │
│                                                         │
│  node_exporter                                         │
│  成功绑定 0.0.0.0:9100 ✅ 正常运行                      │
└─────────────────────────────────────────────────────────┘

验证恢复

# 1. 确认 node_exporter Pod 恢复正常
kubectl get pods -n monitor | grep node-exporter

# 2. 确认端口 9100 已被 node_exporter 正常监听
netstat -antulp | grep 9100

# 3. 验证 metrics 可正常采集
curl http://<node-ip>:9100/metrics

预防措施建议

调整本地端口范围(推荐)

将本地临时端口范围调整到远离常用服务端口(如 9100、9090、3000 等)的区间,请根据业务需求调整端口范围。

# 查看当前范围
cat /proc/sys/net/ipv4/ip_local_port_range
# 默认通常为: 32768  60999

# 建议设置更高的起始端口,避开常用的 9xxx 端口段
echo "40000 60999" > /proc/sys/net/ipv4/ip_local_port_range

# 持久化配置
echo "net.ipv4.ip_local_port_range = 40000 60999" >> /etc/sysctl.conf
sysctl -p

端口规划

在部署前做好端口规划文档,确保常用服务端口(如 node_exporter:9100, Prometheus:9090, Grafana:3000 等)不与系统临时端口范围重叠。

监控告警

  • CrashLoopBackOff 状态 Pod 设置告警
  • 监控关键端口占用变化
  • 设置 node_exporter 健康检查告警

常用排查命令速查

场景 命令
查看端口占用 netstat -antulp | grep <port>
查看端口占用(ss 方式) ss -tunlp | grep <port>
查看 Pod 日志 kubectl logs -n <ns> <pod-name> --tail=100
查看 Pod 事件 kubectl describe pod -n <ns> <pod-name>
查看临时端口范围 cat /proc/sys/net/ipv4/ip_local_port_range
查看进程详情 ps -ef | grep <pid>
强制终止进程 kill -9 <pid>

总结

项目 内容
故障原因 Linux 内核将 node_exporter 的监听端口 9100 分配给了 kube-apiserver 作为客户端临时端口,导致 node_exporter 绑定失败
解决方法 强制终止 etcd 和 kube-apiserver 进程,由 kubelet 自动重启后释放 9100 端口
根本预防 调整内核ip_local_port_range 参数,避免临时端口与常用服务端口重叠
影响范围 控制面组件短暂重启(秒级恢复),不影响已运行的业务 Pod
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇