1

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

我们的问题的要点

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

架构

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

本地测试(在主机上)

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

服务器.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 以便将其映射到 vm,但后来我发现 centos 映像没有安装 iptables(或 firewalld,因为这是 CentOS7)默认。当这种方法被证明不正确时,我决定发帖看看是否有人可以在这里提供帮助,因为我没有想法。

4

1 回答 1

2

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

在 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')
于 2014-11-11T17:47:56.800 回答