这类问题我又碰上了一次。CentOS 7.9 上启动服务报 Address already in use,netstat -lntp 显示 8000 在监听但进程名是横杠,ss -lntp 里根本找不到这个端口。

第一反应是「netstat 走的是 /proc/net/tcp,容器里的端口被 host 网络共享出来」,验证下来不成立。

真正麻烦的地方在于,几个原因的现象几乎一样。监听 socket 在另一个网络命名空间里,宿主机的 ss 看不到;进程已经退出,socket 还被内核的 TIME_WAIT 或 orphan 结构留着;进程属于另一个用户,缺权限时 ss 不显示进程名但仍占端口。

两种工具的结果对照着看

ss -lntp 'sport = :8000' && netstat -lntp | grep 8000

然后按 inode 反查是哪个进程

ss -lntpe 'sport = :8000'

到容器的命名空间里再查一次

nsenter -t $(docker inspect -f '{{.State.Pid}}' web) -n ss -lntp

等前面都确认过,再确认后释放或换端口启动

fuser -k 8000/tcp || sed -i 's/8000/8010/' /etc/app/app.conf

怎么算真的好了,看的是同一批现象。ss 与 netstat 的结论一致,端口占用者明确,服务换端口后正常监听,启动日志不再报地址被占用。

容易忽略的是,ss 比 netstat 快得多而且能看到更多状态,排查端口优先用它;跨命名空间的问题必须进容器里看,宿主机上永远查不到。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。

作者 9823189