Stel je voor: je hebt meerdere containers draaien, maar ze leven in hun eigen kleine wereld. Hoe laat je ze met elkaar praten? Hoe bereik je ze vanaf je host machine? En hoe zorg je ervoor dat ze veilig communiceren?
Het scenario:
In dit hoofdstuk leer je:
Wanneer je geen netwerk specificeert:
# Start een container zonder network configuratie
docker run -d --name web nginx:alpine
# Wat gebeurt er automatisch?
docker inspect web | grep -A 10 "NetworkSettings"
Docker maakt automatisch:
docker0)1. Container Network Model (CNM):
┌─────────────────┐ ┌─────────────────┐
│ Container A │ │ Container B │
│ 172.17.0.2 │ │ 172.17.0.3 │
└─────────┬───────┘ └─────────┬───────┘
│ │
└────────┬─────────────┘
│
┌──────▼──────┐
│ Bridge │
│ docker0 │
│ 172.17.0.1 │
└──────┬──────┘
│
┌──────▼──────┐
│ Host │
│ eth0 │
└─────────────┘
2. Network Drivers:
bridge: Default voor single-host networkinghost: Container gebruikt host’s network stackoverlay: Multi-host clustering (Swarm)macvlan: Geeft containers MAC adressennone: Geen networking3. Network Scopes:
local: Single Docker hostswarm: Docker Swarm clusterglobal: Alle nodes in het clusterAutomatisch gedrag verkennen:
# Lijst huidige networks
docker network ls
# Inspecteer de default bridge
docker network inspect bridge
# Start containers op default bridge
docker run -d --name container1 alpine sleep 3600
docker run -d --name container2 alpine sleep 3600
# Bekijk IP adressen
docker inspect container1 | grep IPAddress
docker inspect container2 | grep IPAddress
Praktische test met netcat:
# In container1: start een server
docker exec -it container1 sh
apk add netcat-openbsd
nc -l -p 8080
# In container2: verbind met container1
docker exec -it container2 sh
apk add netcat-openbsd
# Get container1 IP first
CONTAINER1_IP=$(docker inspect container1 | grep -m 1 '"IPAddress"' | cut -d '"' -f 4)
echo "Hello from container2" | nc $CONTAINER1_IP 8080
Beperkingen van default bridge:
Creëer je eigen bridge network:
# Maak custom bridge network
docker network create mybridge
# Inspecteer het nieuwe network
docker network inspect mybridge
# Start containers op custom network
docker run -d --name web1 --network mybridge nginx:alpine
docker run -d --name web2 --network mybridge nginx:alpine
Voordelen van custom bridge:
# Test DNS resolution met container namen
docker exec web1 ping web2
docker exec web2 ping web1
# Test communicatie met netcat
docker exec -d web1 sh -c "echo 'Hello from web1' | nc -l -p 8080"
docker exec web2 sh -c "nc web1 8080"
Netwerk configuratie opties:
# Network met custom subnet
docker network create \
--driver bridge \
--subnet 192.168.1.0/24 \
--gateway 192.168.1.1 \
--ip-range 192.168.1.128/25 \
mynetwork
# Container met specifiek IP
docker run -d --name fixedip \
--network mynetwork \
--ip 192.168.1.100 \
nginx:alpine
Network debugging tools:
# Installeer network tools in container
docker run -it --rm --network mybridge alpine sh
apk add curl netcat-openbsd tcpdump nmap
# Test connectivity
ping web1
nslookup web1
nc -zv web1 80
# Port scanning
nmap -p 1-1000 web1
Host naar container communicatie:
# Port mapping voor externe toegang
docker run -d --name webapp \
--network mybridge \
-p 8080:80 \
nginx:alpine
# Test vanaf host
curl http://localhost:8080
# Bekijk port mapping
docker port webapp
Container gebruikt host’s network stack:
# Start container met host networking
docker run -d --name hostnet \
--network host \
nginx:alpine
# Container is nu bereikbaar op host IP
curl http://localhost:80
Voordelen en nadelen:
# Voordelen:
# ✅ Beste performance (geen NAT overhead)
# ✅ Container heeft toegang tot alle host interfaces
# ✅ Geen port mapping nodig
# Nadelen:
# ❌ Geen network isolatie
# ❌ Port conflicts tussen containers
# ❌ Security risico's
Praktisch voorbeeld met netcat server:
# Start netcat server op host network
docker run -it --rm --network host alpine sh
apk add netcat-openbsd
nc -l -p 9999
# Vanaf host (andere terminal):
echo "Hello host network" | nc localhost 9999
# Container kan nu alle host interfaces gebruiken
ip addr show
Use cases voor host networking:
Creëer gescheiden netwerken:
# Frontend network
docker network create frontend
# Backend network
docker network create backend
# Database network (geïsoleerd)
docker network create database
Multi-tier applicatie setup:
# Database (alleen op database network)
docker run -d --name db \
--network database \
-e POSTGRES_DB=myapp \
-e POSTGRES_USER=user \
-e POSTGRES_PASSWORD=password \
postgres:alpine
# Backend (verbonden met database en frontend)
docker run -d --name api \
--network backend \
alpine sleep 3600
# Verbind backend ook met database network
docker network connect database api
# Frontend (alleen op frontend network)
docker run -d --name web \
--network frontend \
-p 8080:80 \
nginx:alpine
# Verbind frontend met backend
docker network connect backend web
Test isolatie:
# Web kan api bereiken (beide op backend network)
docker exec web ping api # ✅ Werkt
# Web kan db NIET bereiken (verschillende networks)
docker exec web ping db # ❌ Mislukt
# API kan db bereiken (beide op database network)
docker exec api ping db # ✅ Werkt
Docker’s iptables regels bekijken:
# Bekijk Docker's iptables regels
sudo iptables -L DOCKER
sudo iptables -L DOCKER-USER
# Custom regels toevoegen
sudo iptables -I DOCKER-USER -p tcp --dport 8080 -j DROP
sudo iptables -I DOCKER-USER -s 192.168.1.0/24 -p tcp --dport 8080 -j ACCEPT
Network policies met custom rules:
# Blokkeer alle inter-container communicatie op poort 22
sudo iptables -I DOCKER-USER -p tcp --dport 22 -j DROP
# Allow specifieke communicatie
sudo iptables -I DOCKER-USER -s 172.18.0.0/16 -d 172.19.0.0/16 -j ACCEPT
Initialiseer Docker Swarm:
# Op manager node
docker swarm init --advertise-addr <MANAGER-IP>
# Join commando voor worker nodes
docker swarm join-token worker
Creëer overlay network:
# Overlay network voor services
docker network create \
--driver overlay \
--attachable \
myoverlay
# Deploy service op overlay network
docker service create \
--name web \
--network myoverlay \
--replicas 3 \
nginx:alpine
Cross-host container communicatie:
# Start containers op verschillende hosts
# Host 1:
docker run -d --name container1 \
--network myoverlay \
alpine sleep 3600
# Host 2:
docker run -d --name container2 \
--network myoverlay \
alpine sleep 3600
# Test communicatie tussen hosts
docker exec container1 ping container2
Network traffic analysis:
# Bekijk overlay network details
docker network inspect myoverlay
# Tcpdump op overlay interface
sudo tcpdump -i docker_gwbridge
# VXLAN traffic monitoring
sudo tcpdump -i any port 4789
Creëer macvlan network:
# Bepaal parent interface
ip link show
# Creëer macvlan network
docker network create -d macvlan \
--subnet=192.168.1.0/24 \
--gateway=192.168.1.1 \
-o parent=eth0 \
macvlan-net
# Start container met eigen MAC adres
docker run -d --name macvlan-container \
--network macvlan-net \
--ip=192.168.1.100 \
alpine sleep 3600
Container is nu bereikbaar vanaf netwerk:
# Vanaf andere machine op netwerk
ping 192.168.1.100
ssh user@192.168.1.100 # Als SSH server draait in container
Use cases voor macvlan:
Setup web server en client:
# Netwerk aanmaken
docker network create webnet
# Simple HTTP server met Python
docker run -d --name webserver \
--network webnet \
python:alpine \
python -c "
import http.server
import socketserver
PORT = 8080
Handler = http.server.SimpleHTTPRequestHandler
with socketserver.TCPServer(('', PORT), Handler) as httpd:
print(f'Server running on port {PORT}')
httpd.serve_forever()
"
# HTTP client voor testing
docker run -it --rm \
--network webnet \
alpine sh
# In client container:
apk add curl
curl http://webserver:8080
PostgreSQL server en client:
# Database server
docker run -d --name postgres \
--network webnet \
-e POSTGRES_DB=testdb \
-e POSTGRES_USER=testuser \
-e POSTGRES_PASSWORD=testpass \
postgres:alpine
# Wacht tot database klaar is
docker logs postgres
# Database client
docker run -it --rm \
--network webnet \
postgres:alpine \
psql -h postgres -U testuser -d testdb
# SQL commands:
# CREATE TABLE test (id INT, name VARCHAR(50));
# INSERT INTO test VALUES (1, 'Docker Network Test');
# SELECT * FROM test;
Chat applicatie met netcat:
# Chat server
docker run -it --name chatserver \
--network webnet \
alpine sh
# In server:
apk add netcat-openbsd
nc -l -p 9999
# Chat client
docker run -it --name chatclient \
--network webnet \
alpine sh
# In client:
apk add netcat-openbsd
nc chatserver 9999
# Nu kun je berichten heen en weer sturen!
Setup met nginx load balancer:
# Backend servers
docker run -d --name backend1 \
--network webnet \
-e SERVER_ID=1 \
nginx:alpine
docker run -d --name backend2 \
--network webnet \
-e SERVER_ID=2 \
nginx:alpine
# Nginx load balancer configuratie
cat > nginx.conf << 'EOF'
events {
worker_connections 1024;
}
http {
upstream backend {
server backend1:80;
server backend2:80;
}
server {
listen 80;
location / {
proxy_pass http://backend;
}
}
}
EOF
# Load balancer
docker run -d --name loadbalancer \
--network webnet \
-p 8080:80 \
-v $(pwd)/nginx.conf:/etc/nginx/nginx.conf:ro \
nginx:alpine
Bandwidth testing tussen containers:
# Iperf server
docker run -d --name iperf-server \
--network webnet \
alpine sh -c "
apk add iperf3
iperf3 -s
"
# Iperf client
docker run -it --rm \
--network webnet \
alpine sh -c "
apk add iperf3
iperf3 -c iperf-server -t 30
"
Latency testing:
# Ping statistieken
docker exec chatclient ping -c 100 chatserver
# Hping voor advanced testing
docker run -it --rm \
--network webnet \
--cap-add NET_RAW \
alpine sh -c "
apk add hping3
hping3 -S -p 80 -c 10 webserver
"
Traffic monitoring met tcpdump:
# Monitor bridge traffic
sudo tcpdump -i docker0
# Monitor specifiek network
BRIDGE=$(docker network inspect webnet | jq -r '.[0].Options."com.docker.network.bridge.name"')
sudo tcpdump -i $BRIDGE
# Container network namespace monitoring
PID=$(docker inspect chatserver | jq -r '.[0].State.Pid')
sudo nsenter -t $PID -n tcpdump -i eth0
Network statistieken:
# Container network stats
docker exec chatserver cat /proc/net/dev
# Detailed network info
docker exec chatserver ss -tuln
docker exec chatserver netstat -i
Automatische DNS in custom networks:
# Custom network met DNS
docker network create \
--dns 8.8.8.8 \
--dns 1.1.1.1 \
dnsnet
# Container met custom DNS
docker run -it --rm \
--network dnsnet \
--dns 9.9.9.9 \
alpine sh
# Test DNS resolution
nslookup google.com
dig github.com
Container als DNS server:
# Dnsmasq DNS server
docker run -d --name dns-server \
--network dnsnet \
--cap-add NET_ADMIN \
alpine sh -c "
apk add dnsmasq
echo 'address=/myapp.local/192.168.1.100' > /etc/dnsmasq.conf
dnsmasq --no-daemon
"
# Test custom DNS
docker run -it --rm \
--network dnsnet \
--dns $(docker inspect dns-server | jq -r '.[0].NetworkSettings.Networks.dnsnet.IPAddress') \
alpine sh
# Test custom domain
nslookup myapp.local
Multiple aliases voor een container:
# Container met aliases
docker run -d --name webserver \
--network webnet \
--network-alias web \
--network-alias api \
--network-alias frontend \
nginx:alpine
# Test alle aliases
docker run -it --rm --network webnet alpine sh
ping web
ping api
ping frontend
# Alle wijzen naar dezelfde container!
Iptables regels voor containers:
# Blokkeer uitgaande connecties naar specifieke IP's
sudo iptables -I DOCKER-USER -s 172.17.0.0/16 -d 10.0.0.0/8 -j DROP
# Rate limiting
sudo iptables -I DOCKER-USER -p tcp --dport 80 -m limit --limit 25/minute --limit-burst 100 -j ACCEPT
# Allow alleen specifieke poorten
sudo iptables -I DOCKER-USER -p tcp -m multiport --dports 80,443,22 -j ACCEPT
sudo iptables -A DOCKER-USER -j DROP
Network namespaces isolatie:
# Container in eigen network namespace
docker run -d --name isolated \
--network none \
alpine sleep 3600
# Handmatig network interface toevoegen
sudo ip link add veth0 type veth peer name veth1
sudo ip link set veth1 netns $(docker inspect isolated | jq -r '.[0].State.Pid')
sudo ip addr add 192.168.100.1/24 dev veth0
sudo ip link set veth0 up
# In container namespace:
sudo nsenter -t $(docker inspect isolated | jq -r '.[0].State.Pid') -n sh
ip addr add 192.168.100.2/24 dev veth1
ip link set veth1 up
ip route add default via 192.168.100.1
TLS/SSL tussen containers:
# Generate certificates
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes -subj "/CN=webserver"
# HTTPS server
docker run -d --name https-server \
--network webnet \
-v $(pwd)/cert.pem:/cert.pem:ro \
-v $(pwd)/key.pem:/key.pem:ro \
python:alpine \
python -c "
import http.server
import ssl
import socketserver
PORT = 8443
Handler = http.server.SimpleHTTPRequestHandler
with socketserver.TCPServer(('', PORT), Handler) as httpd:
httpd.socket = ssl.wrap_socket(httpd.socket,
certfile='/cert.pem',
keyfile='/key.pem',
server_side=True)
print(f'HTTPS Server running on port {PORT}')
httpd.serve_forever()
"
# HTTPS client
docker run -it --rm \
--network webnet \
alpine sh -c "
apk add curl
curl -k https://https-server:8443
"
1. Container kan andere container niet bereiken:
# Check if containers are on same network
docker inspect container1 | jq '.[0].NetworkSettings.Networks'
docker inspect container2 | jq '.[0].NetworkSettings.Networks'
# Test connectivity
docker exec container1 ping container2
docker exec container1 nc -zv container2 80
# Check DNS resolution
docker exec container1 nslookup container2
docker exec container1 dig container2
2. Port mapping werkt niet:
# Check port mappings
docker port container-name
# Check if service luistert op juiste interface
docker exec container-name netstat -tlnp
# Test van buitenaf
curl -v http://localhost:mapped-port
telnet localhost mapped-port
3. Network performance problemen:
# Check network stats
docker exec container-name cat /proc/net/dev
# Test bandwidth
docker exec container1 sh -c "yes | head -c 100M" | docker exec -i container2 sh -c "cat > /dev/null"
# Check for packet loss
docker exec container1 ping -c 1000 container2 | grep "packet loss"
Network namespace debugging:
# List network namespaces
sudo ip netns list
# Enter container's network namespace
PID=$(docker inspect container-name | jq -r '.[0].State.Pid')
sudo nsenter -t $PID -n bash
# In namespace:
ip addr show
ip route show
ss -tuln
Packet capture:
# Capture on container interface
PID=$(docker inspect container-name | jq -r '.[0].State.Pid')
sudo nsenter -t $PID -n tcpdump -i eth0 -w capture.pcap
# Capture on bridge
sudo tcpdump -i docker0 -w bridge-capture.pcap
# Analyze with tshark
tshark -r capture.pcap -T fields -e ip.src -e ip.dst -e tcp.port
Network connectivity matrix:
#!/bin/bash
# Test connectivity between all containers
CONTAINERS=$(docker ps --format "")
echo "Container Connectivity Matrix:"
echo "============================="
for container1 in $CONTAINERS; do
echo -n "$container1: "
for container2 in $CONTAINERS; do
if [ "$container1" != "$container2" ]; then
if docker exec $container1 ping -c 1 -W 1 $container2 >/dev/null 2>&1; then
echo -n "✅ $container2 "
else
echo -n "❌ $container2 "
fi
fi
done
echo
done
1. Three-tier architecture:
# DMZ network for load balancers
docker network create dmz
# Application network for app servers
docker network create app-tier
# Database network for data layer
docker network create db-tier
# Load balancer (public access)
docker run -d --name lb \
--network dmz \
-p 80:80 -p 443:443 \
nginx:alpine
# App servers (internal only)
docker run -d --name app1 --network app-tier myapp:latest
docker run -d --name app2 --network app-tier myapp:latest
# Database (most restricted)
docker run -d --name db --network db-tier postgres:alpine
# Connect tiers
docker network connect app-tier lb
docker network connect db-tier app1
docker network connect db-tier app2
2. Zero-trust networking:
# Default deny network
docker network create \
--internal \
--subnet 10.0.0.0/24 \
zero-trust
# Explicit allow rules via reverse proxy
docker run -d --name proxy \
--network zero-trust \
-p 80:80 \
-v $(pwd)/nginx.conf:/etc/nginx/nginx.conf:ro \
nginx:alpine
Centralized logging:
# Log aggregator
docker run -d --name logstash \
--network monitoring \
-p 5000:5000 \
elastic/logstash:latest
# Application with structured logging
docker run -d --name app \
--network app-tier \
--log-driver json-file \
--log-opt max-size=100m \
--log-opt max-file=3 \
myapp:latest
Health checking:
# Health check service
docker run -d --name healthcheck \
--network monitoring \
alpine sh -c "
while true; do
for container in app1 app2 db; do
if nc -z \$container 80; then
echo \"\$(date): \$container - OK\"
else
echo \"\$(date): \$container - FAIL\"
fi
done
sleep 30
done
"
Network configuration backup:
#!/bin/bash
# Backup all Docker networks
BACKUP_DIR="/backup/docker-networks/$(date +%Y%m%d)"
mkdir -p "$BACKUP_DIR"
# Export network configurations
docker network ls --format "" | while read network; do
if [ "$network" != "bridge" ] && [ "$network" != "host" ] && [ "$network" != "none" ]; then
docker network inspect "$network" > "$BACKUP_DIR/$network.json"
fi
done
# Export container network connections
docker ps --format "" | while read container; do
docker inspect "$container" | jq '.[0].NetworkSettings' > "$BACKUP_DIR/$container-networks.json"
done
Network restore script:
#!/bin/bash
# Restore Docker networks from backup
BACKUP_DIR="/backup/docker-networks/$1"
if [ ! -d "$BACKUP_DIR" ]; then
echo "Backup directory not found: $BACKUP_DIR"
exit 1
fi
# Recreate networks
for config_file in "$BACKUP_DIR"/*.json; do
if [[ "$config_file" != *"-networks.json" ]]; then
network_name=$(basename "$config_file" .json)
# Extract network configuration
subnet=$(jq -r '.[0].IPAM.Config[0].Subnet' "$config_file")
gateway=$(jq -r '.[0].IPAM.Config[0].Gateway' "$config_file")
driver=$(jq -r '.[0].Driver' "$config_file")
# Recreate network
docker network create \
--driver "$driver" \
--subnet "$subnet" \
--gateway "$gateway" \
"$network_name"
fi
done
Van simpel naar complex:
Praktische vaardigheden:
Advanced concepten:
Wanneer welk network type te gebruiken:
| Use Case | Network Type | Reden |
|---|---|---|
| Development | Custom Bridge | DNS resolution + isolatie |
| High Performance | Host | Minimale overhead |
| Multi-host | Overlay | Swarm clustering |
| Legacy Integration | Macvlan | Physical network access |
| Maximum Security | None + manual | Complete controle |
| Load Balancing | Custom Bridge | Service discovery |
| Microservices | Multiple Custom | Service isolatie |
Network security:
Performance:
Reliability:
Met deze networking kennis kun je:
Je bent nu klaar voor:
Docker networking is geen mysterie meer - het is je krachtige tool voor moderne, gedistribueerde applicaties! 🌐🚀