我试图创建一个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服务器,而无需重新启动它?
当前回答
如果没有答案,检查你的目标容器是否已经在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
其他回答
您可以使用SSH创建隧道并在主机中公开容器。
可以采用两种方式,从容器到主机或从主机到容器。但是你需要一个SSH工具,比如OpenSSH(一个是客户端,另一个是服务器)。
例如,在容器中,可以这样做
$ yum install -y openssh openssh-server.x86_64
service sshd restart
Stopping sshd: [FAILED]
Generating SSH2 RSA host key: [ OK ]
Generating SSH1 RSA host key: [ OK ]
Generating SSH2 DSA host key: [ OK ]
Starting sshd: [ OK ]
$ passwd # You need to set a root password..
你可以从这一行(在容器中)找到容器的IP地址:
$ ifconfig eth0 | grep "inet addr" | sed 's/^[^:]*:\([^ ]*\).*/\1/g'
172.17.0.2
然后在主机中,你可以这样做:
sudo ssh -NfL 80:0.0.0.0:80 root@172.17.0.2
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
这是另一个想法。使用SSH协议进行端口转发;当你的Docker主机是一个虚拟机时,它也可以在OS X(可能还有Windows)中工作。
docker exec -it <containterid> ssh -R5432:localhost:5432 <user>@<hostip>
有一个方便的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。
我会这么做:
提交活动容器。 使用新映像再次运行容器,并打开端口(我建议挂载一个共享卷并打开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