Category Archives: docker

Dind (Docker in Docker) on Atomic host

I am preparing for Red Hat Docker exam 276, while preparation I came to know about docker in docker term which is called as Dind. It’s not a part of exam content. However I started digging more on it and I found some useful blogs on net to get start with it. In this article I am going to share the steps which I have followed to see the working on Dind.

Checking the docker version present on atomic host by default :

-bash-4.2# docker version
Client:
Version: 1.10.3
API version: 1.22
Package version: docker-common-1.10.3-59.el7.x86_64
Go version: go1.6.2
Git commit: 429be27-unsupported
Built: Fri Nov 18 17:03:44 2016
OS/Arch: linux/amd64

Server:
Version: 1.10.3
API version: 1.22
Package version: docker-common-1.10.3-59.el7.x86_64
Go version: go1.6.2
Git commit: 429be27-unsupported
Built: Fri Nov 18 17:03:44 2016
OS/Arch: linux/amd64

Started a new container using ding image.

-bash-4.2# docker run –privileged -t -i jpetazzo/dind
Unable to find image ‘jpetazzo/dind:latest’ locally
Trying to pull repository registry.access.redhat.com/jpetazzo/dind …
unknown: Not Found
Trying to pull repository docker.io/jpetazzo/dind …
latest: Pulling from docker.io/jpetazzo/dind
16da43b30d89: Pull complete
1840843dafed: Pull complete
91246eb75b7d: Pull complete
7faa681b41d7: Pull complete
97b84c64d426: Pull complete
a1bc5a98c1dc: Pull complete
ce58583abd90: Pull complete
66270626f481: Pull complete
Digest: sha256:63a7c4b0f69fbc21755e677f85532ce327e0240aedf6afa0421ca1f3a66dbf2e
Status: Downloaded newer image for docker.io/jpetazzo/dind:latest
ln: failed to create symbolic link ‘/sys/fs/cgroup/systemd/name=systemd’: Operation not permitted
INFO[0001] libcontainerd: new containerd process, pid: 72
ERRO[0002] devmapper: Udev sync is not supported. This will lead to data loss and unexpected behavior. Install a more recent version of libdevmapper or select a different storage driver. For more information, see https://docs.docker.com/engine/reference/commandline/daemon/#daemon-storage-driver-option
ERRO[0002] ‘overlay’ not found as a supported filesystem on this host. Please ensure kernel is new enough and has overlay support loaded.
INFO[0002] Graph migration to content-addressability took 0.00 seconds
INFO[0002] Loading containers: start.
WARN[0002] Running modprobe bridge br_netfilter failed with message: modprobe: ERROR: ../libkmod/libkmod.c:556 kmod_search_moddep() could not open moddep file ‘/lib/modules/3.10.0-514.2.2.el7.x86_64/modules.dep.bin’
modprobe: ERROR: ../libkmod/libkmod.c:556 kmod_search_moddep() could not open moddep file ‘/lib/modules/3.10.0-514.2.2.el7.x86_64/modules.dep.bin’
, error: exit status 1
WARN[0002] Running modprobe nf_nat failed with message: `modprobe: ERROR: ../libkmod/libkmod.c:556 kmod_search_moddep() could not open moddep file ‘/lib/modules/3.10.0-514.2.2.el7.x86_64/modules.dep.bin’`, error: exit status 1
WARN[0002] Running modprobe xt_conntrack failed with message: `modprobe: ERROR: ../libkmod/libkmod.c:556 kmod_search_moddep() could not open moddep file ‘/lib/modules/3.10.0-514.2.2.el7.x86_64/modules.dep.bin’`, error: exit status 1
INFO[0002] Default bridge (docker0) is assigned with an IP address 172.18.0.0/16. Daemon option –bip can be used to set a preferred IP address

INFO[0002] Loading containers: done.
INFO[0002] Daemon has completed initialization
INFO[0002] Docker daemon commit=7392c3b graphdriver=vfs version=1.12.5
INFO[0002] API listen on /var/run/docker.sock

Check the docker version inside it.

root@0d97538dcb4d:/# docker version
Client:
Version: 1.12.5
API version: 1.24
Go version: go1.6.4
Git commit: 7392c3b
Built: Fri Dec 16 02:30:42 2016
OS/Arch: linux/amd64

Server:
Version: 1.12.5
API version: 1.24
Go version: go1.6.4
Git commit: 7392c3b
Built: Fri Dec 16 02:30:42 2016
OS/Arch: linux/amd64

I am into the container now and I can run the docker commands inside container. Isn’t it cool ?

root@0d97538dcb4d:/# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

Let’s try to spawn a new container inside a container.

While trying to spawn a new container I ran out of space issue.

root@0d97538dcb4d:/# docker run -t -i mysql bash
ERRO[0403] Handler for POST /v1.24/containers/create returned error: No such image: mysql:latest
Unable to find image ‘mysql:latest’ locally
latest: Pulling from library/mysql
75a822cd7888: Pull complete
b8d5846e536a: Pull complete
b75e9152a170: Pull complete
832e6b030496: Pull complete
fe4a6c835905: Pull complete
c3f247e29ab1: Extracting [==================================================>] 19.02 kB/19.02 kB
21be3e562071: Download complete
c7399d6bf033: Downloading [=====================================> ] 57.31 MB/76.98 MB
c7399d6bf033: Downloading [==================================================>] 76.98 MB/76.98 MB
3835a628a92f: Download complete
530d0fb19b13: Download complete
ERRO[0549] Download failed: write /var/lib/docker/tmp/GetImageBlob883713982: no space left on device
ERRO[0549] Not continuing with pull after error: write /var/lib/docker/tmp/GetImageBlob883713982: no space left on device
docker: write /var/lib/docker/tmp/GetImageBlob883713982: no space left on device.
See ‘docker run –help’.

