How to test connectivity between Docker containers

DockerDockerBeginner
Practice Now

Introduction

Docker containers have become a fundamental part of modern application development and deployment. When working with multiple containers, ensuring proper connectivity between them is crucial for your applications to function correctly.

In this lab, you will learn how to verify and troubleshoot connectivity between Docker containers. We will start with basic Docker container concepts, set up containers for testing, and then explore various methods to check and diagnose network connections between containers.

By the end of this tutorial, you will be able to confidently test, verify, and resolve connectivity issues in your containerized applications.

This Lab requires an internet connection for learning, thus only Pro users can start the VM. Upgrade your account to Pro.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL docker(("Docker")) -.-> docker/ContainerOperationsGroup(["Container Operations"]) docker(("Docker")) -.-> docker/NetworkOperationsGroup(["Network Operations"]) docker/ContainerOperationsGroup -.-> docker/run("Run a Container") docker/ContainerOperationsGroup -.-> docker/ls("List Containers") docker/ContainerOperationsGroup -.-> docker/ps("List Running Containers") docker/ContainerOperationsGroup -.-> docker/exec("Execute Command in Container") docker/ContainerOperationsGroup -.-> docker/inspect("Inspect Container") docker/NetworkOperationsGroup -.-> docker/network("Manage Networks") subgraph Lab Skills docker/run -.-> lab-411613{{"How to test connectivity between Docker containers"}} docker/ls -.-> lab-411613{{"How to test connectivity between Docker containers"}} docker/ps -.-> lab-411613{{"How to test connectivity between Docker containers"}} docker/exec -.-> lab-411613{{"How to test connectivity between Docker containers"}} docker/inspect -.-> lab-411613{{"How to test connectivity between Docker containers"}} docker/network -.-> lab-411613{{"How to test connectivity between Docker containers"}} end

Setting Up Docker Containers for Testing

Before we can test connectivity between containers, we need to create some containers to work with. In this step, we will set up two simple Docker containers and learn about basic Docker commands.

Understanding Docker Containers

Docker containers are lightweight, standalone packages that include everything needed to run an application: code, runtime, system tools, libraries, and settings. Containers share the host machine's OS kernel but run in isolated environments.

Creating Test Containers

Let's start by creating two simple containers based on the Ubuntu image. We will use these containers throughout the lab to test connectivity between them.

First, let's create our first container:

docker run -d --name container1 ubuntu:22.04 sleep infinity

Now, let's create the second container:

docker run -d --name container2 ubuntu:22.04 sleep infinity
run containers

The command parameters explained:

  • -d: Runs the container in detached mode (in the background)
  • --name: Assigns a name to the container
  • ubuntu:22.04: The Docker image to use (Ubuntu version 22.04)
  • sleep infinity: A command that keeps the container running indefinitely

Verifying Our Containers Are Running

To check if our containers are running properly, use the following command:

docker ps

You should see output similar to this:

CONTAINER ID   IMAGE          COMMAND            CREATED         STATUS         PORTS     NAMES
f8d97c645cce   ubuntu:22.04   "sleep infinity"   5 seconds ago   Up 4 seconds             container2
a2c516a57cb8   ubuntu:22.04   "sleep infinity"   18 seconds ago  Up 17 seconds            container1

If you don't see both containers listed, they might not have started correctly. You can try creating them again.

Installing Network Tools

By default, the Ubuntu container image is very minimal and doesn't include networking tools that we'll need. Let's install these tools in both containers:

For container1:

docker exec container1 apt-get update
docker exec container1 apt-get install -y iputils-ping net-tools iproute2 curl

For container2:

docker exec container2 apt-get update
docker exec container2 apt-get install -y iputils-ping net-tools iproute2 curl

These commands:

  1. Use docker exec to run commands inside a running container
  2. Update the package list with apt-get update
  3. Install networking tools (iputils-ping for ping, net-tools for netstat, iproute2 for ip commands, and curl)

Now our containers are ready for connectivity testing in the next steps.

Understanding Docker Networks

Docker containers communicate with each other through networks. Understanding how Docker networking works is essential for testing and troubleshooting connectivity between containers.

