Ale*_*rov 13 networking docker
我的场景:我想让我的基于 docker 的服务知道从网络调用它们的 IP(我的应用程序的要求。)
我在云 VPS、debian jessie 和 docker 1.12.2 上运行。
我nc在详细模式下使用打开端口8080。
docker run --rm -p "8080:8080" centos bash -c "yum install -y nc && nc -vv -kl -p 8080"
Run Code Online (Sandbox Code Playgroud)
说,VPS 有域example.com,从我的另一台机器,假设有dead:::::beef我调用的 IP
nc example.com 8080
Run Code Online (Sandbox Code Playgroud)
该服务器说:
Ncat: Version 6.40 ( http://nmap.org/ncat )
Ncat: Listening on :::8080
Ncat: Listening on 0.0.0.0:8080
Ncat: Connection from 172.17.0.1.
Ncat: Connection from 172.17.0.1:49799.
Run Code Online (Sandbox Code Playgroud)
172.17.0.1位于服务器的本地网络上,当然与我的客户端无关。实际上:
docker0 Link encap:Ethernet HWaddr ....
inet addr:172.17.0.1 Bcast:0.0.0.0 Mask:255.255.0.0
Run Code Online (Sandbox Code Playgroud)
如果我以主机网络模式启动容器
docker run --rm --net=host -p "8080:8080" centos bash -c "yum install -y nc && nc -vv -kl -p 8080"
Run Code Online (Sandbox Code Playgroud)
并再次呼叫我的服务器
nc example.com 8080
Run Code Online (Sandbox Code Playgroud)
我得到了预期的结果:
Ncat: Connection from dead:::::beef.
Ncat: Connection from dead:::::beef:55650.
Run Code Online (Sandbox Code Playgroud)
我的问题是:
nc因此在容器中运行只能看到调用来自 docker 守护进程的 IP。Les*_*ter 11
根据文档,默认驱动程序(即当您未--net=host在 中指定时docker run,是bridge网络驱动程序。
这不是关于 docker '屏蔽' IP 地址,而是关于如何bridged和host网络模式变化。
就 Docker 而言,桥接网络使用软件桥接器,允许连接到同一桥接网络的容器进行通信,同时提供与未连接到该桥接网络的容器的隔离。Docker 网桥驱动程序会自动在宿主机中安装规则,以便不同网桥网络上的容器无法直接相互通信。
Docker 创建了一个隔离网络,以便桥接网络中的每个容器都可以进行通信,在您的情况下,它是docker0. 因此,默认情况下,您的 docker 主机上的容器在此网络内进行通信。
正如您现在可能已经发现的那样,yes172.17.0.1是docker0网络上的默认路由,但这并不充当将数据包转发到目的地的路由器,因此您将其视为来自 netcat 输出的源。
事实上,您可以通过ss -tulnp在 docker 主机上运行来验证这一点。您应该会看到侦听端口 8080 的进程是 docker。
另一方面,使用主机网络驱动程序意味着容器和主机之间没有隔离。您可以通过ss -tulnp在 docker 主机上运行来验证这一点;您应该看到在套接字上而不是在 docker 上侦听的进程(在您的情况下,您应该看到nc)。