Docker containers allow applications to be run in an isolated environment. But how can you make two applications able to communicate with each other? You can run them both in the same containers, but this method is not scalable. Because in the future, you may need to make three, four, or even a dozen applications send messages to each other. A better way is to connect containers through the same network. This is where Docker networks come into play. Let's look at Docker networks and how we can connect containers using them.
Docker network
Docker network is a technology that allows containers to communicate with each other and external resources through the network. It works with the help of network drivers. There are several types of network drivers you can use to launch containers. To start working with networks, here are some common types of drivers you must be aware of:
-
bridge: The default network driver. Bridge networks are isolated from the Docker host. You can create a bridge network with thedocker network create <network-name>command. -
host: A host networks is used for standalone containers. It removes network isolation between the container and the Docker host to use the host’s networking configurations directly. That is, the container doesn't get its own IP address. It uses the host's address. Docker automatically creates a host network and you can't create more. -
overlay: Overlay networks connect multiple Docker daemons and enable swarm services to communicate with each other. You can also use overlay networks to facilitate communication between a swarm service and a standalone container, or between two standalone containers on different Docker daemons. This strategy removes the need to do OS-level routing between containers. You can create an overlay network via adocker network create -d overlay --attachable <network-name>command. Note, that you need to initialize a swarm or join a Docker host to an existing swarm. You'll learn about the swarm later on.
You can find the network available to you using the docker network ls command.
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
7614b36c62f8 bridge bridge local
817d58bc7ecb host host local
cf2953a94052 none null local
By default, you'll have above three options with a freshly installed Docker. The none network allows you to disable networking. In this case, your container won't have access to the external network and other containers. Usually, this configuration is used with custom network drivers. You have learned about some common network types and how to create such networks. Now, let's explore their properties.
Inspecting networks
Docker lets you inspect networks by using the docker network inspect <network-name> command. But what output does it give? To find the answer, create a network named hs-bridge and inspect it with the docker network inspect hs-bridge command.
[
{
"Name": "hs-bridge",
"Id": "ac6211a0597ae3da32fbba251b1a141df3bf88b8e2a31afdf8ea3a84b56659fb",
"Created": "2022-11-03T15:55:46.780000757Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.19.0.0/16",
"Gateway": "172.19.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
Here, you need to focus on two important properties. The first is IPAM(IP Address Management). IPAM includes subnet and default gateway. In this case, based on the values of subnet the containers will receive IP addresses in the range of 172.19.0.2 - 172.19.255.254 available IPs.
The other property worth mentioning is Containers. It shows a list of containers attached to the given network. In this case, it doesn't represent any information since there are no containers attached to this network. If you had a container attached to this network, the output would include something similar to the snippet below.
"Containers": {
"dfeffe32841f8a630095a9701581ff791302f1cf0533131fbd8464b7344c622c": {
"Name": "hs-ubuntu",
"EndpointID": "6f1a9ced6bb3c10f232d86b7081e759b9658b478ba68d45c66547f9eade5d9f2",
"MacAddress": "02:42:ac:13:00:02",
"IPv4Address": "172.19.0.2/16",
"IPv6Address": ""
}
}
Other networks have similar properties and you can use the same command to inspect them. Pay special attention to the IPAM section. The host network you have by default won't show any information since containers operate in the host machine network. It will look like this:
"IPAM": {
"Driver": "default",
"Options": null,
"Config": []
}Adding containers to a network
When you run a container without specifying the network, Docker automatically connects it to the default bridge network that you saw in the docker network ls output. If you want to specify another network you have several options.
The first approach is creating a container by specifying the network it will connect to when you run it. Assume you have an image named ubuntu:v1. You can use the following command to create a container without running it:
$ docker create --name hs-ubuntu-v1 --network hs-bridge ubuntu:v1
On the first line, you set the container name. Then the network you want the container to connect to while running. And finally, the image Docker should use to start the container. After running this command, check the container's network using the docker ps -a --format '{{ .ID }} {{ .Names }} {{ json .Networks }}' command. It lists all containers in the given format. Your result will look similar to the following snippet:
$ docker ps -a --format '{{ .ID }} {{ .Names }} {{ json .Networks }}'
0f3f713d745a ubuntu "bridge"
65fdf7f62a91 goofy_keller "bridge"
0417c27f8c28 sweet_bhaskara "bridge"
ee6381ad2782 hs-ubuntu-v1 "hs-bridge"
As you see, the hs-ubuntu container's network is hs-bridge. When you run this container it will run in the specified network.
The next approach is running a container specifying the desired network. To do that, use the --network <network-name> command when running the container setting like this:
$ docker run -d -it --name hs-ubuntu-v2 --network hs-bridge ubuntu:v1
Now use the above mentioned docker ps -a --format '{{ .ID }} {{ .Names }} {{ json .Networks }}' command to check the created container network, it will be hs-bridge.
Another approach is to attach an already-running container to a network. This is another way to specify the network for containers. Use the following command on a running container:
$ docker network connect <network-name> <container-name>
Also, you can disconnect a container from the network by using the disconnect command instead of connect.
$ docker network disconnect <network-name> <container-name>How to choose a network type?
You know about the different docker network types. Now, let's look at how you can choose which network type to use.
bridge: This network is typically used when your applications run in standalone containers and you want them to communicate on the same host.host: This network offers better performance when making a large number of requests with different ports. It doesn't require NAT(Network address translation) which saves time.overlay: Such networks are useful when you want containers on different hosts to communicate with one another. Docker manages to route itself and provides secure communication between containers when encryption is enabled.
If these options don't satisfy your needs, you can use third-party network plugins available on Docker Hub. You can find more information about this in the official Docker documentation.
Conclusion
This topic introduced you to the idea of docker networking. You now have a basic understanding of common network types and when to use them. You know how to create different networks, inspect them, and understand the different approaches to connecting containers to those networks. To summarize:
- Docker networking allows containers to communicate with one another and external resources.
- The three common types of docker network drivers are;
bridge,host, andoverlay. - Docker lets you inspect networks using the
docker network inspect <network-name>command. - You can add containers to a network by specifying the network when the container is created or when the container is run.
- You can also attach an already-running container to a network.