我经常看到将docker容器的端口暴露给主机的解决方案。
在我的情况下,我想将一个本地端口从一个容器转发到另一个容器。我们假设我在容器A 上运行一项服务,该服务具有硬编码配置以访问localhost 3306上的数据库。但我想在容器B 上运行数据库服务器。
将从A-localhost:3306移植到B-IP:3306 的最佳方法是什么?
答案 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没有任何关系。