On the last article, we defined all the networking types that you can use with Docker ( Docker networking types ), we explained them and we gave some practical examples but we didn’t really discuss how two containers on the same docker network communicate to each other and that’s why i am here today! So on this article as i said we will go deeply on how containers on docker can communicate to each other and we will even talk about the system component taking care of this communication! Happy learning 😀
CONTAINERS COMMUNICATION IN DOCKER
The question here is very simple: How does two containers on the same bridge network one to another?
In the above diagram, two containers running on the same host connect via the docker0 bridge. If 172.17.0.6 (on the left-hand side) wants to send a request to 172.17.0.7 (the one on the right-hand side), the packets move as follows:
- A packet leaves the container via eth0 and lands on the corresponding vethxxx interface.
- The vethxxx interface connects to the vethyyy interface via the docker0 bridge.
- The docker0 bridge forwards the packet to the vethyyy interface.
- The packet moves to the eth0 interface within the destination container.
We can see this in action by using ping and tcpdump. Create two containers and inspect their network configuration with ip addr and ip route. The default route for each container is via the eth0 interface.
Ping one container from the other, and let the command run so that we can inspect the traffic. Run tcpdump on the docker0 bridge on the host machine. You will see in the output that the traffic moves between the two containers via the docker0 bridge.
CONTAINERS COMMUNICATION BETWEEN HOSTS
So far we’ve discussed scenarios in which containers communicate within a single host.
While interesting, real-world applications require communication between containers running on different hosts.
Cross-host networking usually uses an overlay network, which builds a mesh between hosts and employs a large block of IP addresses within that mesh. The network driver tracks which addresses are on which host and shuttles packets between the hosts as necessary for inter-container communication.
Overlay networks can be encrypted or unencrypted. Unencrypted networks are acceptable for environments in which all of the hosts are within the same LAN, but because overlay networks enable communication between hosts across the Internet, consider the security requirements when choosing a network driver. If the packets traverse a network that you don’t control, encryption is a better choice.
The overlay network functionality built into Docker is called Swarm. When you connect a host to a swarm, the Docker engine on each host handles communication and routing between the hosts.
Other overlay networks exist, such as IPVLAN, VxLAN, and MACVLAN. More solutions are available for Kubernetes.
For more information on pure-Docker networking implementations for cross-host networking (including Swarm mode and
libnetwork), please refer to the documentation available at the Docker website.
Netfilter and iptables rules
On the last two sections, we looked at how Docker handles communication between containers. On a Linux host, the component which handles this is called Netfilter, or more commonly by the command used to configure it: iptables.
This component manages the rules that define network communication for the Linux kernel. These rules permit, deny, route, modify, and forward packets. It organizes The headers of these rules into tables according to their purpose.
The Filter Table
Rules in the Filter table control if a packet is allowed or denied. Packets which are allowed are forwarded whereas packets which are denied are either rejected or silently dropped.
The NAT Table
These rules control network address translation. They modify the source or destination address for the packet, changing how the kernel routes the packet.
The Mangle Table
The headers of packets which go through this table are altered, changing the way the packet behaves. Netfilter might shorten the TTL, redirect it to a different address, or
change the number of network hops.
This table marks packets to bypass the iptables stateful connection tracking.
This table sets the SELinux security context marks on packets. Setting the marks affects how SELinux (or systems that can interpret SELinux security contexts) handle the packets. The rules in this table set marks on a per-packet or per-connection basis.
Netfilter organizes the rules in a table into chains. Chains are the means by which Netfilter hooks in the kernel intercept packets as they move through processing and packets flow through one or more chains and exit when they match a rule.
A rule defines a set of conditions, and if the packet matches those conditions, an action is taken.
The universe of actions is diverse, but examples include:
- Block all connections originating from a specific IP address.
- Block connections to a network interface.
- Allow all HTTP/HTTPS connections.
- Block connections to specific ports.
The action that a rule takes is called a target, and represents the decision to accept, drop, or forward the packet.
The system comes with five default chains that match different phases of a packet’s journey through processing: PREROUTING, INPUT, FORWARD, OUTPUT, and POSTROUTING. Users and programs may create additional chains and inject rules into the system chains to forward packets to a custom chain for continued processing. This architecture allows the Netfilter configuration to follow a logical structure, with chains representing groups of related rules.
This article is going too long and i don’t want to ruin your learning path, if you have more free time and you want to learn more about Netfilter, you can follow this link:
This is the end of our article, we can conclude that Docker creates several chains, and it is the actions of these chains that handle communication between containers, the host, and the outside world. On our next article, we will try to use all what we learned to containerize a real complex application using Docker.