skip to Main Content

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.

  1. Why is docker doing that? It’s possible that historically this host had over 255 different bridge networks, but not even close momentarily.
  2. 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


  1. Chosen as BEST ANSWER

    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:

    {
      "default-address-pools": [
        { "base": "172.17.0.0/16", "size": 16 },
        { "base": "172.18.0.0/16", "size": 16 },
        { "base": "172.19.0.0/16", "size": 16 },
        { "base": "172.20.0.0/14", "size": 16 },
        { "base": "172.24.0.0/14", "size": 16 },
        { "base": "172.28.0.0/14", "size": 16 }
      ]
    }
    

    Indeed, sudo systemctl restart docker, create a bunch of networks with docker network create your_test_network, inspect them with docker network inspect your_test_network. The first few should work, but after 15 are created, you'll get the following error:

    Error response from daemon: could not find an available, non-overlapping IPv4 address pool among the defaults to assign to the network

    ...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 with size: 16, squint at it enough and you'll notice that the next 3 describe /14 sized subnets, still with size: 16. This seems to mean, for instance, that 172.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, and 172.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 in 192.168.0.0/24, but you have other stuff on your network at 192.168.200.0/24, there is now a 1-in-16 chance you've lost access to them (specifically if 192.168.192.0/16 is the winner of the draw).

    Why this particular range?

    Because RFC1918. Specifically, it defines these three ranges:

     10.0.0.0        -   10.255.255.255  (10/8 prefix)
     172.16.0.0      -   172.31.255.255  (172.16/12 prefix)
     192.168.0.0     -   192.168.255.255 (192.168/16 prefix)
    

    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.


  2. You can redefine Docker possible IP range:

    1. Open or create if not exists docker daemon config file:

      nano /etc/docker/daemon.json

    2. Add your preferable range:

           {
                "default-address-pools":
                [
                  {"base":"<preferable-IP-range-for-Docker>","size":24}
                ]
              }
      
    3. Restart docker:

      sudo systemctl restart docker

    You can check it by creating test network:

    docker network create tst
    docker network inspect tst
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search