mkdir db-expose-33306
cd db-expose-33306
vim Dockerfile
编辑 dockerfile ,将其置于:
# Exposes port 3306 on linked "db" container, to be accessible at host:33306
FROM ubuntu:latest # (Recommended to use the same base as the DB container)
RUN apt-get update && \
apt-get -y install socat && \
apt-get clean
USER nobody
EXPOSE 33306
CMD socat -dddd TCP-LISTEN:33306,reuseaddr,fork TCP:db:3306
14 回答
这是另一个想法 . 使用SSH进行端口转发;当您的Docker主机是VM时,这也可以在OS X(可能还有Windows)中运行 .
有一个方便的HAProxy包装 .
这会为目标容器创建一个HAProxy . 十分简单 .
这就是我要做的事情:
提交实时容器 .
使用新映像再次运行容器,端口打开(我建议安装共享卷并打开ssh端口)
虽然您无法公开现有容器的新端口,但您可以在同一个Docker网络中启动一个新容器,并将其转发到原始容器 .
工作示例
启动一个侦听端口80的Web服务,但是 not 暴露其内部端口80(oops!):
找到它的Docker网络IP:
在端口8080暴露的情况下启动
verb/socat
,并使其将TCP流量转发到该IP的端口80:您现在可以在http://localhost:8080/上访问pastebin,并且您的请求转到
socat:1234
,后者将其转发到pastebin:80
,并且响应以相反的方式传递相同的路径 .我不得不处理同样的问题,并且能够在不停止任何正在运行的容器的情况下解决它 . 使用Docker 1.9.1,这是截至2016年2月的最新解决方案 . 无论如何,这个答案是@ ricardo-branco答案的详细版本,但对新用户更为深入 .
在我的场景中,我想暂时连接到在容器中运行的MySQL,并且由于其他应用程序容器已链接到它,因此停止,重新配置和重新运行数据库容器是不可能的 .
因为我'd like to access the MySQL database externally (from Sequel Pro via SSH tunneling), I' m将在主机上使用端口
33306
. (不是3306
,以防万一有外部MySQL实例在运行 . )大约一个小时的调整iptables证明没有结果,即使:
一步一步,这就是我做的:
编辑
dockerfile
,将其置于:然后构建图像:
然后运行它,链接到正在运行的容器 . (使用
-d
而不是-rm
将其保留在后台,直到明确停止并删除 . 我只希望它在这种情况下暂时运行 . )IPtables黑客行为不起作用,至少在Docker 1.4.1上是这样 .
最好的方法是使用公开端口运行另一个容器并使用socat继电器 . 这就是我用SQLPlus(临时)连接数据库所做的事情:
Dockerfile:
您可以使用像Weave Net这样的覆盖网络,它将为每个容器分配一个唯一的IP地址,并隐式地将所有端口暴露给网络的每个容器部分 .
编织还提供host network integration . 默认情况下禁用它,但是,如果您还要从主机访问容器IP地址(及其所有端口),则只需运行
weave expose
即可运行 .完全披露:我在Weaveworks工作 .
首先阅读Ricardo的回复 . 这对我有用 .
但是,如果正在使用docker-compose启动正在运行的容器,则存在这样的情况 . 这是因为docker-compose(我正在运行docker 1.17)创建了一个新网络 . 解决这种情况的方法是
docker network ls
然后追加以下
docker run -d --name sqlplus --link db:db -p 1521:1521 sqlplus --net network_name
您无法通过Docker执行此操作,但可以从主机访问容器的未公开端口 .
如果你有一个容器,其端口8000上运行的东西,你可以运行
要获取容器的IP地址,请运行以下命令:
在内部,Docker会在你运行图像时弹出来调用iptables,所以可能会有一些变化 .
在localhosts端口8001上公开容器的端口8000:
解决这个问题的一种方法是使用您想要的端口映射设置另一个容器,并比较 iptables-save 命令的输出(但是,我必须删除一些强制流量通过docker代理的其他选项) .
NOTE: this is subverting docker, so should be done with the awareness that it may well create blue smoke
要么
另一种选择是查看(新的?post 0.6.6?) - P选项 - 它将使用随机主机端口,然后连接它们 .
要么
使用0.6.5,您可以使用LINKs功能调出一个与现有容器对话的新容器,还有一些中继到该容器的-p标志? (我没用过LINKs)
要么
与docker 0.11?您可以使用
docker run --net host ..
将容器直接连接到主机的网络接口(即,net不是名称间隔的),因此在容器中打开的 all 端口将被暴露 .实时端口映射是不可能的,但是有多种方法可以为Docker容器提供虚拟机所具有的真实接口 .
Macvlan接口
Docker现在包含Macvlan network driver . 这会将Docker网络连接到"real world"接口,并允许您将该网络地址直接分配给容器(如虚拟机桥接模式) .
pipework
也可以map a real interface进入容器或旧版本的Docker中的setup a sub interface .路由IP
如果您可以控制网络,则可以将您的Docker主机用于容器中 .
然后将该网络分配给容器并设置Docker主机以通过docker网络路由数据包 .
共享主机接口
--net host
选项允许将主机接口共享到容器中,但由于共享特性,这可能不是在一个主机上运行多个容器的良好设置 .要添加到accepted answer
iptables
解决方案,我必须在主机上再运行两个命令才能将其打开到外部世界 .注意:我正在打开端口https(443),我的docker内部IP是
172.17.0.2
注意2:这些规则和时间只会持续到容器重新启动
以下是一些解决方案:
https://forums.docker.com/t/how-to-expose-port-on-running-container/3252/12
如果某人没有回答 - 请检查您的目标容器是否已在docker network中运行:
如果是,则应在同一网络中运行代理容器 .
最终命令:
您可以使用SSH创建隧道并在主机中公开容器 .
您可以通过两种方式执行此操作,从容器到主机以及从主机到容器 . 但是你需要一个像OpenSSH这样的SSH工具(一个是客户端,另一个是服务器) .
例如,在容器中,您可以这样做
您可以从此行(在容器中)找到容器IP地址:
然后在主机中,您可以这样做: