是否可以让主机打开Docker容器访问端口?具体来说,我在主机上运行MongoDB和RabbitMQ,我想在Docker容器中运行一个进程来监听队列并(可选)写入数据库 .
我知道我可以从容器转发到主机(通过-p选项),我可以从Docker容器中连接到外部世界(即Internet),但我不想公开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
我不得不这样做,以获得容器的任何互联网连接:My firewall is blocking network connections from the docker container to outside
EDIT :最后我使用pipework创建了一个自定义网桥,并让服务监听网桥IP . 我采用这种方法而不是让MongoDB和RabbitMQ在docker桥上监听,因为它提供了更大的灵活性 .
5 回答
您的docker主机向所有容器公开适配器 . 假设你是最近的ubuntu,你可以运行
这将为您提供一个网络适配器列表,其中一个看起来像
你需要告诉rabbit / mongo绑定到那个IP(172.17.42.1) . 之后,您应该能够从容器中打开到172.17.42.1的连接 .
一种简单但相对不安全的方法是使用
--net=host
选项docker run
.此选项使容器使用主机的网络堆栈 . 然后,您只需使用“localhost”作为主机名即可连接到主机上运行的服务 .
这更容易配置,因为您不必将服务配置为接受来自docker容器的IP地址的连接,并且您不必告知docker容器要连接的特定IP地址或主机名,只需一个港口 .
例如,您可以通过运行以下命令来测试它,该命令假设您的图像被称为
my_image
,您的图像包含telnet
实用程序,并且您要连接的服务位于端口25上:如果您考虑这样做,请在此页面上查看有关安全性的警告:
https://docs.docker.com/articles/networking/
它说:
您还可以创建一个ssh隧道 .
docker-compose.yml
:docker/Dockerfile.tunnel
:config/ssh/config
:这样,
elasticsearch
通过运行服务(Elasticsearch,MongoDB,PostgreSQL)与服务器 Build 隧道,并使用该服务公开端口9200 .如果MongoDB和RabbitMQ在主机上运行,那么该端口应该已经公开,因为它不在Docker中 .
您不需要
-p
选项来公开从容器到主机的端口 . 默认情况下,所有端口都是公开的 .-p
选项允许您将容器中的端口公开给主机外部 .所以,我的猜测是你根本不需要
-p
它应该工作正常:)我有一个类似的问题从docker容器访问LDAP服务器 . 我为容器设置了固定的IP并添加了防火墙规则 .
docker-compose.yml:
iptables规则:
iptables -A INPUT -j ACCEPT -p tcp -s 192.168.50.2 -d $192.168.50.1 --dport portnumberOnHost
在容器内访问
dockerhost:portnumberOnHost