I have a naive question, but I noticed by playing with some Compose files, that docker creates gateway addresses in the form 172.x.0.1
for all the networks of my projects. x
being normally always (?) incremented (unless the docker service is restarted), starting from 18 (because 17 is used by the default bridge network) up to... some number that I cannot figure out in the documentation. After what, docker jumps to gateways of the form 192.168.y.1
, and here again, I'm not able to figure out what range of y
values is available to docker, and what is its strategy to chose gateway addresses in all those ranges.
I have the strong impression that it only chooses private IP addresses. But I've not seen (yet) addresses such as 10.a.b.c
.
Can anybody explain me, ideally with some official resources, how docker actually chooses gateway addresses when creating bridge networks (specially in the case of Compose files), what are all the pools of addresses available to docker (and if it's possible to manually define or constrain these ranges)?
Some of the pages I consulted without much success:
https://docs.docker.com/network/
https://docs.docker.com/network/bridge/
https://docs.docker.com/network/network-tutorial-standalone/
https://docs.docker.com/compose/networking/
https://github.com/compose-spec/compose-spec/blob/master/spec.md
It seems that some "explanation" hides in that tiny piece of code:
var (
// PredefinedLocalScopeDefaultNetworks contains a list of 31 IPv4 private networks with host size 16 and 12
// (172.17-31.x.x/16, 192.168.x.x/20) which do not overlap with the networks in `PredefinedGlobalScopeDefaultNetworks`
PredefinedLocalScopeDefaultNetworks []*net.IPNet
// PredefinedGlobalScopeDefaultNetworks contains a list of 64K IPv4 private networks with host size 8
// (10.x.x.x/24) which do not overlap with the networks in `PredefinedLocalScopeDefaultNetworks`
PredefinedGlobalScopeDefaultNetworks []*net.IPNet
mutex sync.Mutex
localScopeDefaultNetworks = []*NetworkToSplit{{"172.17.0.0/16", 16}, {"172.18.0.0/16", 16}, {"172.19.0.0/16", 16},
{"172.20.0.0/14", 16}, {"172.24.0.0/14", 16}, {"172.28.0.0/14", 16},
{"192.168.0.0/16", 20}}
globalScopeDefaultNetworks = []*NetworkToSplit{{"10.0.0.0/8", 24}}
)
This is the best I could come up with, as I still haven't found any official documentation about this...
It also seems possible to force Docker to use a range of allowed subnets, by creating a /etc/docker/daemon.json
file with, e.g. such content:
{
"default-address-pools": [
{"base": "172.16.0.0/16", "size": 24}
]
}
One can also specify multiple address pools:
{
"default-address-pools": [
{"base": "172.16.0.0/16", "size": 24},
{"base": "xxx.xxx.xxx.xxx/yy", "size": zz} // <- additional poll can be stacked, if needed
]
}
Don't forget to restart the docker
service once you're done:
$ sudo service docker restart
More on this can be found here: https://capstonec.com/2019/10/18/configure-custom-cidr-ranges-in-docker-ee/