繁体   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