问题:(简短版本)
使用 Docker 进行应用程序开发时,如何配置 Docker-compose 文件以允许我从 docker 容器内部访问主机网络上服务器的 IP 地址?我不想访问主机本身,而是想访问与主机位于同一网络上的另一台服务器。我还需要让各种 Docker 容器能够相互通信。
允许从 docker 容器内部访问主机网络 IPv4 资源并仍然允许容器间通信的最简洁方法是什么?
所有背景和详细信息如下(又称长版本)。
Setup:
我正在编写一个应用程序,该应用程序轮询 Modbus 服务器以按给定时间间隔收集测量数据。 Modbus 服务器位于我的本地网络上的 192.168.1.50 端口 502。我可以从我的计算机成功 ping 该服务器。
我的开发思路是这样的:
- 应用程序位于 docker 容器内
- Mac环境下开发
- 使用 Django-3.1/postgres 构建 UI 并存储数据(目前)
- 使用 pymodbus 库来管理应用程序和远程 Modbus 服务器之间的通信
这是创建应用程序环境的 Docker-compose 文件:
version: '3.8'
services:
db:
container_name: db
image: postgres:10.7
environment:
POSTGRES_PASSWORD: pwd
POSTGRES_DB: app_db
volumes:
- ./data/postgres:/var/lib/postgresql/data
ports:
- 5432:5432
web:
container_name: web
build:
context: ../.
dockerfile: ./_app/dev/Dockerfile
volumes:
- ../.:/app
ports:
- 8000:8000
depends_on:
- db
env_file:
- app.env
command: ./manage.py runserver 0.0.0.0:8000
这是 Dockerfile:
FROM python:3.8.5-buster
RUN mkdir /app
WORKDIR /app
RUN apt-get update -y
RUN apt-get install inetutils-traceroute -y
COPY ./_app/dev/python_reqs.txt /app/python_reqs.txt
RUN pip install --upgrade pip
RUN pip install -r python_reqs.txt
# Install wait-for-it
COPY ./_app/wait-for-it.sh /usr/local/bin/
RUN chmod u+x /usr/local/bin/wait-for-it.sh
# Configure custom entrypoint to wait for postgres and run webserver
COPY ./_app/dev/custom-entrypoint /usr/local/bin/
RUN chmod u+x /usr/local/bin/custom-entrypoint
ENTRYPOINT ["custom-entrypoint"]
EXPOSE 8000
Problem:
从“web”docker 容器内部,我无法访问主机 LAN 上的 Modbus 服务器。我无法 ping 通其 IP 地址 (192.168.1.50)。
traceroute 192.168.1.50
没有提供任何有用的信息。它只是失败了。
当我跑步时docker-compose up
创建一个名为“_app_default”的 docker 网络。这是我跑步时得到的结果docker network inspect _app_default
:
[
{
"Name": "_app_default",
"Id": "59f0836c2f3017c537f973a38ab3a55ad96e2ed737c4ac111fc0e911fa0c8a67",
"Created": "2020-09-13T18:51:14.6395366Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "192.168.112.0/20",
"Gateway": "192.168.112.1"
}
]
},
"Internal": false,
"Attachable": true,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"28af77ef2d6f99812cb392c8f9eca045b150256c464befc3bb249c9de9e653c1": {
"Name": "db",
"EndpointID": "d657f2f29699ada859447c919ad2c94195a6e9a7ae7eeb35989560d2717183c5",
"MacAddress": "02:42:c0:a8:70:02",
"IPv4Address": "192.168.112.2/20",
"IPv6Address": ""
},
"a8a619d664a27286e276614e549514dff2c15c5c3c44c39e127fec54ec2b5c6b": {
"Name": "web",
"EndpointID": "8f1661c6fa24104a70171d1f830e1fe34ed8d89bacd55c9b9d05dc62f64112c0",
"MacAddress": "02:42:c0:a8:70:03",
"IPv4Address": "192.168.112.3/20",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {
"com.docker.compose.network": "default",
"com.docker.compose.project": "_app",
"com.docker.compose.version": "1.27.0"
}
}
]
我已经尝试过的:
我尝试使用network_mode: "host"
在“网络”服务定义中。那没有帮助。
我尽了最大努力通读了 Docker 网络文档,但我找不到针对这种情况的直接解决方案,所以我完全转过来了——不幸的是,我不擅长网络主题——但是:)。我需要“覆盖”网络吗?还是“macvlan”?帮助!
如果 StackOverflow 超级明星能够提供任何帮助,我们将不胜感激。谢谢你!!
-Allan