从我的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服务器。
主机和容器如何相互访问彼此的端口?
答案 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接口。