我经常看到将Docker容器的端口暴露给主机的解决方案。在我的例子中我想将本地端口从一个容器转发到另一个容器。假设我在container A上运行一个服务,该服务具有硬编码配置,可以访问localhost 3306上的db。但我想在container B上运行db服务器。从A-localhost:3306端口转发到B-IP:3306的最佳方式是什么?
dwthyt8l1#
在容器中安装socat,并在启动时运行
socat
socat TCP-LISTEN:3306,fork TCP:B-IP:3306 &
这将在您的3306上进行本地侦听,并将任何流量双向传递到B-IP:3306。socat在名为socat的包中可用。
B-IP:3306
$ yum install -y socat $ apt install -y socat $ apk add socat
编辑-1
你甚至可以做到这一点,不接触你原来的容器
停靠文件
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的网络上侦听时,即使A容器未被触及,localhost:3306也将在A中可用。
localhost:3306
1tu0hz3e2#
您可以简单地以等于host的网络模式运行容器。
docker run --network=host ...
在这种情况下,从容器的Angular 来看,localhost或127.0.0.1将引用主机。因此,如果您的数据库在另一个监听3306的容器B中运行,则容器A中的localhost:3306地址将命中容器B中的数据库。
kmynzznz3#
如果您希望容器B的端口在容器A上公开为localhost端口,则可以启动容器B,并将network选项设置为container模式,以在容器A的网络命名空间上启动容器B。示例:
network
container
docker run --net=container:A postgres
其中:
A
这将在与A相同的网络名称空间的容器中启动postgres,因此在postgres容器中打开的任何端口都将在与A相同的接口上打开,并且它应该在容器A中的localhost上可用。
localhost
sg24os4d4#
这个解决方案对于所述的用例来说是多余的,但是在研究更大范围时遇到这个情况。Hashicorp Consul安装一个localhost代理,它将本地主机端口代理到目录中注册的服务的ip地址和端口。https://www.consul.io/intro我和Hashicorp没有任何关系,除了在我构建的系统中使用他们的产品。
dzhpxtsq5#
对于Windows上的开发,我们可以简单地使用host.docker.internal:参见docker-for-windows网络我想从容器连接到主机上的服务我们建议您连接到特殊的DNS名称host.docker.internal,该名称解析为主机使用的内部IP地址。这是出于开发目的,在Docker Desktop for Windows之外的生产环境中不起作用。所以在你的例子中:
host.docker.internal
container A
3306
该端口现在在主机上可用
container B
host.docker.internal:3306
s5a0g9ez6#
容器可以在内部相互访问,不需要公开或转发任何内容。
krugob8w7#
你可以使用Docker-Compose。例如:
version: '3' services: web: build: .web ports: - "5000:5000" mysql: build: .mysql ports: - "3306:3306"
这里有两个docker示例:web和mysql,所以每个docker示例都可以使用你定义为服务的名称看到对方。希望这能帮上忙
7条答案
按热度按时间dwthyt8l1#
在容器中安装
socat
,并在启动时运行这将在您的3306上进行本地侦听,并将任何流量双向传递到
B-IP:3306
。socat在名为socat的包中可用。编辑-1
你甚至可以做到这一点,不接触你原来的容器
停靠文件
如下所示构建文件
现在运行一个容器从相同
这将在A的网络上运行此容器。因此,当它在A的网络上侦听时,即使A容器未被触及,
localhost:3306
也将在A中可用。1tu0hz3e2#
您可以简单地以等于host的网络模式运行容器。
在这种情况下,从容器的Angular 来看,localhost或127.0.0.1将引用主机。因此,如果您的数据库在另一个监听3306的容器B中运行,则容器A中的localhost:3306地址将命中容器B中的数据库。
kmynzznz3#
如果您希望容器B的端口在容器A上公开为localhost端口,则可以启动容器B,并将
network
选项设置为container
模式,以在容器A的网络命名空间上启动容器B。示例:
其中:
A
是要Map到的容器的名称或标识符。这将在与
A
相同的网络名称空间的容器中启动postgres,因此在postgres容器中打开的任何端口都将在与A
相同的接口上打开,并且它应该在容器A中的localhost
上可用。sg24os4d4#
这个解决方案对于所述的用例来说是多余的,但是在研究更大范围时遇到这个情况。
Hashicorp Consul安装一个localhost代理,它将本地主机端口代理到目录中注册的服务的ip地址和端口。https://www.consul.io/intro
我和Hashicorp没有任何关系,除了在我构建的系统中使用他们的产品。
dzhpxtsq5#
对于Windows上的开发,我们可以简单地使用
host.docker.internal
:参见docker-for-windows网络我想从容器连接到主机上的服务
我们建议您连接到特殊的DNS名称host.docker.internal,该名称解析为主机使用的内部IP地址。这是出于开发目的,在Docker Desktop for Windows之外的生产环境中不起作用。
所以在你的例子中:
container A
发布端口3306
该端口现在在主机上可用
container B
可以直接连接到host.docker.internal:3306
s5a0g9ez6#
容器可以在内部相互访问,不需要公开或转发任何内容。
krugob8w7#
你可以使用Docker-Compose。
例如:
这里有两个docker示例:web和mysql,所以每个docker示例都可以使用你定义为服务的名称看到对方。
希望这能帮上忙