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

How can I forward a port from one docker container to another?

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

在我的例子中我想将一个本地端口从一个容器转发到另一个容器。

假设我 运行 容器 A 上的一项服务具有 硬编码配置以访问本地主机 3306 上的数据库 .但是我想 运行 容器 B 上的数据库服务器。

端口转发 从 A-localhost:3306 到 B-IP:3306 的最佳方法是什么?

你可以用 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 实例都可以使用您定义为服务的名称相互查看。

希望对您有所帮助

在您的容器中安装 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 的网络上。因此,当它在 A 的网络上侦听时,localhost:3306 将在 A 中可用,即使 A 容器未被触及。

你可以简单地运行网络模式等于主机的容器。

docker run --network=host ...

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

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

示例:

docker run --net=container:A postgres

其中:

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

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

对于 Windows 的开发,我们可以简单地使用 host.docker.internal:参见 docker-for-windows networking

I WANT TO CONNECT FROM A CONTAINER TO A SERVICE ON THE HOST
We recommend that you connect to the special DNS name host.docker.internal which resolves to the internal IP address used by the host. This is for development purpose and will not work in a production environment outside of Docker Desktop for Windows.

所以在你的情况下:

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

这个解决方案对于所述的用例来说有点矫枉过正,但在这种情况下,你 运行 在研究更大范围的同时跨越这个。

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

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

容器可以在内部相互访问你不需要公开或转发任何东西。