Docker Network Basics

When you install Docker, it creates several default networks automatically. The most commonly used ones are:

  • bridge: The default network that containers connect to if no network is specified
  • host: Containers use the host's network directly (no isolation)
  • none: Containers have no network access

Let's examine the networks on your system:

docker network ls

You should see output similar to:

NETWORK ID     NAME      DRIVER    SCOPE
1b95853bf83b   bridge    bridge    local
91199fc6ad2e   host      host      local
1078d2c781b6   none      null      local

Understanding the Default Bridge Network

By default, both of our containers are connected to the default bridge network. Let's examine this network:

docker network inspect bridge

This command displays detailed information about the bridge network, including the containers connected to it and their IP addresses. In the output, look for the "Containers" section to see both container1 and container2 listed with their IP addresses.

Finding Container IP Addresses

To work with container connectivity, we need to know the IP addresses assigned to our containers. There are several ways to find this information:

Using docker inspect:

docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container1

Or from inside the container:

docker exec container1 hostname -i

Take note of the IP addresses for both containers:

docker exec container1 hostname -i
docker exec container2 hostname -i

The output will show the IP address for each container, which typically starts with 172.17.0.x on the default bridge network.

Creating a Custom Docker Network

While the default bridge network allows container communication, creating a custom network provides better isolation and built-in DNS resolution (containers can reach each other by name instead of IP).

Let's create a custom bridge network:

docker network create --driver bridge my-network

Now, let's connect our existing containers to this new network:

docker network connect my-network container1
docker network connect my-network container2

We can verify our containers are connected to the new network:

docker network inspect my-network

Now our containers are connected to both the default bridge network and our custom my-network. In the next step, we'll test connectivity between them.

Testing Basic Connectivity Between Containers

Now that we have our containers set up and connected to networks, we can test the connectivity between them. We'll use several methods to verify that the containers can communicate with each other.

Using Ping to Test Connectivity

The simplest way to test basic network connectivity is using the ping command, which sends ICMP echo requests to the target host.

Let's ping from container1 to container2 using IP address:

## First, get container2's IP address
CONTAINER2_IP=$(docker exec container2 hostname -i)
echo "Container2 IP: $CONTAINER2_IP"

## Get the first IP address of the CONTAINER2_IP
CONTAINER2_IP=$(echo $CONTAINER2_IP | cut -d' ' -f1)
echo "Container2 IP: $CONTAINER2_IP"

## Now ping from container1 to container2
docker exec container1 ping -c 4 $CONTAINER2_IP

You should see output similar to:

PING 172.17.0.3 (172.17.0.3): 56 data bytes
64 bytes from 172.17.0.3: icmp_seq=0 ttl=64 time=0.095 ms
64 bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=0.067 ms
64 bytes from 172.17.0.3: icmp_seq=2 ttl=64 time=0.090 ms
64 bytes from 172.17.0.3: icmp_seq=3 ttl=64 time=0.087 ms
--- 172.17.0.3 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.067/0.085/0.095/0.000 ms

Testing DNS Resolution

One advantage of custom Docker networks is that they provide automatic DNS resolution, allowing containers to reach each other by name.

Let's test DNS resolution by pinging the container by name:

docker exec container1 ping -c 4 container2

This should work because both containers are on our custom my-network, which provides DNS resolution. You should see ping responses similar to the previous test, but using the container name instead of IP.

Using curl to Test HTTP Connectivity

For applications running web services, we often need to test HTTP connectivity. Let's set up a simple HTTP server in container2 and test connectivity to it from container1.

First, let's start a basic HTTP server in container2:

docker exec container2 apt-get install -y python3
docker exec -d container2 bash -c "echo 'Hello from container2' > /index.html && cd / && python3 -m http.server 8080"

Wait a few seconds for the server to start, then test the connection from container1:

docker exec container1 curl -s http://container2:8080

You should see the output:

Hello from container2

This confirms that container1 can connect to container2's HTTP service using the container name for DNS resolution.

Testing Connection with Different Methods

It's also useful to know how to test connectivity using other tools. Let's try using nc (netcat) to check if a specific port is open:

