我有一个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
Run Code Online (Sandbox Code Playgroud)
让我们说作为一个例子,我想使用telnet(其他命令类似地失败)连接到端口80.
$ telnet 127.0.0.1 80
Trying 127.0.0.1...
telnet: connect to address 127.0.0.1: Connection refused
Run Code Online (Sandbox Code Playgroud)
这很好,因为我没有在端口80上运行任何东西.但是,假设我使用的是localhost:
$ telnet localhost 80
telnet: localhost: Name or service not known
localhost: Unknown host
Run Code Online (Sandbox Code Playgroud)
这是没有意义的,因为从映射127.0.0.1到localhost中设置/etc/hosts.同样,使用容器的主机名(由docker设置)也会失败:
$ telnet $(hostname) 80
telnet: 39b50fcb603a: Name or service not known
39b50fcb603a: Unknown host
Run Code Online (Sandbox Code Playgroud)
为什么/etc/hosts文件似乎不起作用?
小智 0
来晚了,但是你可以/可以复制:
getent hosts localhost(或者getent hosts <dns name>) ?
(您还需要getent在临时映像中安装以及任何运行时依赖项(检查ldd getent)
我不太了解细节,但 AFAIU glibcgethostbyname将使用NSS作为解析名称的实现(至少在我的操作系统 RHEL7 上)。即使没有nsswitch.conf,NSS“插件”libnss_files.so似乎libnss_dns.so也是默认的,因此这些共享对象将尝试在运行时动态加载。如果这些共享库无法在运行时加载(因为它们没有安装在您的临时映像中),则名称解析将会失败。
因此,本质上您还需要在映像中安装这些共享对象(libresolv.so对我来说也是必需的,作为 的动态链接依赖项libnss_dns.conf)。不同操作系统的详细信息可能有所不同,因此我很难立即描述准确的过程。
strace您可以使用(with )来具体跟踪正在尝试加载哪些共享对象docker run --cap-add SYS_PTRACE <image> strace <command>。
最后注意:
不要与上面的问题混淆,上面的问题是动态加载的共享对象在运行时丢失。但是,如果您要将动态链接的可执行文件安装到容器中,这篇博客文章描述了一种自动确定/安装链接时间依赖项的方法(它本质上使用正则表达式来解析 的输出ldd)
| 归档时间: |
|
| 查看次数: |
1342 次 |
| 最近记录: |