簡體   English   中英

Docker容器無法解析localhost

[英]Docker container unable to resolve localhost

我有一個Docker鏡像,我從頭開始構建,而不是基於現有的圖像,如centos或ubuntu。 機器上的進程似乎無法解析localhost或機器主機名,即使兩者的映射都存在於/etc/hosts 這是容器上的/etc/hosts文件(由docker生成)的樣子:

127.0.0.1   localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.3  39b50fcb603a

讓我們說作為一個例子,我想使用telnet(其他命令類似地失敗)連接到端口80。

$ telnet 127.0.0.1 80
Trying 127.0.0.1...
telnet: connect to address 127.0.0.1: Connection refused

這很好,因為我沒有在端口80上運行任何東西。但是,假設我使用localhost

$ telnet localhost 80
telnet: localhost: Name or service not known
localhost: Unknown host

這沒有意義,因為從127.0.0.1localhost的映射是在/etc/hosts 同樣,使用容器的主機名(由docker設置)也會失敗:

$ telnet $(hostname) 80
telnet: 39b50fcb603a: Name or service not known
39b50fcb603a: Unknown host

為什么/etc/hosts文件似乎不起作用?

來得晚,但可以/你可以復制:

getent hosts localhost (或getent hosts <dns name> )?

(您還需要在暫存圖像中安裝getent ,以及任何運行時依賴項(檢查ldd getent

我對細節不太滿意,但AFAIU glibc的gethostbyname將使用NSS作為解析名稱的實現(至少在我的操作系統,RHEL7上)。 即使沒有nsswitch.conf ,NSS的“插件” libnss_files.solibnss_dns.so似乎也是默認的,因此將嘗試在運行時動態加載這些共享對象。 如果無法在運行時加載這些共享庫(因為它們未安裝在臨時映像中),則名稱解析將失敗。

所以基本上你還需要在你的映像中安裝這些共享對象(我也需要libresolv.so ,作為libnss_dns.conf的動態鏈接依賴項)。 有關操作系統可能有多大差異的詳細信息,因此我不容易立即描述准確的過程。

您可以使用strace專門跟蹤嘗試加載哪些共享對象(使用docker run --cap-add SYS_PTRACE <image> strace <command> )。

最后說明:不要混淆上述問題,即運行時缺少動態加載的共享對象。 但是如果要將動態鏈接的可執行文件安裝到容器中, 這篇博客文章描述了一種自動確定/安裝鏈接時依賴關系的方法(它主要使用正則表達式來解析ldd的輸出)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM