Skip to main content
 首页 » 编程设计

python之是否可以从正在运行的 Docker 容器中发送 HTTP 请求

2025年01月19日35kerrycode

我有一个基本的分布式系统,可以计算 Github 存储库所有提交的平均圈复杂度。它由一个在 Flask 上运行的主节点组成,当一组工作节点向主节点发送 GET 请求时,该节点将 SHA ID 提供给这些节点。

我正在尝试使用 Docker 进行一些练习,并想将我的 Worker 代码放入一个 Docker 容器中,然后将该容器放在一组远程机器上,并让 Master 在我的本地机器上运行。我希望 Worker 和 Master 能够相互交流。

我不清楚该怎么做。我已经尝试告诉 Worker 节点将它们的请求发送到我的本地机器公共(public) IP 和 Flask 服务器运行的端口 (5000)。我已将远程机器的端口 5000 映射到 Docker 容器的端口 5000。这就是我在这里的知识范围。我将在下面附上一些相关的代码片段,而不是复制粘贴整个程序。

主要设置:

if __name__ == '__main__': 
    get_commits() 
    TOTAL_COMMITS = len(JOB_QUEUE) 
    app.run(host='0.0.0.0', port=5000, debug=False) 
    print('\n-----Shutting Down Server-----') 
    calc_avg_cc() 

工作人员 URL:

master_url = 'http://<my public ip>:5000/' 
node_setup_url = 'http://<my public ip>:5000/init' 

------------------------------------编辑-------- --------------------------

正如@odk 和@jonasheinisch 所说,这实际上是一个网络错误。我在大学网络上的远程机器上部署了我的 docker 容器。我启动了两个 AWS 实例,一个用于 Master 实例,一个用于 Worker 实例,嘿,它很快就起作用了。

我现在已经更新了设置,并将根据要求提供更多上下文。我仍然不确定的一件事是,我的 Worker 的请求是如何传递给我的 Master 的。我已将主机上的端口 80 映射到 Docker 容器上的端口 80,如下面的 Dockerfile 所示。我选择端口 80 作为一个猜测,因为我知道它与 HTTP 流量相关联。

docker 文件:

# Use an official Python runtime as a parent image 
FROM python:3.5-slim 
 
# Set the working directory to /worker 
WORKDIR /worker 
 
# Copy the current directory contents into the container at /app 
ADD worker.py requirements.txt github-token ./ 
 
# Install any needed packages specified in requirements.txt 
RUN pip install -r requirements.txt 
 
# Make port 80 available to the world outside this container 
EXPOSE 80 
 
# Run app.py when the container launches 
CMD ["python", "worker.py"] 

新 worker 设置:

master_url = 'http://<public IP of my AWS Master Instance>:5000/' 
node_setup_url = 'http://<public IP of my AWS Master Instance>:5000/init' 

Master 仍在监听端口 5000 上的所有接口(interface)。我的请求(从 Python 请求库发送)究竟如何在 Docker 容器之外到达互联网?

请您参考如下方法:

关于主要问题:正如您确认的那样,这是一个网络连接问题。结案。 关于您的编辑:由于工作人员是启动连接的人(至少根据您的描述),您不需要在这些容器上公开任何端口。 Docker 使用 iptables 为容器导出流量设置 NAT(您可以在 Linux 主机上以 root 身份使用 iptables -L 验证这一点)。它与您的家庭网络相同,您可能有一些小型路由器为您的家庭做 NAT。如果你想访问互联网上的任何网站,你不需要打开任何端口。仅当容器中的某些内容实际监听它并且应该接收入口流量时,您才需要公开端口。希望现在更清楚了。