我的主机上有一个守护进程运行在某个端口(即8008)上,我的代码通常通过联系localhost:8008与守护进程交互。
我现在已经容器化了我的代码,但是还没有容器化守护进程。我怎样才能把我的容器上的localhost:8008转发到运行容器的主机上的localhost:8008(从而也转发守护进程)呢?
以下是我的主机上的netstat -tlnp
。我希望容器将localhost:2009转发到主机上的localhost:2009
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:2009 0.0.0.0:* LISTEN 22547/ssh
tcp6 0 0 :::22 :::* LISTEN -
tcp6 0 0 ::1:2009 :::* LISTEN 22547/ssh
7条答案
按热度按时间4dbbbstv1#
我不确定你是否可以用docker的设置来做到这一点。如果我的理解是正确的,暴露端口不是你要找的。相反,建立从容器到主机的ssh端口转发可能是答案。
0md85ypi2#
您可以轻松地使用
-p 127.0.0.1:8008:8008
并将容器的端口8008
转发到localhost的端口8008
。6ju8rftf3#
如果在本地计算机上执行此操作,则可以在启动容器(
--network host
)时简单地将网络类型指定为host
,这将使主机与Docker容器共享网络。例如:
启动容器:
在主机上,运行:
现在从容器运行:
如果一切顺利,您将在主机终端上看到流量。
kninwzqo4#
docker run -d --name <NAME OF YOUR CONTAINER> -p 8008:8008 <YOUR IMAGE>
这会将容器中的端口
8008
发布到主机上的8008
。cpjpxq1n5#
因此,您需要考虑的是Docker容器有自己的网络堆栈(除非您明确告诉它与
--net=host
共享主机的堆栈)这意味着端口需要在Docker容器内部和外部都公开(文件),容器上公开的端口需要显式绑定到主机端口(在docker run
命令中使用-p xxxx:yyyy
)或隐式(在您的Dockerfile中使用EXPOSE
,在命令行中使用-P
),就像这里说的那样。如果您的Dockerfile不包含EXPOSE 8008
,或者您没有在docker run
命令中指定--expose 8008
,你的容器不能与外界对话,* 即使你在你的docker run
命令中使用-p 8008:8008
!*因此,要使主机上的tcp/8008与容器上的tcp/8008链接,您需要在Dockerfile中使用
EXPOSE 8008
(然后docker build
您的容器)或docker run command
中的--expose 8008
。此外,您需要使用-P
来隐式地或使用-p 8008:8008
来显式地将所公开的容器端口链接到主机端口。执行此操作的docker run
命令示例如下所示:docker run -it --expose 8008 -p 8008:8008 myContainer
记住在
-p 8008:8008
命令行选项中,此操作的顺序是-p HOST_PORT:CONTAINER_PORT
是很方便的。别忘了,除非您在主机 * 上的iptables * 中解除了该端口的阻塞,否则您将无法从互联网上的另一台计算机SSH到您的container。我总是最终忘记这一点,浪费半个小时才想起我忘记了主机上那个特定的tcp端口的iptables -A INPUT ...
。但是您应该能够在不使用iptables规则的情况下从您的主机通过SSH连接到容器,因为它对本地连接使用了回环。qv7cva1a6#
TL;DR:您可以使用特殊的主机名
host.docker.internal
来代替localhost
* 在容器内 * 的任何地方,您想要访问主机上的localhost
。--add-host=host.docker.internal:host-gateway
以启用该功能。完整答案:主机运行的是MacOS还是Windows?Docker Desktop文档中隐藏的事实是,MacOS上没有docker 0桥,Windows上也没有docker 0桥。显然这就是原因。在这两种情况下,解决方法都是(紧接在,在标题为“使用案例和解决方法”的子章节中)是使用特殊主机名
host.docker.internal
来代替要在主机上访问localhost
的容器内的任何位置的localhost
。如果主机是Linux,则有some Linux-only techniques for achieving this。但是,*
host.docker.internal
也可用于Linux主机,但必须先启用它。* 请参阅TL的Linux部分;DR,见上文,以获取说明。通过这种方法,在OP的情况下,应该使用
host.docker.internal:8008
而不是localhost:8008
。注意,这是在容器 * 内运行的应用程序代码的代码或配置更改 。没有必要在容器配置中提及端口。 不要尝试在docker run
命令行中使用-p
或--expose
*。不仅没有必要,但是如果您希望容器连接到的主机应用程序已经在侦听该端口,则容器将无法启动。disbfnqx7#
在检查了答案并做了一些调查后,我相信有两种方法可以做到这一点,这两种方法只适用于Linux环境。
第一个是在这篇文章How to access host port from docker container
第二个应该是当你
docker run
或docker container create
时设置你的--network=host
,在这种情况下,你的docker将使用你在Mac中使用的相同网络接口。但是,上面两种方式都不能在Mac中使用,所以我认为在Mac环境中不能从容器转发到主机,如果我错了请纠正我。