Docker 514 picks each new network's subnet from its default address pools (/16 networks from 172.17 to 172.31, then /20 slices of 192.168.0.0/16), which sometimes collides with a company VPN or office LAN. docker network create lets you choose the subnet, the gateway and a smaller IP range for automatic addresses, and driver options (-o) set the Linux bridge's name and MTU. --ip gives a container a fixed address, and --internal creates a network with no route to the outside:
docker network create --subnet 10.33.0.0/24 --gateway 10.33.0.1 --ip-range 10.33.0.128/25 \
-o com.docker.network.bridge.name=l3-br0 -o com.docker.network.driver.mtu=1400 l3-custom
docker run --rm --network l3-custom alpine:3 ip addr show eth0 | grep -E 'mtu|inet '
docker run --rm --network l3-custom --ip 10.33.0.10 alpine:3 ip addr show eth0 | grep 'inet '
docker network create --internal l3-internal
docker run --rm --network l3-internal alpine:3 wget -T 2 -qO- http://example.com373946c70c9f039d7abab483ff58e2c09220c4be04833cb7e8c4aa6cbf09d998
2: eth0@if299: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1400 qdisc noqueue state UP
inet 10.33.0.128/24 brd 10.33.0.255 scope global eth0
inet 10.33.0.10/24 brd 10.33.0.255 scope global eth0
1354872f1391d21553f0fc2324abfb363bc0c402851e27dab5c90e56effbaf27
wget: bad address 'example.com'The automatic address came from the upper half of the subnet, leaving .2 to .127 for static addresses that never clash with automatic ones. The host sees the bridge as l3-br0 instead of br-373946c70c9f, handy in firewall rules, and the smaller MTU suits traffic that crosses a VPN. The internal network's container could not even resolve a name.
Change the pools for all new networks with default-address-pools in daemon.json; other options include enable_icc=false, which blocks traffic between the network's containers.