Many times when working with docker containers I feel the need of assigning a known beforehand IP address to a container. This is a huge advantage if you want to control the network access to and from a container with a tool like iptables. However, current docker version (1.11.1) does not allow this operation out of the box, but there is an official way of achieving this. Thanks to
docker network command a user may create a fully customizable network and connect a container to it. You may find full information at the official Docker site, here.
I will start with a clean docker installation on a test vagrant machine (Ubuntu Trusty). After installing docker, as usual, you may see
docker0 network interface. This a default bridging interface. I will follow the documentation and create an isolated network using the same subnet, addresses and names.
So the first step is to create a new network:
$ docker network create -d bridge --subnet 172.25.0.0/16 isolated_nw
This network will allow me to use a
172.25.255.254 address range. If I run
ifconfig now I will see that a new interface is created. In my case, docker calls it
br-98446a2a4f1f. Just to be sure I reboot my machine to see if this network persists across reboots and it does.
Now I want to start
nginx container with
172.25.0.2 address, I can do it with the following command:
$ docker run --net=isolated_nw --ip=172.25.0.2 -d --name=my_nginx_01 nginx
If I get inside the container and run
ip addr command I will see that the assigned IP address is, in fact, the requested one:
root@597d1056bc32:/# ip addr 7: eth0:
mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:19:00:02 brd ff:ff:ff:ff:ff:ff inet 172.25.0.2/16 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::42:acff:fe19:2/64 scope link valid_lft forever preferred_lft forever
Now, I will start another container just to check the connectivity between them:
$ docker run --net=isolated_nw --ip=172.25.0.3 -d --name=my_nginx_02 nginx
So, if I get inside a second container I'm able to perform ping and telnet with the first one:
root@47f62e6951db:/# ping 172.25.0.2 PING 172.25.0.2 (172.25.0.2): 56 data bytes 64 bytes from 172.25.0.2: icmp_seq=0 ttl=64 time=0.253 ms 64 bytes from 172.25.0.2: icmp_seq=1 ttl=64 time=0.103 ms 64 bytes from 172.25.0.2: icmp_seq=2 ttl=64 time=0.140 ms --- 172.25.0.2 ping statistics --- 3 packets transmitted, 3 packets received, 0% packet loss round-trip min/avg/max/stddev = 0.103/0.165/0.253/0.064 ms root@47f62e6951db:/# telnet 172.25.0.2 80 Trying 172.25.0.2... Connected to 172.25.0.2. Escape character is '^]'. Connection closed by foreign host.
Time to check that linking between containers also works, I will start my containers this way:
$ docker run --net=isolated_nw --ip=172.25.0.2 -d --name=my_nginx_01 nginx $ docker run --net=isolated_nw --ip=172.25.0.3 --link my_nginx_01:my_nginx_01 -d --name=my_nginx_02 nginx
Then, if I connect to
my_nginx_02 container I will be able to ping and telnet
root@6e36ce623842:/# ping my_nginx_01 PING my_nginx_01 (172.25.0.2): 56 data bytes 64 bytes from 172.25.0.2: icmp_seq=0 ttl=64 time=0.161 ms 64 bytes from 172.25.0.2: icmp_seq=1 ttl=64 time=0.173 ms --- my_nginx_01 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max/stddev = 0.161/0.167/0.173/0.000 ms root@6e36ce623842:/# telnet my_nginx_01 80 Trying 172.25.0.2... Connected to my_nginx_01. Escape character is '^]'. Connection closed by foreign host.
As you can see
my_nginx_01 resolves to the IP address assigned during the startup. With this configuration, you may be able to control your security perimeter using
FORWARD chain in your