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

时间:2017-01-09 19:42:50

标签: docker iptables

为了使项目的开发更容易,我在docker容器中放了一些依赖它的服务。这使得#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

重定向任何定位' localhost'到集装箱的主人。它适用于这种情况,但我更愿意找到一种方法,只为所需的端口做到这一点,因为我希望它不会在其他情况下工作。

这是我想出来的,但是它不起作用;当容器中的连接是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

2 个答案:

答案 0 :(得分:3)

如果我理解得很好,那么对于开发,您需要 localhost 来解析特定容器,包括从另一个容器调用它时。

主机转发

正如您所提到的,重写您的hosts文件并不是一个好主意,因为如果您将 localhost 设计为与...不同的东西,许多服务可以试验问题...你当地的主人。

但你可以考虑一些解决方案。

Docker Toolbox

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

  1. docker run -p 80:80 --name website -d wordpress
  2. 虚拟盒子 - >您的docker VM(通常称为默认) - >网络 - >适配器1 - >端口转发 - >创建从主机8080到访客80的映射
  3. 它将在http://localhost:8080处提供 Wordpress 。请注意,在 MacOS 下,内核限制了非特权端口转发(1024以下的端口)。

    如果要将其放入脚本中,可以在命令行中创建此端口转发:
    VBoxManage modifyvm "default" --natpf1 "app,tcp,,8080,,80"

    适用于Windows的Docker /适用于Mac的Docker

    如果通过Docker for Windows / Docker for Mac(或直接在Linux下)而不是Docker Toolbox运行 docker ,则可以使用<}运行容器由 Scott 发布的-p参数,您的服务将在此端口的 localhost 上提供(因为中间虚拟机是透明的,或Linux下没有VM):

    docker run -p 5432:5432 --name myapp -d myimage会在localhost:5432提供 myapp

    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)

    货柜转发

    - 网络

    您的容器有自己的hosts文件,您可以通过发出以下命令来查看:

    docker run ubuntu cat /etc/hosts

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

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

    但是,此解决方案对localhost无用,因为它不会删除以前的localhost关联。您正在寻找的(以及更干净的)是参数--network=host,它允许容器共享主机的网络接口:

    docker run --network=host ubuntu

    这样,您的容器将能够使用其端口调用localhost上的其他容器服务。

    正确的方式

    当然,实现所需内容的正确方法是将容器链接在一起并使用其链接名称而不是 localhost

    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
    

答案 1 :(得分:1)

告诉我们您如何启动容器

端口映射可能发生在docker run命令中:-p hostport:containerport

,如

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