Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

unable to edit /etc/resolv.conf in docker container

I want to add a domain entry to /etc/resolv.conf of my docker container.

Here is my dockerFile

FROM tomcat:8.0.20-jre7
VOLUME /tmp
#RUN sed -i "s|search local|domain com.example.com|g;" /etc/resolv.conf
RUN echo "domain com.example.com" >> /etc/resolv.conf
# Expose ports.
EXPOSE 8080

I tried both echo and sed. with sed, I get error during build.

sed: cannot rename /etc/sed6LcoES: Device or resource busy

but with echo container build and run successfully. however, when I get into container, I do not see my domain added in /etc/resolv.conf.

why is it not working?

NOTE: I have got dns-search working by passing during run argument

docker run -p 8080:8080 --dns-search=com.example.com -d --name myawesome my/myawesome:latest

but I am interested in getting dockerFile working.

like image 679
brain storm Avatar asked Dec 08 '16 06:12

brain storm


2 Answers

This is by design. /etc/resolv.conf is used by docker engine to handle service discovery. Documentation states the following:

How can Docker supply each container with a hostname and DNS configuration, without having to build a custom image with the hostname written inside? Its trick is to overlay three crucial /etc files inside the container with virtual files where it can write fresh information … This arrangement allows Docker to do clever things like keep resolv.conf up to date across all containers when the host machine receives new configuration over DHCP later. The exact details of how Docker maintains these files inside the container can change from one Docker version to the next, so you should leave the files themselves alone and use the following Docker options instead.

If you want to override/reconfigure some dns settings, use --dns parameters during container starting. See more details:

  • Configure DNS in Docker
like image 143
Ivan Frolov Avatar answered Oct 03 '22 02:10

Ivan Frolov


Using the standard output stream can be solved by trying the following code, the namespace section is corrected to its own DNS server IP, but this is only valid while the container is running:

echo "$(sed '2,$c nameserver 223.5.5.5\nnameserver 223.6.6.6' /etc/resolv.conf)" > /etc/resolv.conf

The sed command does not actually modify a file, but instead creates a new file to replace the original file.(so edit it by vim is ok). Because /etc/resolve.conf is mounted, replacing the original file will inform the device that it is busy.

You can observe the files being mounted by command df -ah :

Filesystem      Size  Used Avail Use% Mounted on
overlay          59G  7.5G   49G  14% /
...
mqueue             0     0     0    - /dev/mqueue
shm              64M     0   64M   0% /dev/shm
/dev/sda1        59G  7.5G   49G  14% /etc/resolv.conf
....

The right way, you can specify the container's DNS server IP when running docker images:

$ docker run --help|grep dns
      --dns list                       Set custom DNS servers
      --dns-option list                Set DNS options
      --dns-search list                Set custom DNS search domains

$ docker run -it --rm --dns=223.5.5.5 --dns=223.6.6.6 centos:perf-tools /bin/bash
[root@ea0ac0fcd834 /]# cat /etc/resolv.conf
nameserver 223.5.5.5
nameserver 223.6.6.6

In addition, DNS server IP can be modified based on the docker-composer.yml configuration file:

dns: 8.8.8.8
dns:
  - 8.8.8.8
  - 9.9.9.9

more see: https://docs.docker.com/v17.09/compose/compose-file/#dns

like image 24
lupguo Avatar answered Oct 03 '22 03:10

lupguo