CentOS 7.9 上一台机器先跑着宿主机自带的 Java 服务占着 8080,再用 docker run -p 8080:80 起 nginx,命令没有报错,访问 8080 一直是 Java 那个页面。
把日志和配置对完,能解释这个现象的基本就这几处。docker 默认只监听 IPv4 的 0.0.0.0,宿主机进程先占了同一个端口,内核把连接给了先绑定的一方;端口绑定失败时 docker 只把告警写进 daemon 日志,容器照样显示 Up;docker-proxy 只负责转发,绑定不上时不阻断容器启动;IPv6 与 IPv4 是两套绑定,ss 里看着端口在听,其实对端不是同一个进程。
动手时先看端口到底被哪个进程占着
ss -lntp 'sport = :8080'
接着查 docker 启动时的端口绑定告警
journalctl -u docker --since '10 min ago' | grep -i 'port is already'
随后换一个未被占用的宿主端口重启容器
docker run -d --name web -p 8081:80 nginx:1.25
从本机验证映射是否真的生效
curl -sI http://127.0.0.1:8081 | head -3
恢复的判定其实很直接。ss 里 8081 的持有进程是 docker-proxy,curl 返回 nginx 的 Server 头,容器日志中出现正常的访问记录。
提醒一点。docker 不会因为端口冲突拒绝启动容器,只会悄悄不转发;上线前用 ss 核一遍宿主机端口,比事后翻 daemon 日志省事。如果同一现象隔几天又出现,说明根因没找到,别当偶发处理。
