简体   繁体   中英

Docker container unable to resolve localhost

I have a docker image which I have built from scratch, rather than basing it on an existing image such as centos or ubuntu. Processes on the machine do not seem to be able to resolve localhost or the machine hostname, even though the mapping for both exists in /etc/hosts . Here's what the /etc/hosts file on the container (generated by docker) looks like:

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

Let's say as an example I want to use telnet (other commands fail similarly) to connect to port 80.

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

This is fine, because I'm not running anything on port 80. However, let's say I use localhost instead:

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

This doesn't make sense, because the mapping from 127.0.0.1 to localhost is set in /etc/hosts . Similarly, using the hostname of the container (set by docker) also fails:

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

Why does the /etc/hosts file seem to not be working?

Coming in late, but can/could you replicate with:

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

(you will also need to install getent in your scratch image, along with any runtime dependencies (check ldd getent )

I am not strong on the details, but AFAIU glibc's gethostbyname will use NSS as the implementation to resolve names (at least on my OS, RHEL7). Even without a nsswitch.conf , NSS 'plugins' libnss_files.so and libnss_dns.so appear to be the default, and so these shared objects will be attempted to be dynamically loaded at runtime. If these shared libraries can't be loaded at runtime (because they are not installed in your scratch image) name resolution will fail.

So essentially you need to also install these shared objects in your image ( libresolv.so was also required for me, as a dynamically linked dependency of libnss_dns.conf ). The details on how probably vary across OS's, so it isn't easy for me to immediately describe an accurate process.

You can trace specifically which shared objects are being attempted to be loaded using strace (with docker run --cap-add SYS_PTRACE <image> strace <command> ).

Final note: Not to confuse with the above issue, which is dynamically loaded shared objects missing at runtime. But if you are installing dynamically linked executables into a container, this blog post describes a way of determining/installing the link time dependencies automatically (it essentially uses regexes to parse the output of ldd )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM