【问题标题】:Error connecting to python server running in boot2docker (centos container | Windows 7.1 host)连接到在 boot2docker 中运行的 python 服务器时出错(centos 容器 | Windows 7.1 主机)
【发布时间】:2015-01-07 07:27:31
【问题描述】:

我的用例
我们需要在无头模式下运行 watir-webdriver 脚本,并且我们的开发机器运行 Windows。

我们问题的要点

我可以在容器内建立 python 服务器,但我无法从主机连接到它的预期位置:http://192.168.59.103:8084.

架构

一个“做一些有用的事情并将输出打印到控制台”的 ruby​​ 脚本和一个基本的 python 服务器,它导入 os 然后在我们的索引路由中执行 os.system('ruby ourrubyscript.rb')。我们还引入了用于 api 路由和 flask.cors 的烧瓶,以消除潜在的跨源问题。

本地测试(在主机上)

在我们的主机工作区中运行“python server.py”会在端口 5000 上建立一个 python 服务器。从浏览器路由到它会执行我们的路由并将预期的输出打印到控制台。

server.py

from flask import Flask
from flask import request
from flask.ext.cors import CORS

import os

app = Flask(__name__)
CORS(app, resources={r'/': {"origins": "*"}}, headers='Content-Type')
app.config['CORS_HEADERS'] = 'Content-Type'

@app.route('/')
def index():
    return "<h1>Hello Stupid</h1>"

@app.route('/ruby/test', methods=['GET'])
def runRubyScript():
    return os.system("ruby script.rb")

if __name__ == "__main__":
    app.run()

当我导航到 localhost:5000 时,“Hello Stupid”会打印到我的屏幕上。
当我路由到 localhost:5000/ruby/test 时,我们的脚本运行并且该脚本打印到我的控制台。


将其移至 docker 的过程

我们提取了最新的 centos 并安装了 wget、xvfb、git、ruby、python、pip、flask、flask-cors 和 firefox;将其提交给名为“webdev”的本地图像。 然后 gem 安装 headless 并将 phantomjs 安装到 $PATH 然后,我们将 src 存储库克隆到容器中的“/opt/testapp”。这个存储库包含我们的“server.py”文件和一个“script.rb”文件。

docker@boot2docker:~$ docker run -d -p 5000:5000 --name wd webdev python /opt/testapp/server.py

所以,我将 boot2docker-vm 绑定到私有 ip 192.168.59.103,我可以通过导航到运行不同容器的不同端口来确认此 ip 有效;但是,当我导航到 5000 时,我得到一个 ERR_CONNECTION_REFUSED。我几乎“啊哈!!”有一刻认为 iptables 默认锁定了端口,我们需要打开内部端口 5000 以便将其映射到虚拟机,但后来我发现 centos 映像没有安装 iptables(或 firewalld,因为这是 CentOS7)默认。当这种方法被证明不正确时,我决定发帖看看是否有人可以在这里提供帮助,因为我没有想法。

【问题讨论】:

    标签: python centos docker boot2docker centos7


    【解决方案1】:

    所以我已经弄清楚了为什么它不暴露在主机环境中,这很有意义。

    在 NAT 模式下,虚拟机被分配一个私有静态 IP 地址:192.168.59.103(即...虚拟机被分配该 IP)

    每个容器都有 2 个适配器:一个环回和一个面向外部的虚拟专用网桥,可供 vm 访问。

    当我在端口 5000 上启动我的服务器时,它直接绑定到容器内的环回,并且虚拟机无法访问。

    从服务中移除 localhost 绑定并允许它 绑定默认网关0.0.0.0:5000

    使服务侦听所有适配器并允许通信 在 vm 和容器的外部适配器之间通过 容器站立时创建的虚拟私有网桥。

    由于某种原因,将我的虚拟机切换到针对我的 NIC 以桥接模式运行会导致 boot2docker-vm 在启动时崩溃......所以我暂时被降级为 NAT,直到我弄清楚如何正确切换。

    [编辑1(与桥接有关)]

    至少从 2014 年 10 月 8 日起,boot2docker 似乎不支持桥接模式。b2d 需要一个用于 ssh 引导的 NAT 适配器和一个用于容器容器套接字访问的主机适配器。

    将容器暴露给网络上的主机的当前不受支持、未记录的解决方法是将第三个网络接口添加到 VirtualBox 并与之桥接。


    [编辑 2(针对默认网关运行的示例服务器)]

    这是一个附加到所有接口的烧瓶服务器示例: 注意上面服务器和下面服务器之间唯一的Δ是配置的最后一行。

    app.run() 需要成为 app.run(host='0.0.0.0')

    from flask import Flask
    from flask import request
    from flask.ext.cors import CORS
    
    import os
    
    app = Flask(__name__)
    CORS(app, resources={r'/': {"origins": "*"}}, headers='Content-Type')
    app.config['CORS_HEADERS'] = 'Content-Type'
    
    @app.route('/')
    def index():
        return "<h1>Hello Stupid</h1>"
    
    @app.route('/ruby/test', methods=['GET'])
    def runRubyScript():
        return os.system("ruby script.rb")
    
    if __name__ == "__main__":
        app.run(host='0.0.0.0')
    

    【讨论】:

    • 你让我开心!我花了几个小时试图弄清楚为什么我无法从主机连接到我的服务器。我不敢相信一点点补充就解决了我的 Windows Host + Docker + Flask 问题。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-19
    • 2021-08-07
    • 1970-01-01
    • 1970-01-01
    • 2020-11-26
    • 2020-02-05
    • 2019-11-27
    相关资源
    最近更新 更多