How do Docker containers communicate?
In the rapidly evolving landscape of modern software development, Docker containers have emerged as a transformative force that enables the creation of modular, scalable and portable applications. A key aspect of this paradigm is container communication, i.e. how containers communicate with each other within an orchestrated environment. This article looks at the intricacies of Docker container communication, explore the mechanisms that facilitate collaboration, data exchange and seamless operation of complex, interconnected systems.
Different types of communication between containers
Containers to www
Even if containers are isolated, they still need to communicate with the outside world. For example, the container must connect to a remote database or call a REST api on another host. Sending http requests from a Docker container works immediately. It is not necessary to change the code to make it work inside the container.
Container to Docker host
The Docker host is the computer on which the container is running. By default, a container cannot communicate with the host. The code that runs inside the container must be changed.In order for a Docker container to communicate with the host computer, we need to replace localhost with host.docker.internal
. Docker converts this variable into the IP address of the host computer.
Container-to-container communication
Containers may need to communicate with other containers if, for example, they need to process a database in another container or send a request to a microservice installed in another container.
A simple solution is to use docker container inspect
to determine the IP address of the target container and use it in the request. This works, but has the disadvantage that if the container to which the request is sent is shut down or crashes and a new container is created, the newly created container will have a different IP.
A better solution is to create a network and add all containers that need to communicate with each other to this network with the —network tag. Once the containers have been created with the tag -network. We can access other containers by using their names in the request as long as they are on the same network.
What are networks and why are they needed?
Docker networks are a key feature of the Docker platform and enable communication between Docker containers and between containers and the outside world. They provide a way to isolate and control communication between different parts of a distributed application.
Here are some important points about Docker networks and their use:
- Isolation: Docker containers are designed to be isolated from each other. Each container has its own file system, its own processes and its own network stack. Docker networking allows you to define an area where containers can communicate to isolate them from the rest of the system.
- Communication between containers: In an application with multiple containers, the containers often need to communicate with each other. Docker networks allow containers to recognise each other by container name or service name and communicate with each other instead of relying on specific IP addresses.
- Standard networks: Three default networks are provided when Docker is installed: bridge, host and none. The bridge network is the default and is used for communication between containers on the same host.
- Custom networks: Docker allows you to create custom networks that give you more control over how containers connect and communicate. You can specify the network type (bridge, overlay, MacVlan, etc.) and define custom subnets and gateway configurations.
- External communication: Docker networks also facilitate communication between containers and the outside world. You can share the ports of a container and map them to the ports of the host system so that external applications can interact with the containerized services.
- Service Discovery: Docker networks often play a role in service discovery in a containerized environment. Containers can be referenced within the network by their container name or their service name, which facilitates dynamic scaling and management of services.
- Security: Networks help implement security measures by controlling the flow of traffic between containers. Using network policies, you can set rules for communication between containers and enforce security best practices.
- Overlay networks for Swarm mode: In Docker Swarm, Docker’s native clustering and orchestration solution, overlay networks are used to enable communication between containers across multiple nodes in a swarm.
How does Docker resolve IP addresses?
Docker uses a built-in DNS server to provide name resolution for containers. When containers are connected to a Docker network, they can communicate with each other using the container name as the hostname. Docker’s DNS server resolves these names to the IP address of the respective container.
Here is a brief overview of how Docker resolves IP addresses:
- Container names: When you start a container, it is given a unique name within the Docker network it is connected to. This name can be used as a hostname for communication between containers. For example, if you have a container with the name “web_app” and another with the name “database”,” the “web_app” container can communicate with the “database” container via the hostname “database”
- Docker DNS Server: Docker includes a DNS server that automatically assigns DNS names to containers when they are started. This DNS server normally listens on the default DNS port (normally 127.0.0.11) and resolves the container names to their IP addresses within the Docker network.
- Container discovery: When one container wants to communicate with another by its name (e.g. via an API request or a database connection), Docker’s DNS server resolves the hostname to the IP address of the corresponding container. This allows containers to communicate with each other by addressing each other using easily recognizable names instead of dealing with explicit IP addresses.
- Custom networks: When you create a custom Docker network, DNS resolution is specific to that network. Containers within the same network can resolve each other’s names, but containers on different networks cannot resolve each other’s names unless there is a network connection between them.
It is important to know that this DNS resolution is limited to the Docker networks. Containers on the same network can resolve each other’s names, but this resolution does not extend to the host machine or external network unless explicit port mappings are configured.
Different Docker network drivers
Docker supports different network drivers that allow you to create different types of networks for different use cases. Each network driver in Docker offers specific features and capabilities. Here are some of the most commonly used Docker network drivers:
- Bridge driver (bridge): This is the default network driver for Docker. If you create a container without specifying a network, it will be connected to the bridge network. Containers that are connected to the bridge network can communicate with each other and also communicate with the host computer. By default, however, they are isolated from the external network. This driver uses a private internal IP address range.
docker network create my_bridge_network
- Host driver (Host): When you use the host network driver, a container shares the network namespace with the host. This means that the container does not have its own isolated network stack, but uses the host’s network directly. This can be useful for scenarios where you want to avoid the network overhead caused by the bridge network.
docker run --network host my_container_
- Overlay driver (overlay): The overlay network driver is mainly used in Docker Swarm mode, Docker’s native clustering and orchestration solution. It enables communication between containers across multiple nodes in a swarm. Containers on different nodes can communicate seamlessly with each other as if they were on the same network.
docker network create --driver=overlay my_overlay_network
- Macvlan driver (macvlan):This driver allows Docker containers to be assigned MAC addresses from the underlying physical network. Each container has its own unique MAC address and IP address in the physical network. This is useful if you want containers to appear as physical devices on the network.
docker network create --driver=macvlan -- subnet=192.168.1.0/24 --gateway=192.168.1.1 -o parent=eth0 my_macvlan_network
- None Driver (none):The use of the none driver means that the container has no network access. It is completely isolated. This can be useful in situations where you want to run a container without any network connection.
docker run --network none my_container_
- Custom bridge networks: You can create custom bridge networks with specific subnets, gateways and other configurations to isolate containers and control their communication.
docker network create --driver=bridge -- subnet=172.18.0.0/16 --gateway=172.18.0.1 my_custom_bridge_network_
The choice of network driver depends on the specific requirements of your application and the network architecture you want to implement.
Key docker network commands
- Create a Network:
docker network create my_network
This command creates a new user-defined bridge network named “my_network.” You can specify additional options such as the subnet, gateway, and driver. - List Networks:
docker network ls
Lists all networks on the host, including their ID, name, driver, and scope. - Inspect a Network:
docker network inspect my_network
Shows detailed information about a specific network, including its configuration and connected containers. - Connect a Container to a Network:
docker network connect my_network my_container
Connects an existing container (identified by its name or ID) to the specified network. - Disconnect a Container from a Network:
docker network disconnect my_network my_container
Disconnects a container from a network. - Remove a Network:
docker networkrmmy_network
Removes a network. Make sure there are no containers connected to the network before attempting removal. - Inspect Container’s Network Settings:
docker inspect --format'{{ .NetworkSettings.Networks.my_network.IPAddress }}'my_container
Displays the IP address assigned to a container within a specific network. Replace “my_network” with the network name. - List Processes Attached to a Network:
docker network inspect --format'{{range $key, $value := .Containers}}{{$key}} {{end}}'my_network
Lists container IDs attached to a specific network. - List Docker Daemon Network Settings:
docker info
Shows information about the Docker daemon, including network-related settings. - Create an Overlay Network (Swarm Mode):
docker network create --driver overlay my_overlay_network
Creates an overlay network in Docker Swarm mode.
Docker compose networks
Docker Compose is a tool for defining and running Docker applications with multiple containers. It uses a YAML file to configure the application’s services, networks and volumes so that you can easily define complex application structures. When it comes to networks in Docker Compose, you can define custom networks to connect your services.
Here are some important aspects of using Docker Compose with networks:
- Defining Networks in Docker Compose: In your
docker-compose.yml
file, you can define custom networks under thenetworks
key. For example:
version:3
services:
web:
image: nginx
networks:
-frontend
database:
image: postgres
networks:
-backend
networks:
frontend:
backend:
In this example, two custom networks, “frontend” and “backend,” are defined. The “web” service is connected to the “frontend” network, and the “database” service is connected to the “backend” network.
- Default Networks:By default, Docker Compose creates a default network for your application to which all services are connected. The default network is named with the project name (the name of the directory where the “docker-compose.yml” file is located), followed by the default suffix “default” You can override the default network name by specifying the”project name” in the “docker-compose.yml” file.
- Connecting Services to Multiple Networks:You can connect a service to multiple networks by listing the network names under the
networks
key for that service. For example:
version: '3'
services:
app:
image: my_app
networks:
-frontend
-backend
networks:
frontend:
backend:
In this example, the “app” service is connected to both the “frontend” and “backend” networks.
- External Networks: You can also connect services to external networks that are created outside of the Docker Compose file. Specify the external network name under the
external
key. For example:
version: '3'
services:
app:
image: my_app
networks:
-external_network
networks:
external_network:
external: true
In this case, the “app” service is connected to an external network named “external_network.”
- Network Aliases:You can assign aliases to services within a network. This can be useful for simplifying service discovery. For example:
version: '3'
services:
app:
image: my_app
networks:
-frontend
aliases:
-myapp
networks:
frontend:
In this example, the “app” service has an alias “myapp” within the “frontend” network.
- Network Scopes:Networks defined in Docker Compose can have different scopes, such as “local” or “global” Local networks are limited to a single Compose file, while global networks are created outside of a specific Compose file and can be shared by multiple Compose projects.