是否可以从正在运行的 Docker 容器内部发送 HTTP 请求

Jac*_*idy 5 python flask docker

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

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

我不清楚如何去做。我已经尝试告诉 Worker 节点将他们的请求发送到我的本地机器公共 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()
Run Code Online (Sandbox Code Playgroud)

工人网址:

master_url = 'http://<my public ip>:5000/'
node_setup_url = 'http://<my public ip>:5000/init'
Run Code Online (Sandbox Code Playgroud)

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

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

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

Dockerfile:

# 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"]
Run Code Online (Sandbox Code Playgroud)

新工人设置:

master_url = 'http://<public IP of my AWS Master Instance>:5000/'
node_setup_url = 'http://<public IP of my AWS Master Instance>:5000/init'
Run Code Online (Sandbox Code Playgroud)

Master 仍然在侦听端口 5000 上的所有接口。我的请求(从 Python 请求库发送)究竟是如何使其在 Docker 容器之外到达 Internet 的?

小智 4

关于主要问题:正如您所确认的,这是一个网络连接问题。案件结案。关于您的编辑:由于工作人员是发起连接的人(至少从您的描述来看),您不需要公开这些容器上的任何端口。Docker 使用 iptables 为容器出口流量设置 NAT(您可以使用以下命令在 Linux 主机上验证这一点)iptables -Lroot 身份在 Linux 主机上验证这一点)。这与您的家庭网络相同,您可能有一些小型路由器为您的家庭执行 NAT。如果您想访问互联网上的任何站点,则无需打开任何端口。仅当容器中的某些内容实际侦听端口并且应该接收入口流量时,您才需要公开端口。希望现在更清楚了。