When docker container starts, does it gets /etc/hosts file from the image it got created from and then update it with the dynamic IP/hostname assigned to this container?
Assuming container is getting started with this simple command and no special arguments are provided:
docker run imageid
CodePudding user response:
Short answer
/etc/hosts
exists temporary in the image at each layer creation.
Detail
I've done a small test with the following dockerfile :
FROM ubuntu:latest
RUN cat /etc/hosts
Here is the build result :
Sending build context to Docker daemon 2.048kB
Step 1/2 : FROM ubuntu:latest
---> fb52e22af1b0
Step 2/2 : RUN cat /etc/hosts
---> Running in ad21775fc2be
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.2 ad21775fc2be
Removing intermediate container ad21775fc2be
---> 9479add5fe39
Successfully built 9479add5fe39
As you can see, we are able to show etc/hosts
content.
When I run an instance of this docker image:
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.2 5446c52a3dee
Only the last line changed
For more information on layers of a container :
https://docs.docker.com/develop/develop-images/dockerfile_best-practices/
EDIT
docker save
experience by @david-maze shows well that it is not stored permanently :
https://stackoverflow.com/a/69313033/16762357
CodePudding user response:
At least in one simple image, /etc/hosts
does not exist in the image; Docker synthesizes it from scratch every time it runs a container.
Arguably the simplest useful image is busybox
, which contains the statically-linked BusyBox tool set and nothing else. Its Dockerfile is very simple, just ADD
ing a tar file to an empty FROM scratch
base. If you run a container, you can see that /etc/hosts
exists inside the container:
docker run --rm busybox cat /etc/hosts
But we can also dig inside the image. Since this image is so tiny, it's straightforward.
docker save -o busybox-image.tar busybox
tar xf busybox-image.tar
ls
# there is a single layer directory with a very long name
cd 4775639832413f9c8c12a59a371ed1c5ae79cb5d743bb81266209c0620c4bf5b
mkdir layer
cd layer
# unpack the layer contents
tar xf ../layer.tar
ls ./etc
You can see that the image contains user-related files like /etc/passwd
and /etc/group
, but not network-related files like /etc/hosts
or /etc/resolv.conf
.
The important thing this means is that you cannot embed environment-specific network information into a Docker image; you cannot include an /etc/hosts
file because Docker will overwrite it when the container runs. It will honor the host's DNS settings, and if your environment has some local host names, setting up a DNS server like dnsmasq or BIND (or using a cloud-hosted option like Amazon's Route 53) will be more maintainable than trying to keep hosts files in sync.