所以我试图将Flask应用程序停靠,它执行以下操作:
我设法让它运行的唯一方法是在0.0.0.0 中创建Bokeh服务器并将容器的主机IP(我在Windows上)传递给地址Flask尝试从中获取它(请参阅autoload_server中的url字段)。但显然这对其他机器不起作用。
以下是相关的代码块:
server = Server({'/datavisualization': bokeh_app}, io_loop=io_loop, address="127.0.0.1",
allow_websocket_origin=["*"], host=["*"])
@app.route('/')
def bokeh_server():
# Fetch Running Bokeh Server
bokeh_embed = autoload_server(model=None,
app_path="/datavisualization",
url="http://127.0.0.1:5006")
html = render_template('index.html', bokeh_embed=Markup(bokeh_embed))
return html
if __name__ == '__main__':
from tornado.httpserver import HTTPServer
from tornado.wsgi import WSGIContainer
from bokeh.util.browser import view
# Serve the Flask app
http_server = HTTPServer(WSGIContainer(app))
http_server.listen(5000, address='0.0.0.0')
io_loop.add_callback(view, "http://0.0.0.0:5000/")
io_loop.start()
也许有更多Docker背景的人可以帮我理解这里发生了什么?我假设从容器的角度来看,在localhost上发布的任何内容都可以从同一容器中发布的其他服务中看到。
提前致谢
答案 0 :(得分:2)
根据我的评论,我将根据我怀疑的情况回答这个问题。
在我对Bokeh和autoload_server
(来自https://bokeh.pydata.org/en/latest/docs/user_guide/embed.html)的简短回顾中,看来这个函数实际上生成了一些JavaScript。它实际上并没有从Python或Flask本身连接到Bokeh服务器。连接来自浏览器。
根据这些信息,监听http://127.0.0.1:5006将不允许浏览器连接。即使容器在Windows或Mac上以--net=host
模式运行,也会使容器在Docker虚拟机网络而不是实际主机上进行监听,但仍会导致连接失败。
Bokeh服务器需要监听0.0.0.0,以便通过Docker NAT传输的任何IP都能够连接。此外,您需要告诉浏览器如何访问此容器。这意味着使用VM的IP地址或露出Docker容器端口的计算机的IP。
在生产设置中,您可能会在负载均衡器或其他反向代理后面运行Flask和Bokeh服务器端口,然后可以公开单个IP / DNS名称以连接到它们。然后,您将使用该DNS名称或IP作为url
参数。
答案 1 :(得分:1)
如果您在Linux计算机上运行此设置,则--net=host
将允许您的容器与主机的环回接口通信;该标志只是指定容器不应该使用自己的网络命名空间,而只是运行时可以访问所有主机的网络适配器。
但是,如果您在Windows或MacOS中运行Docker,--net=host
不起作用 - 这是因为当Docker客户端在Windows计算机上运行时,容器实际上是在docker上运行守护程序在一个单独的VM中。如果您运行localhost
并将Flask服务器指向-e BOKEH_IP=1.2.3.4
,那么您实际上是从docker VM访问本地主机,而不是运行Bokeh的Windows机器的本地主机。
当您需要处理多个容器相互交谈时,Docker中的网络可能会非常棘手。您正在处理的问题是如何在您的应用程序中发现服务。有几种方法可以解决这个问题:
最简单的可能是将你的Bokeh服务器的IP注入你的Flask应用程序作为配置;通常这是使用环境变量完成的,可以在运行带有$mydata = $data['device'][$id]['state']['1'];
标志的docker容器时传递。您可以在生产中配置不同的IP。
您还可以对Bokeh服务器进行容器化,然后使用Docker Compose,Docker Swarm或Kubernetes之类的东西来处理服务之间的通信。 Docker Compose可以在一台机器上运行,Docker Swarm非常适合在多台机器上轻松调度容器,而Kubernetes是一个更复杂,功能更全的选项,用于编排大量的交互服务。