Docker Networking Fundamentals
Docker leverages Linux bridging to create a virtual network bridge (docker0) on the host machine. When a container starts, Docker assigns an IP address from the bridge's subnet range, known as Container-IP. The bridge serves as the default gateway for all containers on the same host, enabling direct inter-container communication through their respective Container-IP addresses.
Since the Docker bridge is a virtual device without physical presence, external networks cannot directly reach containers via Container-IP. To enable external access, port mapping must be configured using the -p or -P flags during container creation.
docker run -d --name web1 -P nginx:latest # Random port mapping (starting from 32768)
docker run -d --name web2 -p 8080:80 nginx:latest # Specific port mapping
docker ps -a
Container logs can be inspected using the docker logs command:
docker logs <container_id_or_name>
Network Modes
Docker provides five network modes: host, container, none, bridge, and custom. When Docker is installed, three default networks are automatically created: bridge, none, and host.
| Mode | Syntax |
|---|---|
| Host | --network=host |
| None | --network=none |
| Container | --network=container:NAME_OR_ID |
| Bridge | --network=bridge (default, can be omitted) |
| Custom | --network=NETWORK_NAME |
List available networks:
docker network ls
Host Mode
In host mode, containers share the host's network namespace without obtaining a separate IP address. Docker utilizes Linux Namespaces for resource isolation, including PID, Mount, and Network namespaces. By default, each container receives its own Network Namespace with independent network interfaces, routing tables, and iptables rules. However, host mode containers reuse the host's Network Namespace, meaning they use the host's IP and ports directly without virtualization.
docker run -d --network=host nginx:latest
Container Mode
Container mode allows a new container to share the Network Namespace of an existing container. The new container won't create its own network interface or IP configuration—it inherits the network settings of the target container including IP and port ranges. However, other namespaces like filesystem and process list remain isolated. Communication between the two containers occcurs through the loopback interface.
docker run -d --name shared_web --network=container:<existing_container>
None Mode
None mode disables all network functionality for the container. The container receives its own Network Namespace but lacks any network configuration—no network interfaces, IP addresses, or routing rules. Only the loopback interface exists, making this mode suitable for scenarios requiring maximum network isolation and security.
docker run -d --name isolated --network=none nginx:latest
docker inspect isolated
Bridge Mode
Bridge mode serves as Docker's default networking option. Containers receive dedicated Network Namespaces and connect to the docker0 virtual bridge. Communication between containers and the host occurs through the bridge and iptables NAT rules.
The bridge mechanism operates as follows:
-
When the Docker daemon starts, it creates a virtual bridge named docker0 on the host. All containers on that host connect to this bridge, forming a layer 2 network.
-
Docker assigns IP addresses from the docker0 subnet to containers and configures docker0 as the default gateway. Virtual ethernet pair (veth) device are created—one end placed inside the container as eth0, the other attached to docker0 with a randomly generated name.
-
The
brctl showcommand displays bridge topology and connected interfaces. -
Port mapping (
-p) creates DNAT rules in iptables for traffic forwarding, viewable viaiptables -t nat -vnL.
docker run -d --name webserver nginx:latest
Custom Networks
Custom networks allow specification of subnet ranges, bridge names, and network drivers. They also enable fixed IP assignment to containers.
Create a custom network:
docker network create \
--subnet=172.20.0.0/16 \
--opt "com.docker.network.bridge.name"=custom_br0 \
my_network
Launch a container with a specific IP on the custom network:
docker run -d --network=my_network --ip=172.20.0.10 nginx:latest
Container Resource Management
Docker utilizes Linux Cgroups (Control Groups) to enforce resource limits on containers, covering CPU, memory, and disk I/O quotas.
Cgroups is a kernel mechanism that limits, monitors, and isolates resource usage (CPU, memory, disk I/O) for process groups. Docker leverages Cgroups through its resource constraint capabilities.
CPU Resource Limits
Setting CPU Usage Cap
Linux uses CFS (Completely Fair Scheduler) to manage CPU allocation across processes. The default scheduling period is 100ms. Container CPU limits are configurable through --cpu-period (scheduling period) and --cpu-quota (CPU time allocation per period).
Valid --cpu-period values range from 1000 to 1000000 microseconds (1ms to 1s). The --cpu-quota value must be at least 1000 (1ms minimum allocation).
cd /sys/fs/cgroup/cpu/docker/<container_id>
# cpu.cfs_period_us: scheduling period in microseconds (default 100000)
# cpu.cfs_quota_us: CPU time quota in microseconds (default -1 = unlimited)
# Setting 50000 quota on 100000 period = 50% CPU limit
For stress testing, pull a CentOS image and install the stress tool:
docker run -id --name testbox centos:7 bash
docker exec -it testbox bash
yum install -y epel-release
yum install -y stress
Apply CPU limits to new containers:
docker run --cpu-period=100000 --cpu-quota=50000 nginx:latest
Modify existing container limits directly:
echo 100000 > /sys/fs/cgroup/cpu/docker/<container_id>/cpu.cfs_period_us
echo 25000 > /sys/fs/cgroup/cpu/docker/<container_id>/cpu.cfs_quota_us
CPU Resource Allocation
The --cpu-shares flag controls relative CPU allocation between containers. The default value is 1024, and values must be multiples of 1024. For example, to allocate CPU resources in a 1:2 ratio between two containers:
docker run -d --name app1 --cpu-shares=1024 nginx:latest
docker run -d --name app2 --cpu-shares=2048 nginx:latest
CPU Affinity
Pin containers to specific CPU cores using --cpuset-cpus:
docker run -d --cpuset-cpus=0,1 nginx:latest
Memory Limits
The -m or --memory flag restricts maximum memory usage. The --memory-swap option controls the combined memory and swap limit.
# Container gets 300MB physical memory and 700MB swap (total 1GB)
docker run -m 300m --memory-swap=1g nginx:latest
# Swap disabled (swap size equals memory size)
docker run -m 500m --memory-swap=500m nginx:latest
# Unlimited swap (-1 means unlimited swap usage)
docker run -m 256m --memory-swap=-1 nginx:latest
Disk I/O Limits
# Limit read/write throughput (bytes per second)
docker run --device-read-bps=/dev/sda:10mb nginx:latest
docker run --device-write-bps=/dev/sda:10mb nginx:latest
# Limit read/write operations (IOPS)
docker run --device-read-iops=/dev/sda:100 nginx:latest
docker run --device-write-iops=/dev/sda:100 nginx:latest
# Clean up unused resources
docker system prune -a
Disk I/O limits control throughput in bytes per second or operation counts per second, enabling fine-grained storage resource management for containers with high I/O demands.