docker.io DNS ไม่ทำงานพยายามใช้ 8.8.8.8


33

ฉันติดตั้ง Ubuntu 14.04 ใหม่และต้องการใช้ Docker เพื่อเรียกใช้เนื้อหาเก่าที่ต้องการ 12.04 DNS ภายใน Docker ไม่ทำงาน

resolv.conf ของแล็ปท็อปของฉันดูเหมือนว่า:

nameserver 127.0.0.1

ซึ่งใช้ไม่ได้กับ Docker ดังนั้นจึงพยายามตั้งค่าเนมเซิร์ฟเวอร์ให้เป็น 8.8.8.8 และ 8.8.4.4 เมื่อฉันทำ

$ sudo docker run -i -t ubuntu /bin/bash

มันบอกว่า:

WARNING: Local (127.0.0.1) DNS resolver found in resolv.conf and containers can't use it. Using default external servers : [8.8.8.8 8.8.4.4]

และภายในพอร์ทอินสแตนเดอร์ resolv.conf ดูเหมือนว่า:

nameserver 8.8.8.8
nameserver 8.8.4.4

ฉันสามารถ ping ทั้งสองอย่างสำเร็จจากภายในอินสแตนซ์ Docker อย่างไรก็ตามไม่มี DNS (เช่นping google.comล้มเหลว)

เอาท์พุท ifconfig ภายใน Docker:

