连接到暴露的Docker容器

4

我想将一个docker容器暴露给外部世界,而不仅仅是主机。当我从基础的CentOS镜像创建图像时,它看起来像这样:

# install openssh server and ssh client
RUN yum install -y openssh-server
RUN yum install -y openssh-clients

RUN echo 'root:password' | chpasswd

RUN sed -ri 's/UsePAM yes/#UsePAM yes/g' /etc/ssh/sshd_config
RUN sed -ri 's/#UsePAM no/UsePAM no/g' /etc/ssh/sshd_config

EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]

我这样运行这个镜像:

sudo docker run -d -P crystal/ssh

当我尝试使用sudo docker ps查看容器时,我看到了Ports:

0.0.0.0:49154->22tcp

如果我在主机上(ubuntu)运行ifconfig,我会看到docker0 inet addr:172.17.42.1。我可以从我的主机ping通这个地址,但是从其他任何机器都无法ping通。我在设置容器连接外部世界方面做错了什么吗?谢谢。
编辑: 我尝试检查容器的IPAddress,并且我看到IPAddress: 172.17.0.28,但我也不能ping通它...
如果我尝试使用nmap,则似乎返回端口。那是否意味着它已开放,如果我已经设置了ssh,我就能够ssh进入容器?谢谢。
nmap -p49154 10.211.55.1 显示该端口已开放,但服务未知。
我尝试通过ssh -l root -p49154 10.211.55.1进行ssh登录,但结果是...
Read from socket failed: Connection reset by peer.

你尝试过连接到主机的公共IP地址,端口号为49154吗?我的意思是eth0接口的IP地址? - Jiri
@Jiri 我尝试了 nmap -p 49154 <eth0 ip>,返回结果为:49155/tcp, open, service unknown - Crystal
2个回答

2

更新

你的Dockerfile有误。你的sshd没有正确配置,它无法正常启动,这就是容器不能正确响应22端口的原因。请查看错误信息:

Could not load host key: /etc/ssh/ssh_host_rsa_key
Could not load host key: /etc/ssh/ssh_host_dsa_key

您需要生成主机密钥。这行代码可以实现此功能:
RUN ssh-keygen -P "" -t dsa -f /etc/ssh/ssh_host_dsa_key

之前的回答

你可能需要查找eth0接口(可以从网络访问)的IP地址,并通过此IP地址连接到容器。来自/发送到docker0桥的流量默认应转发到您的eth接口。

此外,最好检查是否启用了IP转发:

cat /proc/sys/net/ipv4/ip_forward

这个命令应该返回1,否则您需要执行:

sudo echo 1 > /proc/sys/net/ipv4/ip_forward

问:为什么可以通过这种方式连接到容器?

如果您启用了IP转发功能,则从eth0接口传入的数据包将被转发到虚拟的docker0接口。神奇的事情发生了,数据包被正确地接收到容器中。有关更多详细信息,请参见Docker高级网络

但是docker0不是普通的接口。它是一个虚拟以太网桥,自动转发任何附加到它的其他网络接口之间的数据包。这使得容器可以与主机和彼此通信。每次Docker创建一个容器时,它都会创建一对“同级”接口,就像管道的两端 - 发送到其中一个的数据包将在另一个上接收。它将同级之一给容器,成为其eth0接口,并将另一个同级保留在主机机器的命名空间中,具有类似vethAQI2QT的唯一名称。通过将每个veth *接口绑定到docker0桥上,Docker创建了一个在主机机器和每个Docker容器之间共享的虚拟子网。


我该如何从eth0地址连接到容器的IP地址?假设docker的IP地址为172.17.42.5,eth0的IP地址为10.211.55.1,那么我该如何从外部连接?顺便说一下,我正在尝试从docker文档中进行ssh连接。(http://docs.docker.io.s3-website-us-west-2.amazonaws.com/examples/running_ssh_service/)。ip_forward返回了1。 - Crystal
@Crystal,你无法从外部连接到“容器IP地址”,但是只有发送到eth0特定主机端口的数据包会被转发到容器特定端口。我已经更新了我的答案。 - Jiri

0

你无法从主机外部ping通172.17.42.1,因为它是私有IP,只能在私有网络中访问,因为它是运行Docker容器的主机创建的虚拟交换机docker0和连接到桥接docker0的虚拟接口的Docker容器...

此外,172.17.42.1是桥接docker0的IP地址,而不是您的Docker实例的IP地址。如果您想知道Docker实例的IP地址,必须在其中运行ifconfig或使用docker inspect

我不是端口映射方面的专家,但对我来说,这意味着要访问端口22上的Docker容器,您必须连接到主机的49154端口,并将所有流量转发。


我更新了我的问题,但我尝试从“inspect”命令ping IP地址,仍然收到请求超时的错误。 - Crystal
从外部看,您将始终因为它是私有地址而获得ping的请求超时。如果您运行另一个docker容器,则每个docker都可以互相ping,但是没有主机可以从外部ping它们。在ssh命令之前,我认为Jiri的答案可能是解决方案。 - mgaido

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接