从Docker容器内部连接到主机网络上的IP地址

时间:2020-09-13 19:21:44

标签: docker networking docker-compose

问题:(简称)

在使用Docker进行应用程序开发时,如何配置Docker-compose文件以允许我从docker容器内部访问主机网络上服务器的IP地址?我不想访问主机本身,而是想访问与主机位于同一网络上的另一台服务器。我还需要使各种Docker容器能够相互通信。

允许从Docker容器内部访问主机网络IPv4资源并且仍然允许容器间通信的最干净方法是什么?

所有背景和详细信息都在下面(又名长版)。


设置:

我正在编写一个应用程序,该应用程序以给定的时间间隔轮询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

问题:

在“ web”泊坞窗容器内部,我无法访问主机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超级巨星可以发送的任何帮助将不胜感激。谢谢!!

-艾伦

1 个答案:

答案 0 :(得分:1)

似乎您的docker网络和本地网络的IP范围重叠。 要解决此问题,您需要覆盖docker网络地址池,例如

编辑docker守护进程配置

$ cat ~/.docker/daemon.json
{
  "debug" : true,
  "default-address-pools" : [
    {
      "base" : "172.31.0.0/16",
      "size" : 24
    }
  ]
}