The Problem Containers Solve
Docker emerged as a lightweight alternative to virtual machines. VMs consumed significant resources and took 3-5 minutes to boot, making horizontal scaling expensive. Containers package applications with dependencies into images that start in seconds, not minutes.
The Networking Challenge
Without network connectivity, containers offer limited utility. Running a single container on host networking mode works fine - the process accesses the host machine’s network resources directly. But what happens when you need:
- Multiple containerized services with different network requirements on the same machine
- Multiple replicas of the same container on one host
Consider running three Nginx servers on the same host. Each defaults to port 80. How can multiple containers use the same port without conflicts?
Port Mapping Solution
Docker solves this using port mapping with bridge networking mode. Each container gets its own network namespace, allowing services to run simultaneously despite using identical internal ports.
Example: Three Nginx Containers
Container 1: Internal port 80 → Host port 8081
Container 2: Internal port 80 → Host port 8082
Container 3: Internal port 80 → Host port 8083
External traffic arrives at the host’s mapped ports (8081, 8082, 8083) and Docker routes it to the appropriate container’s port 80.
How Bridge Mode Works
Docker’s bridge networking creates isolated network namespaces for each container:
- Container Creation: Docker assigns each container its own network namespace
- Port Mapping: Maps host ports to container ports via iptables rules
- Traffic Routing: External requests to host ports get forwarded to container ports
- Isolation: Containers operate independently while remaining externally accessible
Technical Implementation
Under the hood, Docker uses:
- Network namespaces for isolation
- iptables rules for port forwarding
- Bridge networks to connect containers to the host
- Virtual ethernet pairs (veth) to link namespaces
This architecture enables multiple containers to share host resources while maintaining network isolation and external accessibility.
Key Benefits
- Resource Efficiency: Multiple services on one host without port conflicts
- Isolation: Each container has its own network stack
- Scalability: Easy horizontal scaling with port mapping
- Flexibility: Services can use standard ports internally regardless of external mapping
Container port mapping transforms complex networking challenges into simple configuration, enabling the container revolution that powers modern application deployment.
iptables: The Engine Behind Port Mapping
The iptables firewall utility controls network traffic in Linux systems through tables, chains, and rules. Understanding iptables helps explain how Docker implements port mapping.
Core Components
Tables organize rules by function:
filter: Controls packet filtering (allow/deny traffic)nat: Handles Network Address Translationmangle: Modifies packet headersraw: Configures exemptions from connection trackingsecurity: Enforces MAC (Mandatory Access Control) rules
Chains determine when rules process packets:
INPUT: Packets destined for local systemOUTPUT: Packets generated by local systemFORWARD: Packets routed through the systemPREROUTING: Packets entering the network stackPOSTROUTING: Packets leaving the network stack
Basic Command Structure
iptables commands follow this syntax:
iptables [-t table] -A chain rule-specification
Example rules:
# Allow incoming SSH connections
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# Drop all incoming traffic from specific IP
iptables -A INPUT -s 192.168.1.100 -j DROP
# Allow established connections
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
Common Operations
View current rules:
# List all rules
iptables -L
# Show rules with line numbers
iptables -L --line-numbers
# Display packet counts
iptables -L -v
Manage rules:
# Delete rule by chain and number
iptables -D INPUT 1
# Clear all rules in a chain
iptables -F INPUT
# Save rules permanently
iptables-save > /etc/iptables/rules.v4
Best Practices
- Create a default deny policy:
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
- Allow loopback traffic:
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
- Allow established connections:
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
Common Use Cases
- Port forwarding:
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
- Load balancing:
iptables -A PREROUTING -t nat -p tcp --dport 80 -m statistic --mode nth --every 3 --packet 0 -j DNAT --to-destination 10.0.0.1:80
iptables -A PREROUTING -t nat -p tcp --dport 80 -m statistic --mode nth --every 2 --packet 0 -j DNAT --to-destination 10.0.0.2:80
iptables -A PREROUTING -t nat -p tcp --dport 80 -j DNAT --to-destination 10.0.0.3:80
- Basic firewall:
# Allow HTTP/HTTPS
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# Block ping floods
iptables -A INPUT -p icmp -m limit --limit 1/s --limit-burst 1 -j ACCEPT
Troubleshooting
Debug traffic flows:
# Enable logging for dropped packets
iptables -A INPUT -j LOG --log-prefix "IPTables-Dropped: "
# Track packet matches
iptables -L -v -n
This tutorial covers basic iptables concepts and operations. For production environments, consider using higher-level tools like ufw or firewalld which provide simpler interfaces to iptables.