Docker DNS getaddrinfo ENOTFOUND

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

我在/ etc / default / DOCKER_OPTS="--dns 172.17.42.1"里面有DOCKER_OPTS="--dns 172.17.42.1"

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

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

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

文档说 dns.lookup调用getaddrinfo 。 据我了解getaddrinfocaching/etc/resolv.conf,也许它caching空/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。

我更新了所有的东西到最新版本(docker1.9.0,docker组成1.5.0和节点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 

您应该用您的docker0接口的IPreplace172.17.42.1setTimeout(..., 5000)是必需的,因为node容器可能在dnsdock之前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 

为了更好地查找dns,可以考虑使用networking覆盖,如“ Docker覆盖networking:很简单 ”

它使用基于Consul的KV(Key / Value)存储,以及一个可以注册节点的群集。

你可以build立一个覆盖networking

 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 

这两个容器都将连接到同一个networking,并且可以通过容器名称(不pipe启动顺序)来发现。
此外,当一个容器重新启动时,它将保持可发现的级联重启。