Dockerはネットワークを31個しか作れない

作れないと書いたけど実は作れる。どういうことか見てみよう。

まずはデフォルトのネットワークに何があるのかを見てみる。

$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
d2ab6f31d291        bridge              bridge              local
74a5d829719c        host                host                local
f58f8b205d14        none                null                local

bridge, host, null の3つ存在している。

じゃあネットワークをいっぱい作ってみよう。

$ bash -ec 'for i in {1..100} ; do echo ${i}; docker network create bridge${i} ; done'
1
593eec165f64fa41c45f1588d629a456ab702e44b50444c0f7fd30e871bf0de2
2
8e1fe158f726c84e1838e1b616f7a8a61534a047d77534e94e4262264e25d256
3
f56360c828311c69a75726684f310b3a6cdba72f925bba16e87881b049c1e471
4
c0884ad0b5dc1981ee850b28ba22ef2708962245bc9e909213f139a9d80b37a9
5
26405e901d9dde116499b77ff563090cfd22916cafacc2543925b39744c69271
6
9911f60841b8af356f5d087a699001e349b098e18afa65d0c1ec6c62d6ee2452
7
61bfbe1fa7295e661123ebca37ceacc57399090888e9fefe27181167330af9a8
8
76d45aa9dc3e38af60b0b58e922c43df3c78a382afbe8bfa70e85d03b158ea5d
9
8675f8dc856d6d97fd8e8986df12dfe3555cc6c68cec5dba94b51b5642f95dd1
10
14d4411c28185d09ea90720f564fbe243792c3b2dc76e39245b0ab211be2ed05
11
420fb50af6890c820e4568328a09392ad606fe3c0c94d2856ff3945ee11f68af
12
3838220f3cecac3cfb5e53351021fa8a3c10645ae17f7c3a157d230594db538d
13
735921a582e179132631743354638c7103659c5b2f269b76cf573e37cc13a0b0
14
a049c5ad758bd0af9e29390060c5f927a3c51e204ba8d4cc2a2609b7a0cc115a
15
eb87107535976ee356bc5e1ae1b6de7e7316da7712901f7a3affd79f37ca9c20
16
ebdb696f7427070a537d7187a230166f5f1a64dc546c4db68c22a744cb95d551
17
6af9a3dd72c5a63d07a213444edc02a4a069b181782bbc776a63e28616e35fa9
18
035dbb7b09a8d1654c42fbad74ee2677768ccd3683141d0f1c97c40f922b5e71
19
48e7d32d9d29b2d5d9477d5f0319c6895ddd8465dae7596b5bd9bef2b3e7156d
20
cb5ea88da4ee9a96296fe583adc3d270be91a7c7af8f13d75bac1d34ec27f68d
21
74a254cef5e2b4554c70341f27340f1fe75d170ff4b7a8e5903a8d6c63c9685e
22
aca6864cfbeccb5c35278a1b335514548c2f5a1fa4a40e340588b463c9e73038
23
386a2908546c44565bbbb61579e88a1f2b80dcc0f1a69e7b3d864bec7414d590
24
e8f6e69834bda931e0872c85402eebc98566ae0a50015021a861eec04d3687c5
25
0e0e0ae97ea1dc960383f36df590627df60ca5bb5310045f0099a26a35a8a433
26
60524f4f7430134d7c62b896a5864c3b5e42e4767ad99061f0124c6631a25248
27
4dff28f173bde5a053584f7bf3780872037b028546cd50363dc4ab333da6b3c3
28
06c3e76d652813b17cfc9cd9afeebdd048f6b8a6f61ab5dd590e44b955f4d980
29
85ea0ddc2ea2f321c6b084a6b76c62e90d1ed25abb7c6a6e9bafe8f1e11b16b8
30
Error response from daemon: could not find an available, non-overlapping IPv4 address pool among the defaults to assign to the network

30個目を作ろうとしてエラーになる。

実は作られたネットワークに割り当てられたサブネットを見てみると以下のようになっている。

$ docker network inspect $(docker network ls -q) | grep -E "Subnet" | sort -V
                    "Subnet": "172.17.0.0/16",
                    "Subnet": "172.18.0.0/16",
                    "Subnet": "172.19.0.0/16",
                    "Subnet": "172.20.0.0/16",
                    "Subnet": "172.21.0.0/16",
                    "Subnet": "172.22.0.0/16",
                    "Subnet": "172.23.0.0/16",
                    "Subnet": "172.24.0.0/16",
                    "Subnet": "172.25.0.0/16",
                    "Subnet": "172.26.0.0/16",
                    "Subnet": "172.27.0.0/16",
                    "Subnet": "172.28.0.0/16",
                    "Subnet": "172.29.0.0/16",
                    "Subnet": "172.30.0.0/16",
                    "Subnet": "172.31.0.0/16",
                    "Subnet": "192.168.0.0/20",
                    "Subnet": "192.168.16.0/20",
                    "Subnet": "192.168.32.0/20",
                    "Subnet": "192.168.48.0/20",
                    "Subnet": "192.168.80.0/20",
                    "Subnet": "192.168.96.0/20",
                    "Subnet": "192.168.112.0/20",
                    "Subnet": "192.168.128.0/20",
                    "Subnet": "192.168.144.0/20",
                    "Subnet": "192.168.160.0/20",
                    "Subnet": "192.168.176.0/20",
                    "Subnet": "192.168.192.0/20",
                    "Subnet": "192.168.208.0/20",
                    "Subnet": "192.168.224.0/20",
                    "Subnet": "192.168.240.0/20",

なんだか大きいネットワークが割り当てられている。 デフォルトではどこから払い出されるのかは書かれていないが、以下のチケットに記載されている通り

Document the default address pool for local networks · Issue #8663 · docker/docker.github.io · GitHub

Type Default Size Default Pool
global /24 10.0.0.0/8
local /16 172.17.0.0/12
local* /20 192.168.0.0/16

になる。172.17.0.0/12 とかぱっと計算できないが、172.16.0.0172.31.255.255までになる。 つまりlocalで払い出されるネットワークをすべて使い切ってしまったことになる。

通常は使ってないネットワークを整理すればいいはずだが、本当に31本以上のネットワークを使いたい場合は--subnetオプションを使って細かく切ることができる。

$ docker network create --driver=bridge --subnet=192.168.0.0/24 br0

またデフォルトのプールと切り出すブロックサイズをdaemon.jsonで変更することができる

{
    "default-address-pools": [
        { "base": "172.17.0.0/12", "size": 24 },
        { "base": "192.168.0.0/16", "size": 24 }
    ]
}