My machine is connected to the physical network 192.168.0.0/24, which also has an internet-of-things VLAN 107 at 192.168.107.0/24. After messing around with some docker containers, that host suddenly lost access to VLAN 107. What happened was that a bridge network was created by docker-compose, and although these are usually at 172.x.0.0/16, this one was created at 192.168.96.0/20; indeed, 192.168.96.0/20 contains all of 192.168.107.0/24, so ip route get 192.168.107.100
resolved to that bridge device.
Because I wanted to get things back up and running, I used docker-compose down
and docker-compose up
to restore that network – indeed now it’s at 172.22.0.0/16, and everything works fine. However, I’d really like docker to not do that please thank you.
- Why is docker doing that? It’s possible that historically this host had over 255 different bridge networks, but not even close momentarily.
- How can I get docker to not do that? That is, if it wants to create a bridge network anywhere in 192.168.*, it should fail and refuse to create that network and any requested containers.
2
Answers
Building off of poisoned_monkey's answer, I've dug a bit deeper and found the following.
TL;DR
In
/etc/docker/daemon.json
, set the following:Indeed,
sudo systemctl restart docker
, create a bunch of networks withdocker network create your_test_network
, inspect them withdocker network inspect your_test_network
. The first few should work, but after 15 are created, you'll get the following error:...which is much better (for my case) than it starting to use 192.168.x.x. Other than that, the behavior will be the same as stock docker.
What in the name of Hylia?
Although
default-address-pools
is the config to modify, t's not super-well documented. AFAICT it's only mentioned in the section Dynamic IPv6 subnet allocation (though we're not talking about IPv6 here). Indeed, the default listed there matches this bit of source code. This is the same value I recommended above, but with the extra line{ "base": "192.168.0.0/16", "size": 20 }
.How is that 15 networks?
Although the first three rows describe a
/16
withsize: 16
, squint at it enough and you'll notice that the next 3 describe/14
sized subnets, still withsize: 16
. This seems to mean, for instance, that172.20.0.0/14
is available as split into/16
networks - and there are 4 of those in that range:172.20.0.0/16
,172.21.0.0/16
,172.22.0.0/16
, and172.23.0.0/16
(https://cidr.xyz/ is a neat visualization showing that the first 14 bits of those are the same). So, the first 3 lines contribute 1 network each, and the next 3 contribute 4 each, for a total of 15.These seem to be used in sequence, so your 16th network, on the default config, will be somewhere in the
192.168.0.0/20
range. If, say, your host address on the network is in192.168.0.0/24
, but you have other stuff on your network at192.168.200.0/24
, there is now a 1-in-16 chance you've lost access to them (specifically if192.168.192.0/16
is the winner of the draw).Why this particular range?
Because RFC1918. Specifically, it defines these three ranges:
Docker seems to have left
172.16.0.0/16
for its own use, and divided up the remainder into sensible chunks.Wouldn't it be better to use
size: 24
?It would get me more networks, that's for sure; however, I prefer the system to fail if it needs more than 15 networks, and ask me to explicitly add some. 15 is a ridiculous amount of virtual ethernet devices on my host anyway.
You can redefine Docker possible IP range:
Open or create if not exists docker daemon config file:
nano /etc/docker/daemon.json
Add your preferable range:
Restart docker:
sudo systemctl restart docker
You can check it by creating test network: