Docker Certified Associate Exam Series (Part 6): Networking
Introduction to Docker Networking
Default Networks
When you install Docker on a host machine, it automatically creates 3 types of networks: none, bridge, and host networks.
- The Bridge network is the default network that Docker attaches to containers once they are created. This is a private internal network, whose IP address is typically 172.17.0.1, and assigns IP addresses in the 172.17.1 range to all containers attached to it. Isolated containers within the same host use these IP addresses to communicate with each other. The bridge network cannot facilitate external communication unless container ports are exposed to ports on the host.
- A Host network helps eliminate isolation between containers and hosts, letting containers access the host’s IP address without having to expose any ports. With the host network, you cannot run multiple containers on the same host, as the host’s external port is common to all containers within the host.
- On the other hand, with a None network, containers are not attached to any network. Containers in a none network cannot connect with external hosts or other isolated containers in the same network.
To specify the default network on which you want to run your container, define it as an attribute with the run command, that is:
$ docker run -d --name wbeapp --network=none nginx
or
$ docker run -d --name webapp --network=host nginx
To display the network mode:
$ docker inspect webapp | grep NetworkMode
User-Defined Networks
By default, Docker attaches containers to the Bridge network. You can also create your own Docker networks using the network create
command:
$ docker network create --driver bridge --subnet 182.18.0.0/16 custom-isolated-network
The above command creates a Bridge network named custom-isolated-network with the address 182.18.0.0/16.
To list the networks available on a host, type the command:
$ docker network ls
To check the configuration settings of a network, use the command:
$ docker inspect custom-isolated-network
Embedded DNS
Containers within the same host can resolve and communicate with each other using container names, i.e:
mysql.connect(container-name)
This is made possible by an embedded DNS server, present at the host on the address 127.0.0.1. This server works by creating a namespace for each container then connecting them using virtual ethernet pairs.
Additional Networking Commands
Some of the common tasks you will carry out with networking commands include:
- Listing all available networks:
$ docker network ls
- Checking for additional network information including subnets, gateways, drivers, and IP addresses:
$ docker network inspect net-name
- Attaching a container to a custom network:
$ docker network connect custom-net my-container
- Detaching a container from a custom network:
$ docker network disconnect custom-net my-container
- Deleting a custom network:
$ docker network rm custom-net
- Removing all unused networks:
$ docker network prune
Demo-Docker Network
In this practical lab, you will test your grasp of networking commands in Docker. Some of the content you will cover includes:
- Listing the default available networks
- Obtaining details of networks
- Inspecting network connection in containers
- Creating custom networks
- Attaching & Detaching Containers
- Connecting to remote networks
- Deleting networks
Namespaces
Docker uses namespaces to provide isolation between networks, containers, and processes within the same host. While a container cannot gain access to processes running in a different namespace, the host can view all processes running within its namespaces. A container should, therefore, ‘think’ that it is running on its own host. The host can establish connectivity and communication between namespaces.
If you list the processes running within a container, you will only see one. Inspecting processes as a root user on the host will return various processes, including the containers on the host.
The host has an ethernet interface, routing table, and an Address Resolution Protocol (ARP) table that enable communication with other hosts and processes.
Any time you create a container, the host assigns it a namespace. This namespace comes complete with its own interface, routing, and ARP tables.
- To create new namespaces on the host named red and blue, run the following commands respectively:
$ ip netns add red
$ ip netns add blue
- You can list all namespaces in a host using the command:
$ ip netns
- To display the host interfaces:
$ ip link
- To check for interfaces within a namespace:
$ ip netns exec red ip link
- Alternatively, you could type the command:
$ ip -n red link
- To check IP addresses on the ARP table within a host, run the command:
$ arp
Since namespaces don’t connect to other processes or hosts, running the arp
command within a namespace will return no results:
$ ip netns exec red arp
To display the routing table within the host, run the route command:
$ route
Naturally, namespaces cannot communicate with each other. To establish a connection between two namespaces, we use a virtual ethernet pair/pipe. To create these links for the red and blue namespaces we created earlier, use the command:
$ ip link add veth-red type veth peer name veth-blue
We can now attach each end of the link to the respective namespaces using the command:
$ ip link set veth-red netns red
$ ip link set veth-blue netns blue
Now, we assign IP addresses to the red and blue namespaces by using the commands:
$ ip -n red addr add 192.168.15.1/16 dev veth-red
$ ip -n blue addr add 192.168.15.2/16 dev veth-blue
These links are not yet active. To activate the connection, we bring up the links using the commands:
$ ip -n red link set veth-red up
$ ip -n blue link set veth-blue up
You can now check the connection between these namespaces:
$ ip netns exec red ping 192.168.15.2
$ ip netns exec blue ping 192.168.15.1
If you run the arp
command, will display the details of the other namespace’s interface:
$ ip netns exec red arp
This process only applies when we are trying to connect two namespaces. With multiple namespaces, we will create a virtual network that provides a switch a connection between multiple processes. There exist several switch solutions for Docker. For this exercise, we’ll use a Linux Bridge to connect various namespaces in a docker host.
First, we create an interface named v-net-0 of type bridge, using the command:
$ ip link add v-net-0 type bridge
We then bring up this link:
$ ip link set dev v-net-0 up
We’ll now connect namespaces to this interface by first deleting the virtual link we set up between the red and blue namespaces we created earlier.
$ ip -n red link del veth-red
This command deletes the entire connection between the two namespaces. We will now create new cable pairs that connect namespaces to the virtual network.
$ ip link add veth-red type veth peer name veth-red-br
$ ip link add veth-blue type veth peer name veth-blue-br
You can now attach one end of this link to the namespace:
$ ip link set veth-red netns red
$ ip link set veth-blue netns blue
We then connect the other ends of these links to the network:
$ ip link set veth-red-br master v-net-0
$ ip link set veth-blue-br master v-net-0
We then assign IP addresses to these links:
$ ip -n red addr add 192.168.15.1/24 dev veth-red
$ ip -n blue addr add 192.168.15.2/24 dev veth-blue
To activate these links, use the following commands for bringing them up:
$ ip -n red link set veth-red up
$ ip -n blue link set veth-blue up
Now, assign an IP address to the host’s interface to establish connectivity between the host and namespaces:
$ ip addr add 192.168.15.5/24 dev v-net-0
We can now connect to the host from all namespaces. To check, run the ping command:
$ ping 192.168.15.5
This network is still private and cannot be accessed from outside the host. If you want to connect your namespaces to an external network through the host’s ethernet port, define a gateway on the host’s routing table using the command.
$ ip netns exec blue ip route add 192.168.1.0/24 via 192.168.15.5
This establishes a connection between the namespaces and external hosts. To fetch and display packets from the external host, you will add Network Address Translation (NAT) functionality to your host by typing the command:
$ iptables -t nat -A POSTROUTING -s 192.168.15.0/24 -j MASQUERADE
The NAT translator will send packets to the Local Area Network (LAN) using its own name and address. The destination network will then assume that requests are coming from the host but not the namespace. If the LAN is connected to the internet, we will add a default gateway to establish a connection between the host and the internet, using the command:
$ ip netns exec blue iproute add default via 192.168.15.5
Now, we can connect an external host to the namespace by adding a port that forwards traffic coming into the host’s incoming port to a namespace’s port:
$ iptables -t nat -A PREROUTING --dport 80 -to-destination 192.168.15.2:80 -j DNAT
Docker Networking Deep Dive
As outlined in the first section of this article, by default, Docker creates 3 types of networks.
- In a None network, containers are detached from their hosts and networks. Even containers sharing a host with a none network cannot communicate with each other.
- A Host network offers no isolation between containers and their hosts. If you have a web application container listening on port 80, it will be accessible from the host’s port 80 without requiring the publishing or mapping of ports. Two processes in this network cannot be active within the same host network since they share ports.
- The Bridge network is the default network assigned to Docker containers and processes. This network assigns IP addresses to all attached containers, allowing for communication. As soon as a container is initiated, Docker attaches it to the default Bridge network. Docker knows this network as bridge, but the hostnames this network docker0. This network is assigned the IP address 172.17.0.1.
Whenever a container is initiated, Docker automatically creates and assigns it a Namespace. You can check for default networks in your host using the command:
$ ip netns
To list the namespaces attached to a container, use the command:
$ docker inspect
When attaching containers to the bridge network, Docker uses a Virtual Ethernet Interface. To list all interfaces within a host, run the command:
$ ip link
To display interfaces attached to a specific namespace:
$ ip -n <namespace-ID> link
To check on the IP address assigned to a namespace:
$ ip -n <namespace-ID> addr
Docker goes through the namespace creation process every time a container is initiated. The interfaces of virtual ethernet pairs are paired up using odd and even numbers.
To enable external access to your namespaces, you will need to map/publish your ports using the command:
$ docker run -p 8080:80 nginx
With this command, the Nginx server is now accessible from the host’s IP address at port 8080. To access this server from an external host, use the following command:
$ curl http://192.168.1.0:8080
Docker can now forward traffic to the container port by creating a NAT rule: which appends rules to the IP routing table and changes the destination port from 8080 to 80. This is what the NAT table for the above host will look like:
iptables \
-t nat \
-A DOCKER \
-j NAT \
--dport 8080 \
--to-destination 172.17.0.3:80
You can view these settings by running the iptables
command:
$ iptables -nvL -t nat
Research Questions & Conclusion
This concludes the Networking chapter of the DCA certification exam. To test your knowledge, it is strongly recommended that you access research questions of all core concepts covered in the coursework and a test to prepare you for the exam. You can also send your feedback to the course developers, whether you have feedback or would like something changed within the course.
Here is a quick quiz to help you assess your knowledge. Leave your answers in the comments below and tag us back.
Quick Tip – Questions below may include a mix of DOMC and MCQ types.
1. What IPTables chains does Docker modify to configure port mapping on a host?
[A] INPUT
[B] FORWARD
[C] DOCKER
[D] OUTPUT
2. Service Discovery allows containers and Services to locate and communicate with each other with their names.
[A] True
[B] False
3. What is the command to create an overlay network driver called my-overlay with subnet 10.15.0.0/16 ?
[A] docker network create my-overlay
[B] docker network create --driver overlay --subnet 10.15.0.0/16 my-overlay
[C] docker network create -d overlay -subnet 10.15.0.0/16
[D] docker network create overlay my-overlay
4. The built-in DNS server in Docker always runs at IP address …
[A] 127.0.0.11
[B] 127.0.0.1
[C] 172.17.0.3
[D] 172.17.0.1
5. The … network disables all networking. Usually used in conjunction with a custom network driver
[A] host
[B] bridge
[C] overlay
[D] none
6. Host is the default network a container gets attached to.
[A] True
[B] False
7. What is the command to connect a running container with name myapp to the existing bridge network my-net?
[A] docker container connect myapp my-net
[B] docker container attach myapp my-net
[C] docker network connect my-net myapp
[D] docker network connect myapp my-net
8. If you use the … network mode for a container, that container’s network stack is not isolated from the Docker host (the container shares the host’s networking namespace), and the container does not get its own IP-address allocated
[A] host
[B] bridge
[C] overlay
[D] NAT
9. Docker requires an external DNS server to be configured during installation to help the containers resolve each other using the container name.
[A] True
[B] False
By following this study guide till this part of the series, you have prepared yourself to handle all Docker Engine Networking questions and practical scenarios – and are of course a step closer to pass the DCA certification test.
On KodeKloud, you also get a learning path with recommendations, sample questions and tips for clearing the DCA exam. Once you are done with this section, you can head over to the research questions and practice test sections to examine your understanding of Docker Engine Security.
Responses