如何将端口从一个docker容器转发到另一个?

时间:2017-09-07 15:13:50

标签: docker portforwarding

我经常看到将docker容器的端口暴露给主机的解决方案。

在我的情况下,我想将一个本地端口从一个容器转发到另一个容器。我们假设我在容器A 上运行一项服务,该服务具有硬编码配置以访问localhost 3306上的数据库。但我想在容器B 上运行数据库服务器。

从A-localhost:3306移植到B-IP:3306 的最佳方法是什么?

7 个答案:

答案 0 :(得分:11)

在容器中和启动运行时安装socat

socat TCP-LISTEN:3306,fork TCP:B-IP:3306 &

这将在您的3306上本地收听,并将任意流量双向传递到B-IP:3306。 socat在名为socat的软件包中提供。因此,您将运行以下任何命令来安装它

$ yum install -y socat
$ apt install -y socat
$ apk add socat

修改-1

您甚至可以通过不触摸原始容器来实现此目的

<强> Dockerfile

FROM alpine
RUN apk update && apk add socat

按以下方式构建文件

docker build -t socat .

现在从同一个

运行一个容器
docker run --name mysql-bridge-a-to-b --net=container:<containerAid> socat socat TCP-LISTEN:3306,fork TCP:BIP:3306

这将在A&#39网络上运行此容器。因此,当它在A&#39网络上收听时,即使没有触及容器,localhost:3306也会在A中可用。

答案 1 :(得分:4)

您只需运行网络模式等于主机的容器即可。

docker run --network=host ...

在这种情况下,从容器的角度来看,localhost或127.0.0.1将引用主机。因此,如果您的数据库在侦听3306的另一个容器B中运行,则容器A中的localhost:3306的地址将命中容器B中的数据库。

答案 2 :(得分:3)

如果希望容器B的端口作为容器A上的本地主机端口公开,则可以将network选项设置为container模式来启动容器B,以在容器A的网络名称空间上启动容器B。

示例:

docker run --net=container:A postgres

位置:

  • A是您要映射到的容器的名称或标识符。

这将在与A相同的网络命名空间中的容器中启动postgres,因此在postgres容器中打开的任何端口都将在与A相同的接口上打开,并且应该在localhost位于容器A中。

答案 3 :(得分:1)

容器内部可以互相访问,而您不需要暴露或转发任何东西。

答案 4 :(得分:0)

您可以使用Docker-Compose完成此操作。

docker-compose.yml示例:

version: '3'
services:
  web:
    build: .web
    ports:
     - "5000:5000"
  mysql:
    build: .mysql
    ports:
     - "3306:3306"

这里有2个docker实例:web和mysql,因此每个docker实例可以使用您定义为服务的名称来看到对方。

希望这有帮助

答案 5 :(得分:0)

对于Windows上的开发,我们可以简单地使用return Convert.ToInt32(comm.ExecuteScalar());:请参见docker-for-windows networking

我想从集装箱到主机上的服务
我们建议您连接到特殊的DNS名称host.docker.internal,它将解析为主机使用的内部IP地址。这是出于开发目的,不适用于Windows的Docker Desktop以外的生产环境。

所以在您的情况下:

  • host.docker.internal发布端口container A
    该端口现在在主机上可用
  • 3306可以简单地连接到container B

答案 6 :(得分:0)

此解决方案对于所述用例来说是过大的手段,但是如果您在研究更大范围时遇到了这种情况。

Hashicorp Consul安装一个本地主机代理,它将本地主机端口代理到目录中注册的服务的ip地址和端口。 https://www.consul.io/intro

除了在我构建的系统中使用他们的产品外,我与Hashicorp没有任何关系。