将主机端口转发到 docker 容器

新手上路,请多包涵

是否可以让主机打开 Docker 容器访问端口?具体来说,我在主机上运行了 MongoDB 和 RabbitMQ,我想在 Docker 容器中运行一个进程来监听队列并(可选)写入数据库。

我知道我可以将一个端口从容器转发到主机(通过 -p 选项),并从 Docker 容器内连接到外部世界(即互联网),但我不想公开 RabbitMQ 和 MongoDB 端口从宿主到外界。

编辑:一些澄清:

 Starting Nmap 5.21 ( http://nmap.org ) at 2013-07-22 22:39 CEST
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00027s latency).
PORT     STATE SERVICE
6311/tcp open  unknown

joelkuiper@vps20528 ~ % docker run -i -t base /bin/bash
root@f043b4b235a7:/# apt-get install nmap
root@f043b4b235a7:/# nmap 172.16.42.1 -p 6311 # IP found via docker inspect -> gateway

Starting Nmap 6.00 ( http://nmap.org ) at 2013-07-22 20:43 UTC
Nmap scan report for 172.16.42.1
Host is up (0.000060s latency).
PORT     STATE    SERVICE
6311/tcp filtered unknown
MAC Address: E2:69:9C:11:42:65 (Unknown)

Nmap done: 1 IP address (1 host up) scanned in 13.31 seconds

我必须这样做才能在容器内获得任何互联网连接: 我的防火墙阻止了从 docker 容器到外部的网络连接

编辑:最终我使用 管道 创建了一个自定义网桥,并让服务在网桥 IP 上侦听。我采用了这种方法,而不是让 MongoDB 和 RabbitMQ 在 docker 桥上监听,因为它提供了更大的灵活性。

原文由 JoelKuiper 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.1k
2 个回答

您的 docker 主机向所有容器公开了一个适配器。假设您使用的是最近的 ubuntu,您可以运行

ip addr

这将为您提供网络适配器列表,其中一个看起来像

3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
link/ether 22:23:6b:28:6b:e0 brd ff:ff:ff:ff:ff:ff
inet 172.17.42.1/16 scope global docker0
inet6 fe80::a402:65ff:fe86:bba6/64 scope link
   valid_lft forever preferred_lft forever

您需要告诉 rabbit/mongo 绑定到该 IP (172.17.42.1)。之后,您应该能够从容器中打开到 172.17.42.1 的连接。

原文由 Seldo 发布,翻译遵循 CC BY-SA 3.0 许可协议

一种简单但相对不安全的方法是使用 --net=host 选项 docker run

此选项使容器使用主机的网络堆栈。然后,您只需使用“localhost”作为主机名即可连接到主机上运行的服务。

这更容易配置,因为您不必将服务配置为接受来自 docker 容器 IP 地址的连接,也不必告诉 docker 容器要连接的特定 IP 地址或主机名,只需一个港口。

例如,您可以通过运行以下命令对其进行测试,假设您的图像名为 my_image ,您的图像包含 telnet 实用程序,并且您要连接的服务是在端口 25 上:

 docker run --rm -i -t --net=host my_image telnet localhost 25

如果您考虑这样做,请参阅此页面上的安全注意事项:

https://docs.docker.com/articles/networking/

它说:

–net=host – 告诉 Docker 跳过将容器放置在单独的网络堆栈中。本质上,这个选择告诉 Docker 不要容器化容器的网络!虽然容器进程仍将被限制在它们自己的文件系统和进程列表以及资源限制中,但一个快速的 ip addr 命令将向您显示,在网络方面,它们位于主 Docker 主机的“外部”,并且可以完全访问其网络接口.请注意,这不会让容器重新配置主机网络堆栈——这需要 –privileged=true——但它确实让容器进程像任何其他根进程一样打开低编号端口。它还允许容器访问本地网络服务,如 D-bus。这可能导致容器中的进程能够执行意外的事情,例如重新启动计算机。您应该谨慎使用此选项。

原文由 David Grayson 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题