Skip to content

Networking

Rodrigo edited this page Sep 29, 2019 · 2 revisions

There are three kinds of networks available on Docker 🐳 :

  • bridge
  • host
  • none

Docker uses by default a bridge network. It is a internal network created by Docker (usually in the range 172.17.0.0/16). The following command shows the networks created on Docker:

vagrant@ubuntu-xenial:~$ docker network ls 
NETWORK ID          NAME                DRIVER              SCOPE
931251463e55        bridge              bridge              local
b444b13137c0        host                host                local
f944c5a9e3d1        none                null                local
vagrant@ubuntu-xenial:~$ docker network inspect bridge 
[
    {
        "Name": "bridge",
        "Id": "931251463e55da4c565d0dfb08e44230416e49281d1fe6ec4755a5b5020936f7",
        "Created": "2019-09-29T08:31:39.6494105Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {
            "com.docker.network.bridge.default_bridge": "true",
            "com.docker.network.bridge.enable_icc": "true",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
            "com.docker.network.bridge.name": "docker0",
            "com.docker.network.driver.mtu": "1500"
        },
        "Labels": {}
    }
]

Now, we create two Alpine containers:

vagrant@ubuntu-xenial:~$ docker container run -d --name alpine-1 alpine sleep 10m
a0a6019875b1c4ddab85f322093ca75113e464e4dd553e0243da9facaec61949

vagrant@ubuntu-xenial:~$ docker container run -d --name alpine-2 alpine sleep 10m
3e2a8075a2b9ff0327b3a9a4fde1f30f5468d15291e0564ef0a6540d84dd70af
vagrant@ubuntu-xenial:~$ docker network inspect bridge
[
    {
        "Name": "bridge",
        "Id": "931251463e55da4c565d0dfb08e44230416e49281d1fe6ec4755a5b5020936f7",
        "Created": "2019-09-29T08:31:39.6494105Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "3e2a8075a2b9ff0327b3a9a4fde1f30f5468d15291e0564ef0a6540d84dd70af": {
                "Name": "alpine-2",
                "EndpointID": "ac4abab9cfa6f8301079ba4f67c548eb71a811cc113643d86c1902de550053b9",
                "MacAddress": "02:42:ac:11:00:03",
                "IPv4Address": "172.17.0.3/16",
                "IPv6Address": ""
            },
            "a0a6019875b1c4ddab85f322093ca75113e464e4dd553e0243da9facaec61949": {
                "Name": "alpine-1",
                "EndpointID": "636de7ed99abd60492b74bb4666ddc395dc0144c082413d8ca071ec5d646bf9d",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {
            "com.docker.network.bridge.default_bridge": "true",
            "com.docker.network.bridge.enable_icc": "true",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
            "com.docker.network.bridge.name": "docker0",
            "com.docker.network.driver.mtu": "1500"
        },
        "Labels": {}
    }
]

We can see two containers (alpine-2 & alpine-1) and their network configuration. ¿ Do they see each other ?

vagrant@ubuntu-xenial:~$ docker container exec -ti alpine-1 /bin/sh
/ # ping 172.17.0.3
PING 172.17.0.3 (172.17.0.3): 56 data bytes
64 bytes from 172.17.0.3: seq=0 ttl=64 time=0.185 ms
64 bytes from 172.17.0.3: seq=1 ttl=64 time=0.122 ms
^C
--- 172.17.0.3 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.122/0.153/0.185 ms
/ # ping alpine-2
ping: bad address 'alpine-2'

Bad address ? Why ? ⚠️ The default bridge network on Linux does not support name resolution via the Docker DNS service. So, ¿ What can we do ?

We are going to create a user-defined bridge network:

vagrant@ubuntu-xenial:~$ docker container stop alpine-1 alpine-2
alpine-1
alpine-2

vagrant@ubuntu-xenial:~$ docker container rm alpine-1 alpine-2
alpine-1
alpine-2
docker network create --driver bridge alpine-net

vagrant@ubuntu-xenial:~$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
386de47e534d        alpine-net          bridge              local
931251463e55        bridge              bridge              local
b444b13137c0        host                host                local
f944c5a9e3d1        none                null                local


vagrant@ubuntu-xenial:~$ docker container run -d --name alpine-1 --network alpine-net alpine sleep 10m
1cb3cf683ee8fea5cd3d1565d6f42a66b30e710d98fb5632aafe72aa61552832

vagrant@ubuntu-xenial:~$ docker container run -d --name alpine-2 --network alpine-net alpine sleep 10m
aca6c2f1badd071b753fbf73a64adf8180f6355d77e2d0cf1641c88484229e37
vagrant@ubuntu-xenial:~$ docker network inspect alpine-net
[
    {
        "Name": "alpine-net",
        "Id": "386de47e534de56839b352d97dfa182950eb01df191ccd8b6ea4fa415677aef4",
        "Created": "2019-09-29T09:05:35.876177759Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "1cb3cf683ee8fea5cd3d1565d6f42a66b30e710d98fb5632aafe72aa61552832": {
                "Name": "alpine-1",
                "EndpointID": "6918378a690a2413f9cc1b61ff43a2459d4744d0a06301957f57edd711fa3098",
                "MacAddress": "02:42:ac:12:00:02",
                "IPv4Address": "172.18.0.2/16",
                "IPv6Address": ""
            },
            "aca6c2f1badd071b753fbf73a64adf8180f6355d77e2d0cf1641c88484229e37": {
                "Name": "alpine-2",
                "EndpointID": "10dd9ed3d749c7367727a67959a27a370e1814b44a3bd7c4c2e16c34d9213aec",
                "MacAddress": "02:42:ac:12:00:03",
                "IPv4Address": "172.18.0.3/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]
vagrant@ubuntu-xenial:~$ docker container exec -ti alpine-1 /bin/sh
/ # ping alpine-2
PING alpine-2 (172.18.0.3): 56 data bytes
64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.172 ms
64 bytes from 172.18.0.3: seq=1 ttl=64 time=0.116 ms
^C
--- alpine-2 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.116/0.144/0.172 ms
/ # read escape sequence

It works!!! 🎉 (Docker has a internal DNS server which add all containers started with --name or --net-alias)


On the other hand, we have host network. With this kind of network there is not isolation between the Docker and host network.

vagrant@ubuntu-xenial:~$ docker container stop alpine-1 alpine-2
alpine-1
alpine-2

vagrant@ubuntu-xenial:~$ docker container rm alpine-1 alpine-2
alpine-1
alpine-2

vagrant@ubuntu-xenial:~$ docker container run -d --name nginx --network=host nginx
7cc8466d2ea9f503b6a75057061fb01b19bdb2520706214f74bf66213b6ca2fe
vagrant@ubuntu-xenial:~$ curl localhost:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

⚠️ Now, our Nginx container is using port 80, it would mean that you will now no be able to run another container on the same host and port.


Finally, the none network. Wit this kind of network, the containers are not attached to any network and does not have access to the external network or other containers. It is isolated from all other networks.


Tidying up:

vagrant@ubuntu-xenial:~$ docker container stop alpine-1 alpine-2 nginx
alpine-1
alpine-2

vagrant@ubuntu-xenial:~$ docker container rm alpine-1 alpine-2 nginx
alpine-1
alpine-2
Clone this wiki locally