【发布时间】:2018-09-15 04:44:16
【问题描述】:
请注意,这与 How to expose a service running inside a docker container, bound to localhost 不同,后者可以在 Docker for Linux 中以多种方式解决,例如通过 --net host 甚至 -v 来绑定我的 Linux 风格客户端等。我的问题是特定于 Docker对于 Mac,所以它不是那么简单。
我有一个绑定到localhost:5005 的 TCP 服务器在 Docker for Mac 中运行。 (出于安全原因,我不能绑定到0.0.0.0:5005。)
我有一个 TCP 客户端从我的 Mac(不在 docker 容器内)向该服务器发送请求。
我的问题是,我该如何让它发挥作用?
在 Linux Docker 中,我会简单地使用 --net=host,以便服务器绑定到我的主机 lo 接口,但似乎 Docker for Mac 在托管 VM 上运行,因此 host 网络行为是不同的行为。
为了说明我的观点:
在 MacBook 上
它根本行不通
[me@MacBook App]$ docker run -v `pwd`:/App -p 127.0.0.1:5005:5005 nitincypher/docker-ubuntu-python-pip /App/server.py
[me@MacBook App]$ ./client.py
Client received data:
在 Linux 上
相比之下,在 Linux 上使用host 网络模式就很简单了。因为我使用我的 Linux 的 lo 接口作为我的容器 lo 接口。
[me@Linux App]$ docker run -v `pwd`:/App --net=host nitincypher/docker-ubuntu-python-pip /App/server.py
Server Connection address: ('127.0.0.1', 52172)
Server received data: Hello, World!
[me@Linux App]$ ./client.py
Client received data: Hello, World!
我的模拟服务器代码
要求:它必须绑定到localhost,仅此而已。所以我不能把它改成0.0.0.0。
#!/usr/bin/env python
import socket
TCP_IP = 'localhost'
TCP_PORT = 5005
BUFFER_SIZE = 20 # Normally 1024, but we want fast response
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP, TCP_PORT))
s.listen(1)
conn, addr = s.accept()
print 'Server Connection address:', addr
while 1:
data = conn.recv(BUFFER_SIZE)
if not data: break
print "Server received data:", data
conn.send(data) # echo
conn.close()
我的模拟客户端代码
要求:必须在 MacBook 上运行,因为真正的客户端是用 CPP 编写并编译为只能在 MacBook 上运行。
#!/usr/bin/env python
import socket
TCP_IP = 'localhost'
TCP_PORT = 5005
BUFFER_SIZE = 1024
MESSAGE = "Hello, World!"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
s.send(MESSAGE)
data = s.recv(BUFFER_SIZE)
s.close()
print "Client received data:", data
【问题讨论】:
-
大致来说,在 Docker 容器中运行的绑定 (2) 到
localhost的程序无法从任何地方访问(除了多进程容器中的其他进程,或某些 Kubernetes Pod 中的其他容器)。您可以要求 Docker 只允许来自localhost(-p 127.0.0.1:5005:5005) 的主机连接,但容器内的程序至少需要允许来自 Docker 桥的连接。
标签: macos docker docker-networking