## Make sure netcat is installed in container1
docker exec container1 apt-get install -y netcat

## Test connectivity to the HTTP server on container2
docker exec container1 nc -zv container2 8080

You should see output indicating that the connection was successful:

Connection to container2 (172.18.0.3) 8080 port [tcp/*] succeeded!

These tests confirm that our containers can communicate with each other both at the network level (ping) and the application level (HTTP).

Troubleshooting Container Connectivity Issues

You can skip this step if you don't have any connectivity issues.

Now that we understand how to test connectivity between containers, let's explore how to troubleshoot common connectivity issues.

Common Connectivity Issues

When dealing with Docker container networks, you might encounter several common issues:

  1. Containers on different networks without proper routing
  2. Firewall or security group settings blocking traffic
  3. Application not listening on the expected IP/port
  4. Network configuration errors
  5. DNS resolution problems

Let's go through troubleshooting steps for each of these potential issues.

Checking Network Configuration

First, let's examine the network configuration of our containers:

## View container1's network interfaces
docker exec container1 ip addr show

## View container2's network interfaces
docker exec container2 ip addr show

The output shows all network interfaces in each container. Each connected Docker network appears as an eth interface with its assigned IP address.

Checking Network Routes

Let's check the routing configuration in our containers:

docker exec container1 route -n

This shows the routing table for container1, indicating where network traffic is directed.

Checking Listening Ports

To determine if an application is properly listening for connections, use:

docker exec container2 netstat -tuln

This shows all TCP and UDP listening ports. Our HTTP server should be listening on port 8080.

Diagnosing with tcpdump

For more detailed network traffic analysis, we can use tcpdump to capture and analyze packets:

## Install tcpdump in container1
docker exec container1 apt-get install -y tcpdump dnsutils

## Capture packets for 10 seconds
docker exec container1 timeout 10 tcpdump -i eth0 -n

While this is running, open another terminal and generate some traffic:

docker exec container1 ping -c 3 container2

You should see the ICMP packets being captured in the tcpdump output.

Checking Docker DNS Resolution

If you're having trouble with DNS resolution between containers:

## Check the DNS configuration
docker exec container1 cat /etc/resolv.conf

## Test DNS resolution
docker exec container1 nslookup container2

Simulating a Network Problem

Let's simulate a connectivity problem by temporarily disconnecting container1 from our custom network:

## Disconnect container1 from my-network
docker network disconnect my-network container1

## Try to ping by name (this should fail)
docker exec container1 ping -c 2 container2

You should see that the ping fails because container1 can no longer resolve container2 by name after being disconnected from the shared network.

Let's reconnect it:

## Reconnect container1 to my-network
docker network connect my-network container1

## Verify connectivity is restored
docker exec container1 ping -c 2 container2

Now the ping should work again, demonstrating how containers must be on the same network for name resolution to work.

Troubleshooting Checklist

When facing container connectivity issues, follow this checklist:

  1. Verify containers are running: docker ps
  2. Check they're on the same network: docker network inspect <network>
  3. Verify IP addresses are assigned: docker inspect <container>
  4. Test basic connectivity (ping): docker exec <container> ping <target>
  5. Check application is listening: docker exec <container> netstat -tuln
  6. Verify DNS resolution is working: docker exec <container> nslookup <target>
  7. Look for firewall issues: docker exec <container> iptables -L
  8. Check container logs: docker logs <container>

Using this systematic approach will help you identify and resolve most container connectivity issues.

Summary

In this lab, you have learned how to test and troubleshoot connectivity between Docker containers. You have:

  • Created Docker containers and configured them for networking
  • Learned about Docker networking fundamentals including default and custom networks
  • Used various tools to test basic connectivity between containers (ping, curl, netcat)
  • Explored common connectivity issues and learned systematic troubleshooting approaches

These skills are essential for developing and maintaining Docker-based applications, especially in microservices architectures where multiple containers need to communicate with each other.

For further learning, you might explore Docker Compose for multi-container applications, Docker Swarm or Kubernetes for container orchestration, and more advanced networking concepts like overlay networks for multi-host deployments.