[英]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.1
到localhost
的映射是在/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.so
和libnss_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.