如何在 Docker-Compose 中一起使用主机网络和任何其他用户定义的网络?

Posted

技术标签:

【中文标题】如何在 Docker-Compose 中一起使用主机网络和任何其他用户定义的网络?【英文标题】:How to use the host network, and any other user-defined network together in Docker-Compose? 【发布时间】:2018-04-28 10:13:47 【问题描述】:

我想将定义在 Docker-Compose 文件中的两个 Docker 容器相互连接(appdb)。其中之一(app)也应该连接到host 网络。

容器应连接到通用的用户定义网络(appnetdefault)以使用 docker 网络中的嵌入式 DNS 功能。

app还需要直接连接到主机网络,才能在docker主机的物理网络中接收以太网广播(网络二层)。

在组合中同时使用network_mode: hostnetworks 两个指令,会导致以下错误:

ERROR: 'network_mode' and 'networks' cannot be combined

在服务中指定网络名称host而不在网络中定义它(因为它已经存在),结果:

ERROR: Service "app" uses an undefined network "host"

下一次尝试:明确定义两个网络,不要在服务级别使用network_mode: host 属性。

version: '3'
services:

  app:
    build: .
    image: app
    container_name: app
    environment:
      - MONGODB_HOST=db
    depends_on:
      - db
    networks:
      - appnet
      - hostnet

  db:
    image: 'mongo:latest'
    container_name: db
    networks:
      - appnet

networks:
  appnet: null
  hostnet:
    external:
      name: host

上述撰写文件产生错误:

ERROR: for app network-scoped alias is supported only for containers in user defined networks

如何在 Docker-Compose 中同时使用host 网络和任何其他用户定义的网络(或默认网络)?

【问题讨论】:

【参考方案1】:

TL;DR 你不能。主机网络关闭该容器的 docker 网络命名空间。你不能同时打开和关闭它。

相反,请使用已发布的端口或可作为卷共享的 unix 套接字连接到您的数据库。例如。以下是发布端口的方法:

version: "3.3"

services:

  app:
    build: .
    image: app
    container_name: app
    environment:
      - MONGODB_HOST=127.0.0.1

  db:
    image: mongo:latest
    container_name: db
    ports:
      - 127.0.0.1:27017:27017

【讨论】:

这是一个很棒的答案,但主要被忽视了。发布的端口提供了两全其美的优势,在 localhost 和私有网络上具有可观察性,容器服务可以通过容器名称相互解析。不幸的现实是,您无法将数据包从主机操作系统路由到 Docker for Mac,但您可以使用已发布的端口将容器相互连接并连接到主机操作系统。【参考方案2】:

要使用主机网络,您不需要定义它。只需使用“ports”关键字来定义要在主机网络中公开的服务端口。

【讨论】:

app 需要 OSI 第 2 层访问主机网络。我不是要求 UDP/TCP 端口绑定。 对不起,我的错。我确实在最新的 docker for windows 上重现了它——同样的问题。非常相似的问题在 moby github - github.com/moby/moby/issues/32957 - 似乎这是一个更大问题的一部分 是的,我认为将多容器应用程序与 docker compose 和 host-networking 一起使用的唯一方法是,将 host-network 用于 compose 文件中的所有容器。至少对于 2018 年 1 月的当前版本的 Docker Compose。 这个答案帮助了我,我从必须使用它的容器中删除了桥接网络,为此容器使用了 ports 指令以及与其他容器相关的内部网络,还使用了 expose对于那些其他容器 - 它就像一个魅力【参考方案3】:

由于 Docker 18.03+ 可以使用host.docker.internal 从容器内访问您的主机。无需添加host 网络或与用户定义的网络混合使用。

来源:Docker Tip #65: Get Your Docker Host's IP Address from in a Container

【讨论】:

仅在 Windows 和 macOS 上,在 Linux 上这目前取决于 github.com/docker/for-linux/issues/264 现在 Linux 也实现了这一点。

以上是关于如何在 Docker-Compose 中一起使用主机网络和任何其他用户定义的网络?的主要内容,如果未能解决你的问题,请参考以下文章

将 docker-compose 与多个存储库一起使用

将 nodemon 与 docker 和 docker-compose 一起使用

Docker-Compose

gcloud docker-compose deploy 主容器(子项目的解决方案)

Docker:docker-compose 应用

使用 docker-compose 快速安装Jenkins