我有两个 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,以避免冲突。