docker:容器和主机端口的相互访问

时间:2016-11-24 16:27:54

标签: docker

从我的docker容器中,我想访问在我的主机上运行的MySQL服务器127.0.0.1。我想从主机访问在我的容器容器上运行的Web服务器。我试过这个:

docker run -it --expose 8000 --expose 8001 --net='host' -P f29963c3b74f

但没有一个端口显示为暴露:

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
093695f9bc58        f29963c3b74f        "/bin/sh -c '/root/br"   4 minutes ago       Up 4 minutes                            elated_volhard
$
$ docker port 093695f9bc58

如果我没有--net='host',则会显示端口,我可以访问容器上的Web服务器。

主机和容器如何相互访问彼此的端口?

2 个答案:

答案 0 :(得分:1)

当您定义--expose时:

  

容器内的端口号(服务侦听的地方)   不需要匹配外部暴露的端口号   容器(客户端连接)。例如,在容器内   HTTP服务正在侦听端口80(以及图像开发人员   在Dockerfile中指定 EXPOSE 80。在运行时,端口可能是   绑定到主机上的42800 。查找主机端口之间的映射   和暴露的端口,使用docker port。

使用--net=host

  

- 网络="主机"使容器能够完全访问本地系统服务,例如D-bus,因此被认为是不安全的。

这里你什么都没有" ports"因为您已为主机打开了所有端口。

如果您不想使用host网络,可以使用docker interface从Docker容器访问主机端口
- How to access host port from docker container
- From inside of a Docker container, how do I connect to the localhost of the machine?

如果要从主机访问容器,则需要将端口发布到主机接口。

  

-P选项将所有端口发布到主机接口。搬运工人   将每个公开的端口绑定到主机上的随机端口。范围   端口在由...定义的短暂端口范围内   的/ proc / SYS /网/的IPv4 / ip_local_port_range。明确使用 -p标志   映射单个端口或端口范围

简而言之,当您仅定义--expose 8000时,端口不会暴露给8000,而是暴露给某个随机端口。如果要使端口8000对主机可见,则需要映射已发布端口-p 8000:8000

答案 1 :(得分:0)

Docker的网络模型是为您的容器创建一个新的网络命名空间。这意味着容器有自己的127.0.0.1。如果您希望容器访问仅在主机上侦听127.0.0.1的mysql服务,则您无法访问它。

--net=host会将您的容器放入与主机相同的网络命名空间中,但这是不可取的,因为它有效地关闭了docker所具有的所有其他网络功能 - 您无法获得隔离,你没有得到端口暴露/发布等等。

最好的解决方案可能是让你的mysql服务器监听一个可以从docker容器路由的接口。

如果你不想让mysql听你的公共界面,你可以创建一个桥接界面,给它一个随机的ip(确保你没有任何冲突),把它连接到什么都没有,并配置mysql只侦听该IP和127.0.0.1。例如:

sudo brctl addbr myownbridge
sudo ifconfig myownbridge 10.255.255.255
sudo docker run --rm -it alpine ping -c 1 10.255.255.255

该IP地址可以从您的主机和该主机上运行的任何容器中路由。

另一种方法是容纳你的mysql服务器。你可以将它放在与其他容器相同的网络上并以此方式实现。您甚至可以将其端口3306发布到主机的127.0.0.1接口。