在虚拟机上安装了docker, 并且下载了mysql镜像, 准备启动mysql镜像, 然后遇到了如下问题:
Error starting userland proxy: listen tcp4 0.0.0.0:3306: bind: address already in use.
大意就是说我的这个3306端口被占用了, 所以无法启动容器中的mysql镜像.
可以从上面看到, 此时我并没有启动的任何镜像文件. 于是我使用了命令去查我虚拟机的端口是否被占用.
通过上面这两条命令可以看出, 此时我的3306端口并没有被占用. (下面那个坚听是我在 执行了docker run mysql 那条后, 才出现的, 这说明我启动了一个mysql镜像失败了, 失败原因就是3306端口没有映射上的原因)
那就很奇怪了, 虚拟机3306 端口未被占用, docker容器中3306也属于空闲, 那这个端口被使用到底是哪儿来的?
一顿百度后发现, 我的查询端口命令并不正确, 这个原因导致了我怎么都查不出端口被占用的真实情况.
第一个:
ps -ef | grep 3306
这个命令是查看服务器的进程信息中进程名称为“3306”的所有进程的所有列信息. 很显然我并有进程为“3306”的进程, 所以并未查到.
第二个:
netstat -ano | grep 3306
这个命令是用于显示套接字内容中含有 3306 的套接字内容, 不仅显示正在通信的套接字,还显示包括尚未开始通信等状态的所有套接字, 显示 IP 地址和端口号, 还有pid. 当我查询这个的时候, 有一个没有ip的3306端口处于监听状态, 这个是我docker run mysql运行后的, 运行失败的mysql镜像所处于的状态(因为他在等待和3306端口做映射, 但是3306被占用), 所以这个方法也没找到占用的具体原因.
后来经过百度, 使用了另一个命令, 才找到原因.
lsof -i :3306
执行了上面命令后, 显示我在虚拟机上有一个mysql进程在运行(不是docker中的), 这时我想起来, 我在很早之前在虚拟机上安装了mysql, 当我启动了虚拟机后, 他自己就在后台跑了, 占用了3306端口, 所以一直导致docker中的mysql镜像端口映射失败. (图片忘记保存了)
然后在我删除了mysql文件后, 再去执行 docker run mysql ****, 这时就成功了.
这里要说明一下 netstat 和 lsof 两个命令的区别. 首先两个都是很强大的命令, 都可以查询端口的占用情况, 但是netsat更多的是看端口占用的信息, 比如什么端口、ip、协议, lsof则是查看进程, 直接看占用端口的进程信息. 所以以后如果遇到端口占用, 不妨试试 lsof命令.
希望对遇到相同困难的朋友有帮助.