Skip to content

Docker Networking

This chapter will provide an in-depth explanation of Docker network configuration and management, including network modes, custom networks, service discovery, load balancing, and other core concepts and practices.

Docker Networking Overview

Network Architecture

Docker networking is based on Linux network namespace technology, providing network isolation and communication capabilities for containers:

┌─────────────────────────────────────────────────────────┐
│                    Host Network                           │
├─────────────────────────────────────────────────────────┤
│  Docker Network Layer                                    │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐     │
│  │   bridge    │  │    host     │  │    none     │     │
│  │   network   │  │    network  │  │    network  │     │
│  └─────────────┘  └─────────────┘  └─────────────┘     │
├─────────────────────────────────────────────────────────┤
│  Container Network Namespaces                            │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐     │
│  │  Container A│  │  Container B│  │  Container C│     │
│  │  eth0       │  │  eth0       │  │  (no network)│    │
│  └─────────────┘  └─────────────┘  └─────────────┘     │
└─────────────────────────────────────────────────────────┘

Network Driver Types

Driver TypeDescriptionUse Cases
bridgeDefault network driver, creates virtual bridgeSingle-host container communication
hostContainer uses host network directlyHigh-performance network requirements
noneDisables container networkingSecurity isolation scenarios
overlayCross-host container communicationClusters and Swarm mode
macvlanAssigns MAC addresses to containersDirect physical network connection needed

Basic Network Operations

Network Management Commands

bash
# List all networks
docker network ls

# View network details
docker network inspect bridge

# Create custom network
docker network create mynetwork

# Delete network
docker network rm mynetwork

# Clean up unused networks
docker network prune

# Connect container to network
docker network connect mynetwork container_name

# Disconnect container from network
docker network disconnect mynetwork container_name

View Container Network Information

bash
# View container network configuration
docker inspect container_name | grep -A 20 "NetworkSettings"

# View container IP address
docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container_name

# View container port mapping
docker port container_name

# View network configuration inside container
docker exec container_name ip addr show
docker exec container_name netstat -tulpn

Bridge Networks

Default Bridge Network

bash
# Run container using default bridge network
docker run -d --name web1 nginx
docker run -d --name web2 nginx

# View default network
docker network inspect bridge

