我试图创建一个Docker容器,就像一个完整的虚拟机。我知道我可以在Dockerfile中使用EXPOSE指令来公开一个端口,并且我可以使用-p标志与docker run一起分配端口,但是一旦容器实际运行,是否有命令打开/映射其他端口?

例如,假设我有一个运行sshd的Docker容器。其他人使用容器ssh并安装httpd。有没有办法公开容器上的80端口,并将其映射到主机上的8080端口,以便人们可以访问容器中运行的web服务器,而无需重新启动它?


当前回答

以下是一些解决方案:

https://forums.docker.com/t/how-to-expose-port-on-running-container/3252/12

运行容器时映射端口的解决方案。 Docker运行-d——net=host myvnc 这将自动将端口公开并映射到您的主机

其他回答

这是另一个想法。使用SSH协议进行端口转发;当你的Docker主机是一个虚拟机时,它也可以在OS X(可能还有Windows)中工作。

docker exec -it <containterid> ssh -R5432:localhost:5432 <user>@<hostip>

我会这么做:

提交活动容器。 使用新映像再次运行容器,并打开端口(我建议挂载一个共享卷并打开ssh端口)

sudo docker ps 
sudo docker commit <containerid> <foo/live>
sudo docker run -i -p 22 -p 8000:80 -m /data:/data -t <foo/live> /bin/bash

Docker运行-i——expose=22 b5593e60c33b bash

裁判:https://forums.docker.com/t/how-to-expose-port-on-running-container/3252/5

这可能对你有帮助

如果没有答案,检查你的目标容器是否已经在docker网络中运行:

CONTAINER=my-target-container
docker inspect $CONTAINER | grep NetworkMode
        "NetworkMode": "my-network-name",

将它保存到变量$NET_NAME中:

NET_NAME=$(docker inspect --format '{{.HostConfig.NetworkMode}}' $CONTAINER)

如果是,您应该在同一网络中运行代理容器。

接下来查找容器的别名:

docker inspect $CONTAINER | grep -A2 Aliases
                "Aliases": [
                    "my-alias",
                    "23ea4ea42e34a"

将它保存到变量$ALIAS中:

ALIAS=$(docker inspect --format '{{index .NetworkSettings.Networks "'$NET_NAME'" "Aliases" 0}}' $CONTAINER)

现在在网络$NET_NAME中的容器中运行socat,桥接到$ALIASed容器的暴露端口(但没有发布):

docker run \
    --detach --name my-new-proxy \
    --net $NET_NAME \
    --publish 8080:1234 \
    alpine/socat TCP-LISTEN:1234,fork TCP-CONNECT:$ALIAS:80

你不能通过Docker来做到这一点,但是你可以从主机上访问容器未暴露的端口。

如果您有一个在端口8000上运行某些内容的容器,您可以运行

wget http://container_ip:8000

要获取容器的IP地址,运行以下2条命令:

docker ps
docker inspect container_name | grep IPAddress

在内部,当你运行一个图像时,Docker外壳会调用iptables,所以这可能会有一些变化。

将容器的端口8000暴露在本地主机的端口8001上:

iptables -t nat -A  DOCKER -p tcp --dport 8001 -j DNAT --to-destination 172.17.0.19:8000

解决这个问题的一种方法是使用您想要的端口映射设置另一个容器,并比较iptables-save命令的输出(尽管如此,我不得不删除一些迫使通信通过docker代理的其他选项)。

注意:这是在颠覆docker,所以应该注意到它可能会产生蓝烟。

OR

另一种选择是查看(new?- p选项-它将使用随机的主机端口,然后将它们连接起来。

OR

在0.6.5中,你可以使用LINKs特性来启动一个与现有容器对话的新容器,并附加一些对该容器的-p标志的中继?(我还没用过LINKs。)

OR

docker 0.11?你可以使用docker run——net host ..将容器直接连接到主机的网络接口(即,net没有命名空间),因此在容器中打开的所有端口都是公开的。