如何将docker容器中的单个端口redirect到容器的主机?

为了使项目的开发更容易,我在docker容器中放了一些它依赖的服务。 这使得项目configuration中的“localhost”在传递给其中一个容器时会有所不同。

编辑

要清楚,我试图转发一个容器的端口到主机,所以当容器中运行的进程试图访问localhost:5432时,它连接到主机的端口5432。

EndEdit中

我目前正在使用

HOST_IP=`ip route | grep default | awk '{ printf "%s",$3 }'` cat /etc/hosts | sed "s/127.0.0.1/$HOST_IP/" > /tmp/etc_hosts cp /tmp/etc_hosts /etc/hosts 

将任何目标为'本地主机'redirect到容器的主机。 它在这种情况下工作,但我宁愿find一种方法来做到这一点,只为所需的端口,因为我希望它不会在其他情况下工作。

这是我想出来做的,但是这不起作用。 当容器中的连接是localhost:5432时,它将尝试连接到容器的5432而不是主机的:

 # --- These are the things that should make redirecting port 5432 to the host machine # work, provided the container is run in privileged mode. sysctl -w net.ipv4.ip_forward=1 sysctl -w net.ipv4.conf.all.route_localnet=1 iptables -t nat -A PREROUTING -p tcp --dport 5432 -j DNAT --to 172.19.0.1:5432 iptables -A FORWARD -d 172.19.0.1 -p tcp --dport 5432 -j ACCEPT iptables -t nat -A POSTROUTING -j MASQUERADE 

如果我理解的很好,为了开发,你需要本地主机parsing到一个特定的容器,包括从另一个容器调用的时候。

主机转发

正如你所提到的那样,重写你的hosts文件并不是一个好主意,因为如果你将本地主机devise成与本地主机不同的东西,那么很多服务都可以试验问题。

但是你可以考虑一些解决scheme。

Docker工具箱

如果使用Docker Toolbox运行Docker Toolbox ,或者在虚拟机上运行Docker Toolbox ,则中间虚拟机是可见的,所以localhost将代表它。 您必须运行容器,公开此端口,然后在Virtualbox中设置端口转发。 如果我使用WordPress作为例子:

  1. docker run -p 80:80 --name website -d wordpress
  2. Virtual Box – >您的docker VM(通常称为默认 ) – > Network – > Adapter 1 – >端口转发 – >创build从主机8080到guest虚拟机80的映射

这将使WordPresshttp://localhost:8080可用。 请注意,在MacOS下,内核限制非特权端口转发(1024以下的端口)。

这个端口转发可以在命令行中创build,如果你想把它放在一个脚本中:
VBoxManage modifyvm "default" --natpf1 "app,tcp,,8080,,80"

Docker for Windows / Docker for Mac

如果通过Docker for Windows Docker for Mac (或直接在Linux下)的Docker for Windows / Docker for Mac运行docker ,而不是Docker Toolbox ,则可以使用Scott的文章中指定的-p参数运行容器,并且您的服务将在localhost上可用在这个端口上(因为中间虚拟机是透明的,或者在Linux下没有虚拟机):

docker run -p 5432:5432 --name myapp -d myimage将使myapplocalhost:5432可用。

socat(或iptables)

你可以通过这种方式在你的主机上运行socat来把特定端口上的通信转发给你的容器:

socat TCP-LISTEN:5432,fork,reuseaddr,user=node,group=node,mode=777 TCP:172.19.0.1:5432 &

(其中172.19.0.1是您的容器IP)

集装箱转运

– networking

你的容器有自己的hosts文件,你可以通过发出这样的命令来看到:

docker run ubuntu cat /etc/hosts

您可以使用--add-host参数向hosts添加条目:

docker run --add-host domain:1.2.3.4 --add-host domain2:5.6.7.8 ubuntu cat /etc/hosts

但是这个解决scheme对于localhost是没用的,因为它不会删除以前的localhost关联。 你正在寻找什么(什么更清洁)是参数 – --network=host ,它允许容器共享主机的networking接口:

docker run --network=host ubuntu

这样,您的容器将能够使用其端口在本地主机上调用其他容器服务。

正确的方式

当然,实现你想要的东西的正确方法是将你的容器链接在一起,并使用它们的链接名称而不是本地主机

 docker run -d --name mariadb -e MYSQL_ROOT_PASSWORD=password mariadb docker run -d --name="wordpress" -p 8080:80 -e WORDPRESS_DB_PASSWORD=password --link mariadb:mysql wordpress 

在这种情况下, WordPress容器将在其hosts文件中有一个mysql条目,指向mariadb容器的IP地址。 要看到它,在WordPress容器中打开一个bash会话,并自己看看。

 docker exec -ti wordpress bash #cat /etc/hosts 

向我们展示如何启动您的容器

端口映射可以发生在您的docker运行命令:-p hostport:containerport

如在

 docker run -p 5432:5432 --name mycontainer -d myimage