Restarting named container assigns different IP
Asked Answered
S

3

6

Im a trying to deploy my application using Docker and came across an issue that restarting named containers assigns a different IP to container. Maybe explaining what I am doing will better explain the issue:

  • Postgres runs inside a separate container named "postgres"
    $ PG_ID=$(docker run --name postgres postgres/image)
  • My webapp container links to postgres container
    $ APP_ID=$(docker run --link postgres:postgres webapp/image)

Linking postgres container image to webapp container inserts in webapp container a hosts file entry with the IP of the postgres container. This allows me to point to postgres db within my webapp using postgres:5432 (I am using Django btw). This all works well except if for some reason postgres crashes.

Before I manually stop postgres process to simulate postgres process crashing I verify IP of postgres container:

$ docker inspect --format "{{.NetworkSettings.IPAddress}}" $PG_ID
172.17.0.73

Now to simulate crash I stop postgres container:

$ docker stop $PG_ID

If now I restart postgres by using

$ docker start $PG_ID

the ip of the container changes:

$ docker inspect --format "{{.NetworkSettings.IPAddress}}" $PG_ID
172.17.0.74

Therefore the IP which points to postgres container in webapp container is no longer correct. I though that by naming container docker assigns a name to it with specific configs so that you can reliably link between containers (both network and volumes). If the IP changes this seems to defeat the purpose.

If I have to restart my webapp process each time I postgres restarts, this does not seem any better than just using a single container to run both processes. Then I can use supervisor or something similar to keep both of them running and use localhost to link between processes.

I am still new to Docker so am I doing something wrong or is this a bug in docker?

Sloat answered 13/7, 2014 at 21:51 Comment(2)
You may find this related question & answer useful.Etherize
thanks. will take a look at ddns. hopefully wont be that difficult. Docker seems very cool however it seems needs some learning curve to use it properly...Sloat
S
0

2nd UPDATE: maybe you already discovered this, but as workaround, I plan to map the service to share the database to the host interface (ej: with -p 5432:5432), and connect the webapps to the host IP (the IP of the docker0 interface: in my Ubuntu and CentOS, the IP is 172.17.42.1). If you restart the postgres container, the conteiner's IP will change, but I wil be accesible using 172.17.42.1:5432. The downside is that you are exposing that port to all the containers, and loose the fine-grained mapping that --link gives you.

--- OLD UPDATES:

CORRECTION: Docker will map 'postgres' to the container's IP in the /etc/hosts files, on the webapp container. So, in the webapp container, you can ping 'postgres', and it will be mapped to the IP.

1st UPDATE: I've seen that Docker generates and mounts /etc/hosts, /etc/resolv.conf, etc. to have always the correct information, but this does not apply when the linked container is restarted. So, I've assumed (wrongly) that Docker would update the hosts files.

-- ORIGINAL (wrong) response:

Add --hostname=postgres-db (you can use anythin, I'm using something different than 'postgres' to avoid confussion with the container name):

$ docker run --name postgres --hostname postgres-db postgres/image

Docker will map 'postgres-db' to the container's IP (check the contents of /etc/hosts on the webapp container).

This will allow you run 'ping postgres-db' from the webapp container. If the IP changes, Dockers will update /etc/hosts for you.

In the Django app, use 'postgres-db' instead of the IP (or whatever you use for --hostname of the container with PostgreSql).

Bye! Horacio

Stralsund answered 16/7, 2014 at 2:0 Comment(2)
please check your facts. Docker when linking container only uses --name parameter. --hostname is only used to insert an entry in the postgres container, not in the webappcontainer.Sloat
miki725: you are right, I get confused in my tests. I have used the same string for name and hostname, and assumed that the specified in 'hostname' were used in /etc/hosts...Stralsund
U
0

According to https://docs.docker.com/engine/reference/commandline/run/, it should be possible to assign a static IP for your container -- at the time of container creation -- using the --ip option:

Example:

docker run -itd --ip 172.30.100.104 --name postgres postgres/image

....where 172.30.100.104 is a free IP address on a custom bridge/overlay network.

This should then retain the same IP address even if postgres container crashes/restarts.

Looks like this was released in Docker Engine v 1.10 or greater, therefore if you have a lower version, you have to upgrade first.

Unriddle answered 25/8, 2016 at 11:53 Comment(0)
S
-1

As of Docker 1.0 they implemented a stronger sense of linked containers. Now you can use the container instance name as if it were the host name.

Here is a link

I found a link that better describes your problem. And while that question was answered I wonder whether or not this ambassador pattern might not solve the problem... this assumes that the ambassador is more reliable than the services that link.

Sims answered 14/7, 2014 at 12:4 Comment(1)
please read my question. once the parent container is restarted, its IP changes hence whatever is in the hosts file is no longer valid.Sloat

© 2022 - 2024 — McMap. All rights reserved.