我试图创建一个Docker容器,就像一个完整的虚拟机。我知道我可以在Dockerfile中使用EXPOSE指令来公开一个端口,并且我可以使用-p标志与docker run一起分配端口,但是一旦容器实际运行,是否有命令打开/映射其他端口?
例如,假设我有一个运行sshd的Docker容器。其他人使用容器ssh并安装httpd。有没有办法公开容器上的80端口,并将其映射到主机上的8080端口,以便人们可以访问容器中运行的web服务器,而无需重新启动它?
我试图创建一个Docker容器,就像一个完整的虚拟机。我知道我可以在Dockerfile中使用EXPOSE指令来公开一个端口,并且我可以使用-p标志与docker run一起分配端口,但是一旦容器实际运行,是否有命令打开/映射其他端口?
例如,假设我有一个运行sshd的Docker容器。其他人使用容器ssh并安装httpd。有没有办法公开容器上的80端口,并将其映射到主机上的8080端口,以便人们可以访问容器中运行的web服务器,而无需重新启动它?
当前回答
基于Robm的回答,我创建了一个Docker映像和一个名为portcat的Bash脚本。
使用portcat,您可以轻松地将多个端口映射到现有的Docker容器。使用(可选)Bash脚本的示例:
curl -sL https://raw.githubusercontent.com/archan937/portcat/master/script/install | sudo bash
portcat my-awesome-container 3456 4444:8080
好了!Portcat正在映射:
Port 3456到my-awesome-container:3456 端口4444到my-awesome-container:8080
请注意,Bash脚本是可选的,以下命令:
ipAddress=$(docker inspect my-awesome-container | grep IPAddress | grep -o '[0-9]\{1,3\}\(\.[0-9]\{1,3\}\)\{3\}' | head -n 1)
docker run -p 3456:3456 -p 4444:4444 --name=alpine-portcat -it pmelegend/portcat:latest $ipAddress 3456 4444:8080
我希望portcat能派上用场。干杯!
其他回答
您可以使用像Weave Net这样的覆盖网络,它将为每个容器分配唯一的IP地址,并隐式地将所有端口暴露给网络的每个容器部分。
Weave还提供主机网络集成。缺省情况下是禁用的,但是,如果您还想从主机访问容器IP地址(及其所有端口),您可以简单地运行weave expose。
坦白说,我在纺织工场工作。
基于Robm的回答,我创建了一个Docker映像和一个名为portcat的Bash脚本。
使用portcat,您可以轻松地将多个端口映射到现有的Docker容器。使用(可选)Bash脚本的示例:
curl -sL https://raw.githubusercontent.com/archan937/portcat/master/script/install | sudo bash
portcat my-awesome-container 3456 4444:8080
好了!Portcat正在映射:
Port 3456到my-awesome-container:3456 端口4444到my-awesome-container:8080
请注意,Bash脚本是可选的,以下命令:
ipAddress=$(docker inspect my-awesome-container | grep IPAddress | grep -o '[0-9]\{1,3\}\(\.[0-9]\{1,3\}\)\{3\}' | head -n 1)
docker run -p 3456:3456 -p 4444:4444 --name=alpine-portcat -it pmelegend/portcat:latest $ipAddress 3456 4444:8080
我希望portcat能派上用场。干杯!
有一个方便的HAProxy包装器。
docker run -it -p LOCALPORT:PROXYPORT --rm --link TARGET_CONTAINER:EZNAME -e "BACKEND_HOST=EZNAME" -e "BACKEND_PORT=PROXYPORT" demandbase/docker-tcp-proxy
这将为目标容器创建一个HAProxy。容易peasy。
IPtables黑客不能工作,至少在Docker 1.4.1上是这样。
最好的方法是使用暴露的端口运行另一个容器,并使用socat进行中继。下面是我使用SQLPlus(临时)连接数据库所做的工作:
docker run -d --name sqlplus --link db:db -p 1521:1521 sqlplus
Dockerfile:
FROM debian:7
RUN apt-get update && \
apt-get -y install socat && \
apt-get clean
USER nobody
CMD socat -dddd TCP-LISTEN:1521,reuseaddr,fork TCP:db:1521
不可能进行实时端口映射,但有多种方法可以给Docker容器提供类似虚拟机的真实接口。
Macvlan接口
Docker现在包含一个Macvlan网络驱动程序。这将Docker网络附加到一个“真实世界”接口上,并允许你直接将网络地址分配给容器(就像虚拟机桥接模式)。
docker network create \
-d macvlan \
--subnet=172.16.86.0/24 \
--gateway=172.16.86.1 \
-o parent=eth0 pub_net
管道也可以将一个真实的接口映射到容器中,或者在旧版本的Docker中设置一个子接口。
IP的路由
如果你可以控制网络,你可以将额外的网络路由到Docker主机中,以供容器使用。
然后将该网络分配给容器,并设置Docker主机通过Docker网络路由数据包。
共享主机接口
——net host选项允许将主机接口共享到一个容器中,但由于共享的性质,这可能不是在一个主机上运行多个容器的良好设置。