繁体   English   中英

如何从Mac到达docker容器`localhost`?

[英]How to reach docker container `localhost` from Mac?

请注意,这与如何公开在docker容器中运行的绑定到localhost的服务不同 ,可以在Docker for Linux中以多种方式解决,例如通过--net host或者甚至-v绑定我的Linux-flavor客户端我的问题是特定于Docker for Mac,所以它不是那么简单。

我有一个TCP服务器绑定到localhost:5005在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上

相比之下,使用host网络模式在Linux上进行操作将是微不足道的。 因为我使用我的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

这是一个有效的解决方案。 基本思想是使用SSH隧道进行端口转发。

高层次的想法

  • 首先需要构建一个docker镜像来支持SSH访问,因为
    1. ubuntu图像没有开箱即用的sshd ,也是
    2. 您需要知道正在运行的容器的root密码。
  • 然后,您将按照通常的方式旋转容器,除非您根据创建的新图像执行此操作。
  • 您可以从MacBook创建SSH隧道会话,然后像往常一样在MacBook上运行客户端。

作为参考,该命令SSH隧道可以找到这里,创建的sshd搬运工图像的处理说明如下 ,以及如何ssh到搬运工容器这里解释

脚步

  1. 创建一个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"] 
  2. 从Dockerfile创建Docker镜像

     [me@MacBook App]$ docker build -t my_ssh_python . 
  3. 旋转您的服务器容器

     [me@MacBook App]$ docker run -d -P -v `pwd`:/App --name myserver my_ssh_python 
  4. 在容器内启动服务器

     [me@MacBook App]$ docker exec myserver /App/server.py 
  5. 创建SSH隧道

     [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 

    注意

    一个。 您必须使用MacBook的IP地址而不是Docker容器的IP地址。

    您将使用默认容器ssh端口22映射到主机上的端口

    C。 在隧道-L 8000:localhost:8000 ,你要说的是从MacBook 8000 (第一个8000)到端口8000 Docker容器的localhost转发任何东西

  6. 现在您可以在本地使用客户端

     [me@MacBook App]$ ./client.py Client received data: Hello, World! 

    在服务器端,你可以看到

     Server Connection address: ('127.0.0.1', 55396) Server received data: Hello, World! 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM