初学docker的时候,不知道为啥,按着教程里打的代码,最后却出现了映射失败的情况。即:在docker内部设置的映射端口,外部却没有办法访问。想了想,不外乎两个原因,要么是docker内部映射失败,要么是外部访问地址出了错误,所以,带着这两个疑问,我来排查了。

内部原因

考虑是内部原因,我先用nginx试了试。输入简单的一个端口映射:

docker run -d -P nginx

然后成功运行,查看端口也是没有问题的。
在这里插入图片描述
所以,再继续看看端口,上图可以看出是32769端口被监听了。所以输入命令:

netstat -na|grep 32769

但是,没有用。没有输出,这就有意思了。
这代表端口没有开启,但是上一条命令又说开启了。所以,我想是在镜像内部开启了一个32769,但是外部还是本地的32769并没有被映射到。所以输入localhost:32769访问不到。这时候,查看一下虚拟出来的镜像的本地端口,输入:

docker-machine ip default

出来了端口
在这里插入图片描述
浏览器输入:192.168.99.100:32769
访问成功。
在这里插入图片描述
综上,外部原因,输入localhost访问不到,要输入容器的localhost才可以。以后自己新建的镜像的端口也是,要找到真实端口才可以访问的,虚拟端口浏览器是无法识别出的。

参考文献

本质原因

2021年2月7日,隔了一年多了,之前只是实验出来了怎么找才可以实现映射,但是本质原因没有找。最近看到有网友给我点赞,我去思考了一下这个问题出现的本质原因,有了一些自己的看法。
其实最近刚好有看虚拟机的网络,联想这个问题,现在也可以解释一下原理了。docker的默认网络模型是桥接模型,而且和虚拟机(VMware那种)的桥接模型不一样,它相当于是虚拟机的桥接模型+NAT模型构成的一个网络模型(对于这两种模型可以看看我的博客,最近有写,也可以直接百度:1.虚拟机网络模型;2.docker网络模型,你就知道为什么了)。
它也是用了虚拟机网络模拟那一套。大概原因是:docker内部模拟了一个网卡,类似虚拟机的桥接模式,所以,在宿主机内访问docker容器,实际上是相当于访问了一个局域网内的另一台机器,所以localhost是找不到了,要用docker的虚拟网关分配给容器的ip才可以访问。即:在宿主机中,相当于各个docker容器和宿主机是一个局域网内的多台机器。这也就是为什么我们用虚拟ip:192.168.99.100:32769就可以访问的原因了。而你的localhost:32769,它由虚拟网卡分配,应该是分配到了192.168.99.xxx(这个xxx是你此时的宿主机所分配到的地址,但肯定不是100),所以,你是访问不到服务的。

再记录一下遇到的”docker ps报错bash: ps: command not found“的问题。
是我们下载的nginx镜像没有打包ps命令,所以只要重新下载就好了。使用:apt-get update && apt-get install procps命令即可。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