Windows主机与WSL中Docker镜像端口冲突的问题
Windows主机与WSL中Docker镜像端口冲突的问题
在Windows主机和WSL(Windows Subsystem for Linux)中同时运行MySQL服务时,可能会遇到端口冲突的问题。本文通过实验环境展示了具体的操作步骤和解决方案,帮助读者解决实际问题。
问题描述
我们在Windows主机上安装MySQL时,按照安装教程或者默认配置,一般会将MySQL的监听端口设为3306。巧合的是,当我们在WSL中使用docker命令部署MySQL镜像时,一般在做容器的端口映射时,也会选择命令-p 3306:3306把容器的3306端口暴露给WSL的3306端口。
存在以下几个问题:
- 无论是在Windows还是Linux中,当不同的两个程序监听同一个端口时,会报端口冲突的错误。那么,Windows主机可以和WSL子系统使用相同的端口嘛?会报错嘛?
- 如果不会报错,那么该如何分别访问Windows/WSL中监听相同端口的不同程序呢?
实验环境
Windows主机端
Windows主机端已经提前启动MySQL了,PID为2096。
WSL Docker端
WSL Docker端已经提前启动docker了,并且使用docker run命令提前部署好了一个MySQL容器。
此外,WSL的ip地址为172.18.28.170。(这个因人而异,不过WSL一般都是172打头的这个II类子网ip)。
解决办法
上述两张图分别展示了如何通过-h命令访问两个位于“相同”端口的MySQL数据库。可以通过MySQL的版本号和show databases;加以区分。
(Windows主机端的版本较旧,为8.0.33,并且除了系统自带的数据库外还有自建的数据库;而拉取的docker镜像为8.0.39,版本更新一些,除了系统自带的数据库外还没有新建库。)
原理揭晓
端口冲突时的默认规则
参考博客WSL 使用指南——03 避免的坑 - Ja’Soon的文章 - 知乎可知,在上述3306端口冲突的情况下,localhost:3306是优先分给了Windows主机端。
端口WSL和Win10共享同一套端口,如果出现两者监听同一个端口的情况,Windows主系统的程序拥有更高的优先级。也就是说,如果我们在WSL运行需要监听端口的程序,必须确认该端口没有被Windows主系统内的任何程序占用。如果出现冲突,请参阅软件相关文档修改默认配置。
这就解释了为什么mysql -hlocalhost -uroot -p命令,会访问到Windows主机端安装的MySQL。
MySQL中已经为User配置Host
那么为什么mysql -h172.18.28.170 -uroot -p就可以访问WSL中的docker镜像了呢?
原来docker中的mysql:8.0.39镜像在部署后,mysql数据库中的user表中,root用户有一行Host为%。意味着同一局域网内的其他主机,可以通过指定数据库所在主机的ip地址,来访问数据库。