使用 network=host 进行容器主机名解析

使用 network=host 进行容器主机名解析

我有两个 docker 容器。一个是“后端”,另一个是“连接器”。

连接器需要将其网络类型设置为“主机”(接收 udp 多播:ssdp/mdns 数据包)。

但它还需要能够使用 docker dns 系统,这样我就可以把容器名称解析为它们的 ip 地址。

我怎样才能做到这一点?

docker-compose.yml

version: "3"
services:

  database:
    image: mongo
    container_name: database
    hostname: database
    ports:
      - "27017:27017"

  backend:
    image: "project/backend:latest"
    container_name: backend
    hostname: backend
    environment:
      - NODE_ENV=production
      - DATABASE_HOST=database
    ports:
      - "8080:8080"
    depends_on:
      - database
    tty: true

  connector:
    image: "project/connector:latest"
    container_name: connector
    hostname: connector
    ports:
      - "1900:1900/udp"
    environment:
      - NODE_ENV=production
      - BACKEND_HOST=backend
    depends_on:
      - backend
    network_mode: host
    tty: true

当我用它运行它时docker compose up,我的连接器容器抛出“EAI_AGAIN”错误:

connector  | Error: getaddrinfo EAI_AGAIN backend
connector  |     at GetAddrInfoReqWrap.onlookup [as oncomplete] (node:dns:109:26) {
connector  |   errno: -3001,
connector  |   code: 'EAI_AGAIN',
connector  |   syscall: 'getaddrinfo',
connector  |   hostname: 'backend'
connector  | }

这意味着 node.js 应用程序无法解析主机名“backend”。这并不奇怪,因为网络设置为“host”。

如何让“连接器”容器将其网络设置为“主机”但仍能够解析其他容器名称?

答案1

Docker macvlan 在您选择的主机网络接口上设置软件交换机(网桥)。这可以是与主机相同的接口,也可以是具有不同网络的不同接口或子接口。

将容器分配到此 macvlan docker 网络将为容器创建一个唯一的第 2 层地址,并允许它使用在 macvlan 父接口上具有路由的任何第 3 层 ip 地址。这还将为您的容器提供主机网络功能,即 mdns 网络发现。

分配给 macvlan 网络的容器可以同时分配给 Compose 文件中的其他 docker 网络,并与 docker 网络内的其他容器进行通信。macvlan 接口仅用作其余堆栈正在使用的任何数据的入口。

这样做的缺点和注意事项:

  • Macvlan 配置需要指向一个物理命名接口。它还需要连接到您要将其桥接到的实际第 2 层网络。将 macvlan 引入到您的 docker 环境中会降低其可移植性。

  • macvlan 接口没有适当的方法参与 DHCP。可以为 Docker 指定一个范围,以自动将容器分配给 macvlan 网络,或者您可以为每个容器单独分配一个静态 IP。请务必从 DHCP 范围中删除这些 IP,以避免冲突。

相关内容