请注意,这与How to expose a service running inside a docker container, bound to localhost不同,--net host
可以通过多种方式在Docker for Linux中解决,例如通过-v
甚至localhost:5005
来绑定我的Linux风格客户端等等。我的问题特定于Docker for Mac,所以它不是那么简单。
我有一个TCP服务器绑定到在Docker for Mac中运行的0.0.0.0:5005
。 (出于安全原因,我不能绑定到--net=host
。)
我有一个TCP客户端从我的Mac(不在docker容器内)向此服务器发送请求。
我的问题是,我该如何使其发挥作用?
在Linux Docker中,我只是使用lo
,因此服务器绑定到我的主机host
接口,但似乎Docker for Mac在托管VM上运行,因此[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:
网络行为是不同的行为。
为了说明我的观点:
在MacBook上
它根本行不通
host
在Linux上
相比之下,使用lo
网络模式在Linux上做起来是微不足道的。因为我使用我的Linux的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()
。
#!/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
我的模拟客户端代码
要求:它必须在MacBook上运行,因为真正的客户端是用CPP编写的,并且编译为仅在MacBook上运行。
ubuntu
这是一个有效的解决方案。基本思想是使用SSH隧道进行端口转发。
sshd
图像没有开箱即用的root
,也是
您需要知道正在运行的容器的SSH tunneling的密码。作为参考,可以在这里找到explained here的命令,创建sshd docker镜像的过程是explained here,以及如何ssh到docker容器是Dockerfile
#Use whatever image you are using on Docker Linux , say "FROM ubuntu:16.04"
FROM nitincypher/docker-ubuntu-python-pip
RUN apt-get update && apt-get install -y openssh-server
RUN mkdir /var/run/sshd
RUN echo 'root:screencast' | chpasswd
RUN sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
# SSH login fix. Otherwise user is kicked off after login
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd
ENV NOTVISIBLE "in users profile"
RUN echo "export VISIBLE=now" >> /etc/profile
EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]
[me@MacBook App]$ docker build -t my_ssh_python .
[me@MacBook App]$ docker run -d -P -v `pwd`:/App --name myserver my_ssh_python
[me@MacBook App]$ docker exec myserver /App/server.py
[me@MacBook App]$ ssh root@`hostname` -p `docker port myserver 22 | awk -F ":" '{print $2}'` -L 8000:localhost:8000 -N
#Password is "screencast" as you built in Dockerfile
ssh
注意
一个。您必须使用MacBook的IP地址而不是Docker容器的IP地址。
湾您将在主机上使用默认容器22
port -L 8000:localhost:8000
映射到的端口
C。在隧道8000
,你是说在你的MacBook localhost
(第一个8000)到Docker容器的8000
端口[me@MacBook App]$ ./client.py
Client received data: Hello, World!
的任何东西Server Connection address: ('127.0.0.1', 55396)
Server received data: Hello, World!
在服务器端,你可以看到
qazxswpoi