Dive Into Docker Networking

DockerDockerBeginner
Practice Now

Introduction

In this lab, we will explore advanced Docker networking concepts, building upon the fundamentals of Docker networking. We'll dive deeper into the three main network modes: Bridge, Host, and None. We'll also learn how to create custom networks, connect containers across different networks, and understand the implications of each network mode on container communication and isolation. This hands-on experience will provide you with a solid foundation in Docker networking practices.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL docker(("`Docker`")) -.-> docker/ContainerOperationsGroup(["`Container Operations`"]) docker(("`Docker`")) -.-> docker/NetworkOperationsGroup(["`Network Operations`"]) docker/ContainerOperationsGroup -.-> docker/exec("`Execute Command in Container`") docker/ContainerOperationsGroup -.-> docker/run("`Run a Container`") docker/ContainerOperationsGroup -.-> docker/inspect("`Inspect Container`") docker/NetworkOperationsGroup -.-> docker/network("`Manage Networks`") subgraph Lab Skills docker/exec -.-> lab-389047{{"`Dive Into Docker Networking`"}} docker/run -.-> lab-389047{{"`Dive Into Docker Networking`"}} docker/inspect -.-> lab-389047{{"`Dive Into Docker Networking`"}} docker/network -.-> lab-389047{{"`Dive Into Docker Networking`"}} end

Custom Bridge Networks

While Docker provides a default bridge network, creating custom bridge networks offers better isolation and control over inter-container communication.

  1. First, let's see the current list of Docker networks:
docker network ls

You should see something like this:

NETWORK ID     NAME      DRIVER    SCOPE
296d1b460b17   bridge    bridge    local
91199fc6ad2e   host      host      local
1078d2c781b6   none      null      local
  1. Now, let's create a custom bridge network:
docker network create my-custom-bridge
  1. List all Docker networks again to verify the creation:
docker network ls

You should now see my-custom-bridge in the output:

NETWORK ID     NAME               DRIVER    SCOPE
296d1b460b17   bridge             bridge    local
91199fc6ad2e   host               host      local
7215f99d0080   my-custom-bridge   bridge    local
1078d2c781b6   none               null      local
  1. Launch two containers on the custom bridge network and install ping:
docker run --network=my-custom-bridge --name container1 -d nginx
docker run --network=my-custom-bridge --name container2 -d nginx

Now, let's install the ping utility in both containers. We need to do this because the default Nginx image doesn't include ping:

docker exec container1 apt-get update && docker exec container1 apt-get install -y iputils-ping
docker exec container2 apt-get update && docker exec container2 apt-get install -y iputils-ping
  1. Test the communication between the containers:
docker exec container1 ping -c 4 container2

You should see successful ping responses, demonstrating that containers on the same custom bridge network can communicate using container names. This works because Docker's built-in DNS resolves container names to their IP addresses within the same network.

If you don't see successful pings, make sure both containers are running (docker ps) and that you've correctly installed the ping utility.

Connecting Containers Across Networks

Docker allows containers to be connected to multiple networks, enabling communication between containers on different networks. This is particularly useful when you want to isolate certain containers but still allow specific communications between them.

  1. First, let's create a second custom bridge network:
docker network create my-second-bridge
  1. Verify the network creation:
docker network ls

You should now see both custom networks:

NETWORK ID     NAME               DRIVER    SCOPE
296d1b460b17   bridge             bridge    local
91199fc6ad2e   host               host      local
7215f99d0080   my-custom-bridge   bridge    local
8a15f99d0081   my-second-bridge   bridge    local
1078d2c781b6   none               null      local
  1. Connect container2 to the new network:
docker network connect my-second-bridge container2

This command adds container2 to my-second-bridge network while keeping it connected to my-custom-bridge.

  1. Create a new container on the second network:
docker run --network=my-second-bridge --name container3 -d nginx
docker exec container3 apt-get update && docker exec container3 apt-get install -y iputils-ping
  1. Test communication between all containers:
docker exec container1 ping -c 2 container2
docker exec container1 ping -c 2 container3
docker exec container2 ping -c 2 container3

Note the results:

  • container1 can communicate with container2 (they're on the same network)
  • container1 cannot communicate with container3 (they're on different networks)
  • container2 can communicate with both container1 and container3 (it's connected to both networks)

If container1 could ping container3, something would be wrong with your network isolation.

Host Network Mode

Host network mode removes network isolation between the container and the Docker host, allowing the container to use the host's network directly. This can be useful for maximizing performance, but it comes with security implications as it reduces isolation.

  1. Create a container using host network mode:
docker run --network host --name host-container -d nginx
  1. Verify the current network list:
docker network ls

You won't see a new network for this container because it's using the host's network directly.

  1. Verify that the container is using the host's network:
docker inspect --format '{{.HostConfig.NetworkMode}}' host-container

This should output host.

  1. Try to access the Nginx default page from your host machine:
curl localhost:80

You should see the Nginx welcome page. This works because the container is using the host's network, and Nginx is listening on port 80 of the host's network interface.

Note: If you already have a service running on port 80 of your host machine, this step might fail. In that case, you'd need to stop the existing service first.

None Network Mode

The 'none' network mode creates containers with no network interface, completely isolating them from the network. This is useful for maximum security isolation, but it means the container can't communicate over the network at all.

  1. Create a container with no network:
docker run --network none --name isolated-container -d alpine sleep infinity
  1. Verify the current network list:
docker network ls

You won't see a new network for this container because it's not connected to any network.

  1. Verify that the container has no network interface:
docker exec isolated-container ip addr

You should only see the loopback interface (lo). There won't be any eth0 or other network interfaces.

  1. Try to ping Google from the isolated container:
docker exec isolated-container ping -c 2 google.com

This should fail with a "Network is unreachable" error, as the container has no network access.

Network Aliases and Service Discovery

Docker networks support service discovery using network aliases, which can be useful for creating resilient, scalable applications. This feature allows multiple containers to respond to the same DNS name, enabling basic load balancing.

  1. Create a new bridge network for this exercise:
docker network create service-network
  1. Verify the network creation:
docker network ls

You should see service-network in the list.

  1. Create two containers with the same network alias:
docker run -d --network service-network --network-alias myservice --name service1 nginx
docker run -d --network service-network --network-alias myservice --name service2 nginx
  1. Create a client container and use nslookup to resolve the service:
docker run --rm --network service-network appropriate/curl nslookup myservice

You should see both container IPs returned, demonstrating that Docker's embedded DNS server is load-balancing between the two containers.

  1. Test accessing the service multiple times:
for i in {1..4}; do docker run --rm --network service-network appropriate/curl curl -s http://myservice; done

You should see responses from both containers, demonstrating basic load balancing. The Docker DNS server will alternate between the two IP addresses when resolving myservice.

Summary

In this advanced Docker networking lab, we explored several key concepts:

  1. Custom bridge networks for improved container isolation and communication
  2. Connecting containers across multiple networks
  3. Host network mode for direct access to the host's network stack
  4. None network mode for complete network isolation
  5. Network aliases and service discovery for building scalable applications

These advanced networking features in Docker provide powerful tools for designing complex, multi-container applications with precise control over inter-container communication and isolation. Understanding these concepts is crucial for designing efficient, secure, and scalable containerized applications.

Remember that while Docker networking offers great flexibility, it's important to consider security implications when designing your container network architecture. Always follow the principle of least privilege, only exposing the necessary ports and services.

As you continue working with Docker, you'll find these networking concepts invaluable in orchestrating complex applications and microservices architectures. Practice these concepts regularly to become proficient in managing Docker networks effectively.

Other Docker Tutorials you may like