【问题标题】:Docker DNS getaddrinfo ENOTFOUNDDocker DNS getaddrinfo ENOTFOUND
【发布时间】:2015-10-20 21:22:05
【问题描述】:

我正在使用 node:4.2.1-wheezydnsdock 容器运行 docker-compose。

我在 /etc/default/docker 中有 DOCKER_OPTS="--dns 172.17.42.1"

当我在 node.js 容器中运行 node -e "require('dns').resolve('host_name_here')" 时,主机通过 172.17.42.1 dns 服务器正确解析。

但是当我运行 node -e "require('dns').lookup('host_name_here')" 时,它会因 ENOTFOUND 错误而失败。

问题是http.request 使用dns.lookup 而不是dns.resolve

The docs say dns.lookup 调用 getaddrinfo。据我了解,getaddrinfo 缓存 /etc/resolv.conf 并且可能缓存空 /etc/resolv.conf (但cat /etc/resolv.conf 打印nameserver 172.17.42.1)。

我真的不知道如何解决这个问题。什么会导致这种行为?

更新 1。

docker -v
Docker version 1.7.1, build 786b29d

docker-compose -v
docker-compose version: 1.4.2

更新 2。

我已将所有内容更新到最新版本(docker 1.9.0、docker-compose 1.5.0 和 node 最高 5.0.0),但问题仍然存在。

所以这是重现问题的 docker-compose.yml:

dnsdock:
  image: tonistiigi/dnsdock
  volumes:
    - /var/run/docker.sock:/run/docker.sock
  ports:
    - "172.17.42.1:53:53/udp"
  environment:
    - DNSDOCK_ALIAS=dns.org
node:
  image: node:5.0.0-wheezy
  command: node -e "setTimeout(function () { var dns = require('dns'); dns.resolve('dns.org', console.log.bind(console, 'resolve')); dns.lookup('dns.org', console.log.bind(console, 'lookup')); }, 5000)"
  dns: 172.17.42.1

您应该将172.17.42.1 替换为您的 docker0 接口的 IP。 setTimeout(..., 5000) 是必需的,因为 node 容器可能在 dnsdock 之前启动。

这是我的docker-compose up 输出:

Creating test_node_1
Creating test_dnsdock_1
Attaching to test_node_1, test_dnsdock_1
dnsdock_1 | 2015/11/07 09:29:44 Added service: 3653951cff40c06c04b9ab3f5d2fc94ccc19305eaac7ba1a545ce1dbab3e3e17 {test_dnsdock_1 dnsdock 172.17.42.3 -1 [dns.org]}
dnsdock_1 | 2015/11/07 09:29:44 Added service: 36577feea136bc713f77b64b2a6a9712cd509c47ca55427f6749308cc5a4b140 {test_node_1 node 172.17.42.2 -1 []}
node_1    | resolve null [ '172.17.42.3' ]
node_1    | lookup { [Error: getaddrinfo ENOTFOUND dns.org]
node_1    |   code: 'ENOTFOUND',
node_1    |   errno: 'ENOTFOUND',
node_1    |   syscall: 'getaddrinfo',
node_1    |   hostname: 'dns.org' }
dnsdock_1 | 2015/11/07 09:29:49 Stopped service: 36577feea136bc713f77b64b2a6a9712cd509c47ca55427f6749308cc5a4b140
test_node_1 exited with code 0

【问题讨论】:

  • 你能分享一个 docker-compose.yml 来重现你的设置吗?
  • 还请考虑包含一个重现此内容的示例脚本。

标签: node.js dns docker


【解决方案1】:

为了更好的 dns 查找,您可以考虑使用网络覆盖,如“Docker Overlay Networks: That was Easy”中所述

它使用基于Consul 的 KV(键/值)存储,以及可以在其中注册节点的 swarm 集群。

你可以建立一个覆盖网络

eval "$(docker-machine env --swarm c0-master)"
docker network create -d overlay myStack1

并使用它来运行图像:

docker run -d --name web --net myStack1 nginx
docker run -itd --name shell1 --net myStack1 alpine /bin/sh

这两个容器都将连接到同一个网络,并且可以通过容器名称发现(无论启动顺序如何)。
此外,当容器重新启动时,它将保持可发现状态,而无需级联重新启动。

【讨论】:

  • 感谢您的回复!我的用例是同构应用程序。所以它在客户端和前端服务器上使用相同的 js。这是我来到的架构:nginx:在前端和后端服务器之间分发请求。 dnsdock:将app.comapi.app.com 解析为nginx。 前端:使用dnsdock通过api.app.com访问后端。我应该如何使用 docker 网络来实现它?我应该摆脱 nginx 和 dnsdock 并将后端容器名称设置为api.app.com 吗?如果我决定使用app.com/api 而不是api.app.com 会怎样?
  • @AliakseiTuzik nginx 似乎是个好主意。在我的回答中,dnsdock 将被 consul 取代。
猜你喜欢
  • 2018-05-24
  • 2013-07-15
  • 2017-10-16
  • 2022-06-23
  • 1970-01-01
  • 1970-01-01
  • 2018-03-03
  • 2019-03-14
  • 1970-01-01
相关资源
最近更新 更多