# Container communication (via IP address)
docker exec web1 ping $(docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' web2)

Custom Bridge Network

bash
# Create custom bridge network
docker network create --driver bridge mybridge

# Specify subnet and gateway
docker network create \
  --driver bridge \
  --subnet=172.20.0.0/16 \
  --ip-range=172.20.240.0/20 \
  --gateway=172.20.0.1 \
  mybridge

# Run containers in custom network
docker run -d --name web1 --network mybridge nginx
docker run -d --name web2 --network mybridge nginx

# Container communication (via container names)
docker exec web1 ping web2

Bridge Network Configuration Options

bash
# Create bridge network with configuration
docker network create \
  --driver bridge \
  --subnet=192.168.100.0/24 \
  --gateway=192.168.100.1 \
  --ip-range=192.168.100.128/25 \
  --opt com.docker.network.bridge.name=mybr0 \
  --opt com.docker.network.bridge.enable_icc=true \
  --opt com.docker.network.bridge.enable_ip_masquerade=true \
  --opt com.docker.network.driver.mtu=1500 \
  advanced-bridge

# Specify container IP address
docker run -d --name web \
  --network advanced-bridge \
  --ip 192.168.100.10 \
  nginx

Host Network

Using Host Network

bash
# Use host network
docker run -d --name web --network host nginx

# View container network (same as host)
docker exec web ip addr show

# Access host ports directly
curl http://localhost:80

Host Network Characteristics

Advantages:

  • Best network performance, no NAT overhead
  • Containers can bind directly to host ports
  • Suitable for high-performance network applications

Disadvantages:

  • Container shares network namespace with host
  • Port conflict risk
  • Lower security
bash
# Example: high-performance database
docker run -d \
  --name postgres \
  --network host \
  -e POSTGRES_PASSWORD=password \
  postgres:13

# Connect directly to host's 5432 port
psql -h localhost -U postgres

None Network

Disabling Network

bash
# Create networkless container
docker run -d --name isolated --network none alpine sleep 3600

# View network configuration (only loopback)
docker exec isolated ip addr show

# Manually configure network (if needed)
docker exec isolated ip link add eth0 type dummy

Use Cases

bash
# Secure sensitive data processing
docker run --rm -it \
  --network none \
  --volume /host/data:/data:ro \
  my-secure-processor

# Offline data processing
docker run --rm \
  --network none \
  --volume /input:/input:ro \
  --volume /output:/output \
  data-processor

Custom Networks

Creating Multi-Network Architecture

bash
# Create frontend network
docker network create frontend

# Create backend network
docker network create backend

# Create database network
docker network create database

# Web server (connect frontend and backend)
docker run -d --name web \
  --network frontend \
  nginx

docker network connect backend web

# API server (connect backend and database)
docker run -d --name api \
  --network backend \
  myapi

docker network connect database api

# Database (connect only database network)
docker run -d --name db \
  --network database \
  postgres

Network Aliases

bash
# Create network
docker network create mynetwork

# Use network aliases
docker run -d --name web1 \
  --network mynetwork \
  --network-alias web \
  nginx

docker run -d --name web2 \
  --network mynetwork \
  --network-alias web \
  nginx

# Access via alias (load balancing)
docker run --rm --network mynetwork alpine \
  nslookup web

Port Mapping

Basic Port Mapping

bash
# Map single port
docker run -d -p 8080:80 --name web nginx

# Map multiple ports
docker run -d -p 8080:80 -p 8443:443 --name web nginx

# Map to specific IP
docker run -d -p 127.0.0.1:8080:80 --name web nginx

# Map UDP port
docker run -d -p 8080:80/udp --name app myapp

# Map port range
docker run -d -p 8000-8010:8000-8010 --name app myapp

# Map to random port
docker run -d -P --name web nginx

Dynamic Port Mapping

bash
# View mapped random port
docker port web 80

# Get port number for scripts
PORT=$(docker port web 80 | cut -d: -f2)
echo "Web server is running on port $PORT"

# Use environment variables
docker run -d -p ${HOST_PORT:-8080}:80 --name web nginx

Container-to-Container Communication

Same Network Container Communication

bash
# Create application network
docker network create app-network

# Run database
docker run -d --name database \
  --network app-network \
  -e POSTGRES_PASSWORD=password \
  postgres:13

# Run application (connect to database by container name)
docker run -d --name webapp \
  --network app-network \
  -e DATABASE_URL=postgresql://postgres:password@database:5432/mydb \
  mywebapp

# Test connection
docker exec webapp ping database

Cross-Network Container Communication

bash
# Create multiple networks
docker network create frontend
docker network create backend

# API gateway connects to both networks
docker run -d --name gateway \
  --network frontend \
  nginx

docker network connect backend gateway

# Frontend service
docker run -d --name frontend-app \
  --network frontend \
  my-frontend

# Backend service
docker run -d --name backend-app \
  --network backend \
  my-backend

Service Discovery

DNS Service Discovery

bash
# Create network
docker network create service-network

# Run services
docker run -d --name service1 \
  --network service-network \
  --hostname service1.local \
  myservice

docker run -d --name service2 \
  --network service-network \
  --hostname service2.local \
  myservice

# DNS query
docker run --rm --network service-network alpine \
  nslookup service1

docker run --rm --network service-network alpine \
  dig service1.local

Using Consul for Service Discovery

yaml
# docker-compose.yml
version: '3.8'

services:
  consul:
    image: consul:latest
    ports:
      - "8500:8500"
    command: agent -server -bootstrap -ui -client=0.0.0.0
    networks:
      - service-network

  service1:
    image: myservice
    depends_on:
      - consul
    environment:
      - CONSUL_URL=http://consul:8500
      - SERVICE_NAME=service1
    networks:
      - service-network

  service2:
    image: myservice
    depends_on:
      - consul
    environment:
      - CONSUL_URL=http://consul:8500
      - SERVICE_NAME=service2
    networks:
      - service-network

networks:
  service-network:
    driver: bridge

Load Balancing

Nginx Load Balancing

nginx
# nginx.conf
upstream backend {
    server backend1:8080;
    server backend2:8080;
    server backend3:8080;
}

server {
    listen 80;
    location / {
        proxy_pass http://backend;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}
yaml
# docker-compose.yml
version: '3.8'

services:
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - backend1
      - backend2
      - backend3
    networks:
      - app-network

  backend1:
    image: mybackend
    networks:
      - app-network

  backend2:
    image: mybackend
    networks:
      - app-network

  backend3:
    image: mybackend
    networks:
      - app-network

networks:
  app-network:
    driver: bridge

HAProxy Load Balancing

# haproxy.cfg
global
    daemon

defaults
    mode http
    timeout connect 5000ms
    timeout client 50000ms
    timeout server 50000ms

frontend web_frontend
    bind *:80
    default_backend web_servers

backend web_servers
    balance roundrobin
    server web1 web1:80 check
    server web2 web2:80 check
    server web3 web3:80 check

Network Security

Network Isolation

bash
# Create isolated internal network
docker network create --internal backend-network

# Only backend services can access database
docker run -d --name database \
  --network backend-network \
  postgres

docker run -d --name api \
  --network backend-network \
  myapi

# Frontend cannot directly access database
docker run -d --name frontend \
  --network frontend-network \
  myfrontend

Firewall Rules

bash
# Limit container network access
iptables -I DOCKER-USER -s 172.17.0.0/16 -d 192.168.1.0/24 -j DROP

# Allow specific ports
iptables -I DOCKER-USER -p tcp --dport 80 -j ACCEPT
iptables -I DOCKER-USER -p tcp --dport 443 -j ACCEPT

# Limit container-to-container communication
iptables -I DOCKER-USER -i docker0 -o docker0 -j DROP

Network Encryption

yaml
# Services using TLS encryption
version: '3.8'

services:
  web:
    image: nginx:alpine
    ports:
      - "443:443"
    volumes:
      - ./ssl:/etc/nginx/ssl:ro
      - ./nginx-ssl.conf:/etc/nginx/nginx.conf:ro
    networks:
      - secure-network

  app:
    image: myapp
    environment:
      - TLS_CERT_FILE=/certs/cert.pem
      - TLS_KEY_FILE=/certs/key.pem
    volumes:
      - ./certs:/certs:ro
    networks:
      - secure-network

networks:
  secure-network:
    driver: bridge
    driver_opts:
      encrypted: "true"

Network Monitoring

Network Traffic Monitoring

bash
# Monitor container network traffic
docker exec container_name netstat -i

# Use iftop for monitoring
docker exec -it container_name iftop

# Monitor network connections
docker exec container_name ss -tulpn

# Network performance testing
docker run --rm --network mynetwork alpine \
  sh -c "apk add --no-cache iperf3 && iperf3 -c target_container"

Network Diagnostic Tools

bash
# Network connectivity testing
docker run --rm --network mynetwork alpine ping target_container

# DNS resolution testing
docker run --rm --network mynetwork alpine nslookup target_container

# Port connectivity testing
docker run --rm --network mynetwork alpine \
  sh -c "apk add --no-cache netcat-openbsd && nc -zv target_container 80"

# Route tracing
docker run --rm --network mynetwork alpine traceroute target_container

Advanced Network Configuration

Macvlan Networks

bash
# Create macvlan network
docker network create -d macvlan \
  --subnet=192.168.1.0/24 \
  --gateway=192.168.1.1 \
  -o parent=eth0 \
  macvlan-network

# Run container getting independent MAC address
docker run -d --name web \
  --network macvlan-network \
  --ip 192.168.1.100 \
  nginx

Overlay Networks (Swarm Mode)

bash
# Initialize Swarm
docker swarm init

# Create overlay network
docker network create --driver overlay --attachable myoverlay

# Cross-node container communication
docker run -d --name web1 --network myoverlay nginx
docker run -d --name web2 --network myoverlay nginx

# Containers on different nodes can communicate directly

Custom Network Drivers

bash
# Install third-party network plugin
docker plugin install store/weaveworks/net-plugin:latest

# Create network using custom driver
docker network create --driver weave myweave

# Run container
docker run -d --network myweave nginx

Troubleshooting

Network Issue Diagnosis

bash
# Check network configuration
docker network ls
docker network inspect network_name

# Check container network
docker inspect container_name | grep -A 20 "NetworkSettings"

# Test network connectivity
docker exec container1 ping container2

# Check port listening
docker exec container_name netstat -tulpn

# View routing table
docker exec container_name ip route show

# Check iptables rules
sudo iptables -L DOCKER-USER
sudo iptables -L DOCKER

Common Issue Solutions

bash
# Issue 1: Container cannot access external network
# Check DNS configuration
docker exec container_name cat /etc/resolv.conf

# Restart Docker service
sudo systemctl restart docker

# Issue 2: Port mapping not working
# Check firewall rules
sudo ufw status
sudo iptables -L

# Issue 3: Containers cannot communicate
# Check network connection
docker network inspect network_name

# Reconnect network
docker network disconnect network_name container_name
docker network connect network_name container_name

Performance Optimization

Network Performance Tuning

bash
# Adjust network buffer size
echo 'net.core.rmem_max = 134217728' >> /etc/sysctl.conf
echo 'net.core.wmem_max = 134217728' >> /etc/sysctl.conf

# Optimize TCP parameters
echo 'net.ipv4.tcp_congestion_control = bbr' >> /etc/sysctl.conf

# Apply configuration
sysctl -p

Container Network Optimization

bash
# Use host network for better performance
docker run -d --network host high-performance-app

# Adjust MTU size
docker network create --driver bridge \
  --opt com.docker.network.driver.mtu=9000 \
  jumbo-network

# Disable unnecessary network features
docker run -d \
  --sysctl net.ipv6.conf.all.disable_ipv6=1 \
  myapp

Chapter Summary

This chapter comprehensively introduced various aspects of Docker networking:

Key Points:

  • Network modes: bridge, host, none, overlay and other different modes
  • Custom networks: Create isolated network environments
  • Service discovery: Container communication by name
  • Load balancing: Distribute traffic across multiple containers
  • Network security: Isolate and encrypt network communication
  • Monitoring diagnostics: Network troubleshooting and performance optimization

Best Practices:

  • Use custom networks instead of default bridge
  • Design network architecture and isolation strategies reasonably
  • Implement appropriate security measures
  • Monitor network performance and traffic
  • Regularly check and optimize network configuration

In the next chapter, we will learn about Docker troubleshooting, including common issue diagnosis and solutions.

Further Reading

Content is for learning and research only.