Checked the filesystem utilization inside container. Found that /etc/hosts has not such space left.

~~~
root@0d97538dcb4d:/# df -Ph
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/docker-253:0-5137701-f6e4b3a3f41c934e95188beb881a8fa964bcdcdef7bd86f46dfb8c3740905410 10G 456M 9.6G 5% /
tmpfs 1.9G 0 1.9G 0% /dev
tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup
/dev/mapper/rhelah-root 3.0G 2.3G 779M 75% /etc/hosts
shm 64M 0 64M 0% /dev/shm
~~~

I fixed the issue by expanding the root filesystem on host atomic machine. After that I was able to see the expanded filesystem space inside the container.

~~~
root@0d97538dcb4d:/# df -Ph
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/docker-253:0-5137701-f6e4b3a3f41c934e95188beb881a8fa964bcdcdef7bd86f46dfb8c3740905410 10G 456M 9.6G 5% /
tmpfs 1.9G 0 1.9G 0% /dev
tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup
/dev/mapper/rhelah-root 8.0G 2.3G 5.8G 28% /etc/hosts
shm 64M 0 64M 0% /dev/shm
~~~

Let’s try to start the second citizen container again. This time I am able to start the nested container successfully and I am into new nested container.

root@0d97538dcb4d:/# docker run -t -i mysql bash
ERRO[0917] Handler for POST /v1.24/containers/create returned error: No such image: mysql:latest
Unable to find image ‘mysql:latest’ locally
latest: Pulling from library/mysql
75a822cd7888: Pull complete
b8d5846e536a: Pull complete
b75e9152a170: Pull complete
832e6b030496: Pull complete
fe4a6c835905: Pull complete
c3f247e29ab1: Pull complete
21be3e562071: Pull complete
c7399d6bf033: Pull complete
ccdaeae6c735: Pull complete
3835a628a92f: Pull complete
530d0fb19b13: Pull complete
Digest: sha256:de1570492c641112fdb94db9c788f6a400f71f25a920da95ec88c3848450ed57
Status: Downloaded newer image for mysql:latest
root@bb8d6a3218ab:/#

Let’s switch to base atomic machine and see how many containers we are seeing in output.

We are seeing only one container. Second container is running inside this container.

-bash-4.2# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0d97538dcb4d jpetazzo/dind “wrapdocker” About an hour ago Up About an hour compassionate_borg

Let’s login into this container and then see the second running container. Great we are able to see nested container.

-bash-4.2# docker exec -it 0d97538dcb4d bash

root@0d97538dcb4d:/# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bb8d6a3218ab mysql “docker-entrypoint.sh” About an hour ago Up About an hour 3306/tcp gloomy_hawking

Let’s check some network settings about this setup. As you may already know by default installation of atomic host creates a docker bridge and first class container got the IP address in that default range.

In my case atomic host is having this docker0 linux bridge.

-bash-4.2# ip a show docker0
3: docker0: mtu 1500 qdisc noqueue state UP
link/ether 02:42:5a:45:6e:46 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:5aff:fe45:6e46/64 scope link
valid_lft forever preferred_lft forever

Inspecting the IP address of first class container. It’s range of docker0.

-bash-4.2# docker inspect -f ‘{{.NetworkSettings.IPAddress}}’ 0d97538dcb4d
172.17.0.2

Let’s login into container and then see the interfaces assigned to it.

-bash-4.2# docker exec -it 0d97538dcb4d bash
root@0d97538dcb4d:/# ip a
1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: docker0: mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:d5:03:ab:de brd ff:ff:ff:ff:ff:ff
inet 172.18.0.1/16 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:d5ff:fe03:abde/64 scope link
valid_lft forever preferred_lft forever
4: veth2b9b80a@if3: mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether 62:60:f4:0a:07:f3 brd ff:ff:ff:ff:ff:ff
inet6 fe80::6060:f4ff:fe0a:7f3/64 scope link
valid_lft forever preferred_lft forever
96: eth0@if97: mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.2/16 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::42:acff:fe11:2/64 scope link
valid_lft forever preferred_lft forever

We can see that it’s having another docker0 linux bridge which is having subnet range “172.18.0.1/16” now this will be used to provide the DHCP ip address to second class or nested containers.

root@0d97538dcb4d:/# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bb8d6a3218ab mysql “docker-entrypoint.sh” About an hour ago Up About an hour 3306/tcp gloomy_hawking
root@0d97538dcb4d:/# docker inspect -f ‘{{.NetworkSettings.IPAddress}}’ bb8d6a3218ab
172.18.0.2

This IP address will not be reachable from atomic host.

-bash-4.2# ping 172.18.0.2
PING 172.18.0.2 (172.18.0.2) 56(84) bytes of data.
^C
— 172.18.0.2 ping statistics —
3 packets transmitted, 0 received, 100% packet loss, time 2003ms

Obviously you would be able to reach “172.17.0.2” from atomic host because of masquerading rule.

-bash-4.2# iptables -L -t nat
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DOCKER all — anywhere anywhere ADDRTYPE match dst-type LOCAL

Chain INPUT (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination
DOCKER all — anywhere !loopback/8 ADDRTYPE match dst-type LOCAL

Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all — 172.17.0.0/16 anywhere

Chain DOCKER (2 references)
target prot opt source destination
RETURN all — anywhere anywhere