2015-10-20 96 views
6

我正在運行碼頭 - 與node:4.2.1-wheezydnsdock容器組成。Docker DNS getaddrinfo ENOTFOUND

我在/ 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 that dns.lookup calls 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

我所有的東西更新到最新版本(1.9.0碼頭工人,碼頭工人,組成1.5.0和節點高達5.0 .0)但問題仍然存在。

所以這是搬運工,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接口的IP取代172.17.42.1。需要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 
+0

你可以分享一個碼頭 - 撰寫。yml重現你的設置? –

+0

也請考慮包含一個可以重現這一點的示例腳本。 –

回答

2

爲了更好的DNS查找,你可以考慮使用一個網絡覆蓋,如 「Docker Overlay Networks: That was Easy

它採用了KV呈現(鍵/值)在Consul上存儲基礎,以及一個羣集羣,您可以在其中註冊節點。

您可以構建一個覆蓋網絡

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 

這兩個容器將被連接到同一個網絡,並發現按容器名稱(不管起始順序)。
此外,當容器重新啓動時,它將保持可發現的級聯重啓狀態。

+0

感謝您的回覆! 我的用例是同構的應用程序。所以它在客戶端和前端服務器上使用相同的js。 這是我來到的體系結構: ** nginx **:在前端服務器和後端服務器之間分配請求。 ** dnsdock **:將'app.com'和'api.app.com'解析爲nginx。 **前端**:使用dnsdock通過'api.app.com'訪問後端。 我應該如何使用碼頭網絡來實現它?我應該擺脫nginx和dnsdock並將後端容器名稱設置爲'api.app.com'嗎?如果我決定使用'app.com/api'而不是'api.app.com'呢? –

+0

@AliakseiTuzik nginx似乎是一個好主意。在我的回答中,dnsdock將被領事取代。 – VonC