eth0      Link encap:Ethernet  HWaddr aa:e9:9f:83:9d:92  
          inet addr:172.17.0.2  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::a8e9:9fff:fe83:9d92/64 Scope:Link
          UP BROADCAST RUNNING  MTU:1500  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:9 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:648 (648.0 B)  TX bytes:738 (738.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

ตอนนี้คืออะไร

คำตอบ:


23

เมื่อแพ็คเกจ Ubuntu Docker ได้รับการอัปเดตเป็นใช้ systemd มันได้รับการสนับสนุนสำหรับ/etc/default/dockerไฟล์กำหนดค่าดังนั้นโซลูชันเริ่มต้นที่แนะนำโดย rocketman10404จะไม่ทำงานอีกต่อไป (การปิดใช้งานdnsmasqจะยังคงทำงานได้ แต่มีข้อเสียในการป้องกัน .

แก้ไขในdaemon.jsonไฟล์กำหนดค่าใหม่

ค้นหาเซิร์ฟเวอร์ DNS ของเครือข่ายของคุณ:

$ nmcli dev show | grep 'IP4.DNS'
IP4.DNS[1]:                             10.0.0.2

เปิดหรือสร้างหากไม่มีอยู่/etc/docker/daemon.jsonและเพิ่มการตั้งค่า DNS ในExecStartบรรทัด:

# /etc/docker/daemon.json
{
    "dns": ["10.0.0.2", "8.8.8.8"]
}

รีสตาร์ท docker daemon:

$ sudo service docker restart

ฉันเขียนโพสต์บล็อกเชิงลึกและยื่นข้อผิดพลาดเกี่ยวกับปัญหานี้หากคุณต้องการรายละเอียดเพิ่มเติม

(เดิมฉันแก้ไขมันด้วยการเปิด /lib/systemd/system/docker.service และเพิ่มการตั้งค่า DNS ในบรรทัด ExecStartแต่ไม่ดีเราไม่ควรแก้ไขไฟล์ systemd โดยตรง )


ขอบคุณสำหรับวิธีแก้ปัญหาของคุณ - มีประโยชน์บนท้องถนนฉันเข้ามาหาทางออกของฉัน - ซึ่งฉันคิดว่าเป็นการจับคู่ที่หรูหรากว่าสำหรับสถานการณ์ของฉันและลักษณะของการใช้ Docker บน Ubuntu (หรือ distros เดสก์ท็อปอื่น ๆ
เอเดรีย

16

ฉันไม่ได้ใช้นักเทียบท่าด้วยตัวเองดังนั้นโดยปกติฉันจะไม่ชนที่นี่ในคำถามนักเทียบท่า แต่ฉันเพิ่งจะอ่านเกี่ยวกับมันและสะดุดในเอกสารนักเทียบท่าบางอย่างที่ปรากฏเพื่อแก้ไขปัญหาที่แน่นอนนี้ เพื่อสรุป ...

เอกสารแนะนำการแก้ไขปัญหาเล็กน้อย สิ่งแรกคือการระบุเซิร์ฟเวอร์ DNS ที่จะใช้โดยนักเทียบท่า daemon สำหรับภาชนะบรรจุโดยเพิ่มบรรทัดต่อไปนี้/etc/default/docker:

docker_OPTS="--dns 8.8.8.8"

ที่ DNS ที่ระบุอาจเป็นเซิร์ฟเวอร์ DNS ในเครื่องเช่น 192.168.1.1 (เกตเวย์) จากนั้นรีสตาร์ทด้วย

sudo restart docker

โซลูชันทางเลือกเกี่ยวข้องกับการปิดใช้งาน dnsmasq ใน NetworkManager โดยการคอมเม้นต์การกำหนดค่า/etc/NetworkManager/NetworkManager.confดังนี้:

#dns=dnsmasq

จากนั้นรีสตาร์ททั้งสอง

sudo restart network-manager
sudo restart docker

3
ปิดการใช้งาน dnsmasq ทำงานสำหรับฉัน
bennyl

2
แน่นอนว่าวิธีการหลังนี้หมายถึงผู้จัดการเครือข่ายไม่สามารถควบคุม dnsmasq ได้ซึ่งหมายความว่ามันไม่สามารถเปลี่ยนเซิร์ฟเวอร์ dns ของคุณเมื่อคุณเปลี่ยนเครือข่ายรวมถึงการเปลี่ยนเป็น VPN วิธีก่อนดูเหมือนดีกว่าสำหรับฉัน แต่ฉันต้องการให้ dnsmasq รับฟัง docker IP (172.17.0.1) ด้วยดังนั้นฉันจึงสามารถชี้โฮสต์ hoster ได้
mc0e

1
ตั้งแต่ Ubuntu เปลี่ยนไปตั้งค่า Docker ด้วย sytemd /etc/default/dockerไม่มีผลกระทบใด ๆ อีกต่อไป ดูโซลูชันของฉันสำหรับวิธีแก้ปัญหานี้ในโลกหลังเริ่มต้น / เริ่มต้นใหม่
Robin Winslow

/etc/NetworkManager/NetworkManager.confไม่มีอยู่ใน Ubuntu 18.04 LTS : /
XtraSimplicity

โปรดทราบว่าการตั้งค่าบางอย่างของ Ubuntu 18.04 (เช่นรูปภาพขั้นต่ำใน Amazon) systemd-resolvedทำหน้าที่เป็นเซิร์ฟเวอร์แคช DNS โดยค่าเริ่มต้นและจะกระตุ้นให้เกิดWARNING: Local (127.0.0.1) DNS resolver found in resolv.conf and containers can't use it.ปัญหา (การตั้งค่า Ubuntu 16.04 ไม่ปรากฏขึ้นเพื่อเปิดใช้งานตามค่าเริ่มต้น) วิธีแก้ปัญหาคือการปิดการใช้งานsystemd-resolvedหรือใช้--dnsตัวเลือกเมื่อเริ่มต้นภาชนะตามที่กล่าวไว้ในคำตอบหลัก
Anon

9

ฉันพบปัญหานี้ในสถานการณ์ที่เฉพาะเจาะจง

  • การเรียกใช้คอนเทนเนอร์นักเทียบท่าบนเครื่องพัฒนาท้องถิ่นของฉัน
  • ซึ่งเชื่อมต่อกับ VPN
  • สคริปต์บิลด์คอนเทนเนอร์ของเราทำสิ่งต่าง ๆ เช่นเรียกใช้npm installจากที่เก็บที่กำหนดเองบน VPNภายในคอนเทนเนอร์
    • สิ่งนี้ทำงานได้จาก CI ไปป์ไลน์ แต่ไม่ใช่จากเครื่องนักพัฒนาซอฟต์แวร์ของเราเพราะnpmไม่สามารถทำการค้นหา DNS ที่ประสบความสำเร็จได้
    • เรามีปัญหากับคอนเทนเนอร์ที่ต้องทำการค้นหาเพื่อเรียกใช้ REST API ภายนอก

Ubuntu ตามค่าเริ่มต้น dnsmasq NetworkManager เพื่อแคชคำร้องขอ DNS และกำหนดค่า/etc/resolv.confให้ชี้ไปที่อินสแตนซ์นี้127.0.1.1

  • ไคลเอ็นต์ VPN ที่เราใช้ไม่รองรับ NetworkManager และบังคับให้เป็นของตัวเอง/etc/resolv.confซึ่งเขียนทับการกำหนดค่า NetworkManager
  • สิ่งนี้จะกำหนดค่าเซิร์ฟเวอร์ DNS สำหรับ VPN
  • นักเทียบท่าเงาของคุณ/etc/resolv.confไปยังภาชนะบรรจุโดยค่าเริ่มต้น
    • โดยปกติแล้วบน Ubuntu มันจะส่งผ่านเซิร์ฟเวอร์ Google DNS ไปยังคอนเทนเนอร์ (เนื่องจากรู้เกี่ยวกับ dnsmasqสถานการณ์
    • แต่ก็ยินดีที่จะส่งการกำหนดค่าเซิร์ฟเวอร์ DNS DNS ไปยังคอนเทนเนอร์
    • ไม่มีเส้นทางจากคอนเทนเนอร์บนdocker0บริดจ์เครือข่ายไปยังเซิร์ฟเวอร์ DNS ผ่านtap0อะแดปเตอร์VPN
  • อย่างไรก็ตามการค้นหา DNS ทั้งหมดในคอนเทนเนอร์ล้มเหลวเนื่องจากไม่สามารถเข้าถึงเซิร์ฟเวอร์ DNS ที่ให้มาด้วยเท่านั้น
  • นอกจากนี้เครือข่ายบางเครือข่ายบล็อกการร้องขอไปยังเซิร์ฟเวอร์ DNS ของ Google เพราะต้องการดักฟังการค้นหา DNS ทั้งหมดของคุณ

การแก้ไขปัญหา :

มันจะดูสง่างามกว่าการใช้ NetworkManager และเป็นdnsmasqตัวอย่างที่ถูกจับในแบบที่มันถูกออกแบบมา

  1. บอกนักเทียบท่าให้ใช้dnsmasqอินสแตนซ์ของคุณกับ DNS

    • เพิ่มหรือแก้ไขไฟล์/etc/docker/daemon.jsonเพื่อบอกให้นักเทียบท่าใช้docker0บริดจ์อะแดปเตอร์สำหรับ DNS

      {
        "dns": ["172.17.0.1"]
      }
      
  2. กำหนดค่าdnsmasqอินสแตนซ์NM เพื่อฟังบริดจ์ Docker เช่นกันเพราะโดยค่าเริ่มต้นจะรับฟังเพียง 127.0.1.1 เท่านั้น - สร้างไฟล์/etc/NetworkManager/dnsmasq.d/docker-bridge.conf

    # Default Docker bridge
    interface=docker0
    # Other Docker bridges
    interface=br-*
    
  3. ฉันไม่ชอบพฤติกรรมหยาบคายของไคลเอนต์ VPN นั้นและฉันต้องการใช้ DNS ที่จุดสิ้นสุด VPN สำหรับการค้นหา VPN เท่านั้น (หากคุณมีไคลเอนต์ VPN สุภาพที่ใช้ NetworkManager ที่กำหนดค่าไว้อย่างถูกต้องคุณจะไม่ต้องทำสิ่งนี้ )

    • ปิดคุณสมบัติ DNS ในไคลเอนต์ VPN (จะหยุดเขียนทับการresolv.confเชื่อมต่อและตอนนี้ DNS ทั้งหมดจะผ่านdnsmasqอีกครั้ง)
    • เพิ่มไฟล์ปรับแต่งเพื่อบอกdnsmasqการร้องขอ DNS โดยตรงสำหรับโดเมนของคุณอย่างเหมาะสม - เพิ่มไฟล์ `/etc/NetworkManager/dnsmasq.d/vpn-dns.conf

      server=/myprivatedomain.net/10.0.0.1  
      # or whatever your private DNS server is
      
    • เลือกเพิ่มโดเมนการค้นหาสำหรับโดเมนของคุณเพื่อให้คุณสามารถใช้ชื่อย่อ

      • ฉันเพิ่งเพิ่มโดเมนท้องถิ่นของเราลงในรายการค้นหาในการเชื่อมต่อเครือข่ายเริ่มต้นของฉัน
  4. รีสตาร์ท NetworkManager และ Docker

    sudo service network-manager restart
    sudo service docker restart
    

ณ จุดนี้คอนเทนเนอร์ Docker ของคุณควรจะสามารถทำได้nslookupโดยไม่มีปัญหาเมื่อคุณใช้ VPN สำหรับโดเมนทั้งภายในและภายนอก VPN ของคุณ


1
การปรับแต่งขนาดเล็กที่ไม่เกี่ยวข้องกับการเข้ารหัส hard-coding docker0 bridge IP คือการใช้อินเตอร์เฟซแทนการฟังคำสั่งที่อยู่: interface = docker0
siwyd

คำอธิบายและคำแนะนำที่ยอดเยี่ยม +1 สมควรได้รับ
ereOn

Cheers @simonwydooghe - ฉันได้รวมข้อเสนอแนะของคุณ - คุณยังสามารถใช้สัญลักษณ์แทนในฟิลด์นั้นได้ดังนั้นฉันจึงเพิ่มรูปแบบสำหรับชื่อบริดจ์ทั้งหมดที่ใช้โดยเครือข่ายที่ไม่ใช่ค่าเริ่มต้น (อย่างน้อยที่สุดเท่าที่ใช้โดยนักแต่ง
เอเดรียน

1
ดูเหมือนว่าค่า dns ใน daemon.json จะต้องเป็นอาร์เรย์มิฉะนั้นฉันจะได้รับข้อผิดพลาด: cannot unmarshal string into Go value of type []stringเมื่อรีสตาร์ทบริการนักเทียบท่า
Slaven Rezic

อัปเดตสำหรับไบโอนิค: 18.04 ไม่ใช้อินสแตนซ์ที่ดักจับของ dnsmasq ที่จัดการโดย NetworkManager สำหรับ DNS และใช้การแก้ไขระบบแทน ซึ่งทำให้เกิดปัญหาของตัวเองเนื่องจากไม่สามารถกำหนดค่าให้ฟังสะพาน docker0 ได้ ฉันใช้วิธีปิดใช้งานและติดตั้ง NetworkManager dnsmasq อีกครั้งและกำหนดค่าให้ถูกต้อง
เอเดรีย

2

นี่คือวิธีที่ฉันตั้งค่าตัวเทียบท่าบนเซิร์ฟเวอร์ Ubuntu 14.04 ที่ไม่มีหัว

ฉันใช้เซิร์ฟเวอร์ Ubuntu 14.04 โดยติดตั้งตัวเชื่อมต่อรุ่นต่อไปนี้

#docker version
Client version: 0.9.1
Go version (client): go1.2.1
Git commit (client): 3600720
Server version: 0.9.1
Git commit (server): 3600720
Go version (server): go1.2.1

ไฟล์ /etc/init/docker.io.conf และสคริปต์มีบรรทัดต่อไปนี้:

# modify these in /etc/default/$UPSTART_JOB (/etc/default/docker)
    DOCKER=/usr/bin/$UPSTART_JOB
    DOCKER_OPTS=

คำตอบข้างต้นช่วยให้ฉันค้นหาไฟล์ด้านบน

ฉันไม่ใส่เครื่องหมายข้อคิดเห็นต่อไปนี้ใน /etc/default/docker.io และเพิ่มเซิร์ฟเวอร์ DNS ในเครื่อง:

# Use DOCKER_OPTS to modify the daemon startup options.  
DOCKER_OPTS="--dns 192.168.X.X"

เริ่มบริการใหม่ด้วย:

sudo service docker.io restart

Ran docker run <image> /bin/bash

ไม่มีข้อความ dns เมื่อเริ่มต้นคอนเทนเนอร์

เริ่มคอนเทนเนอร์ใหม่ติดตั้ง dnsutils

Ran dig และข้อความเซิร์ฟเวอร์เป็นเซิร์ฟเวอร์ DNS ภายในเครื่องที่ถูกต้อง


0

ผมมีปัญหาที่คล้ายกันรายงานไปยัง StackOverflow ปรากฏว่าฉันไม่สามารถสืบค้น8.8.8.8nameserver ที่ระบุในการติดตั้ง Ubuntu เริ่มต้นของ Docker อย่างไรก็ตามฉันสามารถปิงได้ ในกรณีนี้ให้ใช้เซิร์ฟเวอร์ DNS ซึ่งคุณสามารถสอบถามได้จริง ทดสอบด้วย

nslookup - dns.server.name

และเริ่มคอนเทนเนอร์ผ่าน

docker run --dns=ip.addr.of.dns

ฉันยังไม่พบวิธีที่จะhttps://askubuntu.com/q/607172/30266เพื่อหาวิธีแก้ปัญหาอัตโนมัติ


คำตอบของฉันอาจจะเป็นไปโดยอัตโนมัติเพียงพอสำหรับคุณ ...
Adrian

0

คุณสามารถใช้แก้ไข DNS ของโฮสต์ท้องถิ่น (เช่นdnsmasq) จากตู้คอนเทนเนอร์หางของคุณถ้าพวกเขาอยู่ในเครือข่ายที่ผู้ใช้กำหนด ในกรณีนั้นคอนเทนเนอร์/etc/resolv.confจะมีเนมเซิร์ฟเวอร์127.0.0.11(aka เซิร์ฟเวอร์ DNS ที่ฝังตัวของ Docker ) ซึ่งสามารถส่งต่อการร้องขอ DNS ไปยังที่อยู่ลูปแบ็คของโฮสต์ได้อย่างถูกต้อง

$ cat /etc/resolv.conf
nameserver 127.0.0.1
$ docker run --rm alpine cat /etc/resolv.conf
nameserver 8.8.8.8
nameserver 8.8.4.4
$ docker network create demo
557079c79ddf6be7d6def935fa0c1c3c8290a0db4649c4679b84f6363e3dd9a0
$ docker run --rm --net demo alpine cat /etc/resolv.conf
nameserver 127.0.0.11
options ndots:0    

หากคุณใช้docker-composeจะเป็นการตั้งค่าเครือข่ายที่กำหนดเองสำหรับตู้คอนเทนเนอร์ของคุณโดยอัตโนมัติ (พร้อมรูปแบบไฟล์v2 + ) แต่โปรดทราบว่าในขณะที่docker-composeภาชนะบรรจุทำงานในเครือข่ายที่ผู้ใช้กำหนดก็ยังคงสร้างไว้ในเครือข่ายเริ่มต้น ในการใช้เครือข่ายที่กำหนดเองสำหรับการสร้างคุณสามารถระบุnetworkพารามิเตอร์ในการกำหนดค่าการสร้าง (ต้องใช้รูปแบบไฟล์v3.4 + )

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.