简体   繁体   English

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

[英]Is it possible to send HTTP requests from inside a running Docker container

I have a basic distributed system that calculates the average cyclomatic complexity across all commits of a Github repo.我有一个基本的分布式系统,可以计算 Github 存储库所有提交的平均圈复杂度。 It consists of a Master node running on Flask that gives SHA ID's to a set of Worker nodes when they send a GET request to the Master.它由一个运行在 Flask 上的 Master 节点组成,当一组 Worker 节点向 Master 发送 GET 请求时,它会向一组 Worker 节点提供 SHA ID。

I was trying to get some practice with Docker, and wanted to put my Worker code in a Docker container, then put that container on a set of remote machines and have the Master run on my local machine.我正在尝试使用 Docker 进行一些练习,并想将我的 Worker 代码放在 Docker 容器中,然后将该容器放在一组远程机器上,并让 Master 在我的本地机器上运行。 I wanted the Workers and Master to be able to communicate with one another.我希望 Worker 和 Master 能够相互交流。

I'm not clear on how to go about doing this.我不清楚如何去做这件事。 I have tried telling the Worker nodes to send their requests to my local machines public IP and the port that the Flask server is running on (5000).我已经尝试告诉 Worker 节点将他们的请求发送到我的本地机器公共 IP 和 Flask 服务器运行的端口 (5000)。 I have mapped the port 5000 of the remote machine to port 5000 of the Docker container.我已经将远程机器的 5000 端口映射到 Docker 容器的 5000 端口。 That is about the extent of my knowledge here.这就是我在这里的知识范围。 I'll attach some relevant code snippets below, without copy pasting the entire program.我将在下面附上一些相关的代码片段,而不是复制粘贴整个程序。

Master setup:主设置:

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()

Worker URLS:工人网址:

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

-------------------------------------Edit--------------------------------- - - - - - - - - - - - - - - - - - - -编辑 - - - - - - ---------------------

As @odk and @jonasheinisch suggested, it was in fact a network error.正如@odk 和@jonasheinisch 所建议的,这实际上是一个网络错误。 I was deploying my docker container on a remote machine that was on my university network.我正在大学网络上的远程机器上部署我的 docker 容器。 I spun up two AWS instances, one for Master and one for Worker's and hey presto it worked.我启动了两个 AWS 实例,一个用于 Master,一个用于 Worker,嘿,它很快就起作用了。

I've updated the setup now, and will provide a bit more context as requested.我现在已经更新了设置,并将根据要求提供更多的上下文。 One thing that I am still unsure of is exactly how my requests from my Worker are making it to my Master.我仍然不确定的一件事是我从我的工人那里提出的要求究竟是如何向我的主人提出的。 I have mapped port 80 on the host to port 80 on the Docker container, as shown in my Dockerfile below.我已将主机上的端口 80 映射到 Docker 容器上的端口 80,如下面的 Dockerfile 所示。 I chose port 80 as a bit of a guess, because I know that it is associated with HTTP traffic.我选择了端口 80 作为一个猜测,因为我知道它与 HTTP 流量相关联。

Dockerfile: 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"]

New Worker setup:新工人设置:

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 is still listening on all interfaces on port 5000. How exactly do my requests (sent from the Python request library) make it outside the Docker container to the Internet? Master 仍然在侦听端口 5000 上的所有接口。我的请求(从 Python 请求库发送)究竟是如何使其在 Docker 容器之外到达 Internet 的?

About main problem: As you confirmed it was a network connectivity issue.关于主要问题:正如您确认的那样,这是一个网络连接问题。 Case closed.案件结案。 About your edit: As the workers are the ones that initiate the connection (at least from your description) you don't need to expose any port on those containers.关于您的编辑:由于工作人员是发起连接的人(至少根据您的描述),您不需要在这些容器上公开任何端口。 Docker sets up NAT using iptables for container egress traffic (you can verify this on Linux host using iptables -L as root). Docker 使用 iptables 为容器出口流量设置 NAT(您可以使用iptables -L作为 root 在 Linux 主机上验证这一点)。 It's same as in your home network, you probably have some small router that does NAT for your home.这与在您的家庭网络中相同,您可能有一些小型路由器为您的家庭执行 NAT。 And you don't need to open any ports if you want to access any site on internet.如果您想访问互联网上的任何站点,则无需打开任何端口。 You need to expose ports only when something in your container actually listens on it and should receive ingress traffic.仅当容器中的某些内容实际侦听它并且应该接收入口流量时,才需要公开端口。 Hope this is more clear now.希望现在更清楚了。

Yes.是的。 You could make a docker swarm containing your local machine and the remote machines, then deploy your workers and master as services in the same docker network.您可以制作一个包含本地机器和远程机器的 docker swarm,然后将您的 worker 和 master 作为服务部署在同一个 docker 网络中。 See https://docs.docker.com/engine/swarm .请参阅https://docs.docker.com/engine/swarm

To target specific machines on the swarm, you need to label them and use the labels as placement constraints (see https://docs.docker.com/engine/swarm/services/#placement-constraints ‌​).要定位 swarm 上的特定机器,您需要标记它们并将标签用作放置约束(请参阅https://docs.docker.com/engine/swarm/services/#placement-constraints ‌ )。

尝试使用您的服务名称而不是您的 ip,它应该会有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM