可能在一些旧版的docker环境,使用Docker compose启动容器时,会碰过下方的错误:
Error response from daemon: could not find an available, non-overlapping IPv4 address pool among the defaults to assign to the network
这其实这是default-address-pools用光的症状,在这些环境中,docker-compose默认会使用Class B的私有网络。
172段的私有IP是有范围的,从172.16.0.0到172.31.255.255。
也就是说,当我们起动一个docker-compose的Project,就会吃掉一个Class B的私有段,非常豪迈,
一个class b的网段可以有65,534个主机,相当於可以有65,534个服务。
您可以透过下方这个命令查看自己的network已用了那些subnet。
docker inspect $(docker network ls|tail -n+2|awk '{print $1}') -f "{{.IPAM}}"|sort
我的MacOS为例,结果如下: (因为deviny/phpenv可以用./all start的功能,所以我故意建了一堆的env档模拟)
docker inspect $(docker network ls|tail -n+2|awk '{print $1}') -f "{{.IPAM}}"|sort
{default map[] []}
{default map[] []}
{default map[] [{10.99.0.0/24 map[]}]}
{default map[] [{172.17.1.0/24 172.17.1.1 map[]}]}
{default map[] [{172.18.0.0/16 172.18.0.1 map[]}]}
{default map[] [{172.19.0.0/16 172.19.0.1 map[]}]}
{default map[] [{172.20.0.0/16 172.20.0.1 map[]}]}
{default map[] [{172.21.0.0/16 172.21.0.1 map[]}]}
{default map[] [{172.22.0.0/16 172.22.0.1 map[]}]}
{default map[] [{192.168.112.0/20 192.168.112.1 map[]}]}
{default map[] [{192.168.128.0/20 192.168.128.1 map[]}]}
{default map[] [{192.168.144.0/20 192.168.144.1 map[]}]}
{default map[] [{192.168.160.0/20 192.168.160.1 map[]}]}
{default map[] [{192.168.176.0/20 192.168.176.1 map[]}]}
{default map[] [{192.168.192.0/20 192.168.192.1 map[]}]}
{default map[] [{192.168.208.0/20 192.168.208.1 map[]}]}
{default map[] [{192.168.224.0/20 192.168.224.1 map[]}]}
{default map[] [{192.168.240.0/20 192.168.240.1 map[]}]}
每启一个docker-compose他会自动跑出一个子网段 ,但在我的MacOS上他是不会满的,他会自动切换到其他网段,例如192段😆。
假设在一个用满不会自动切换子网的环境,以deviny/phpenv的docekr-compose环境来说,
.env中默认的web及php,加上额外的三个ssh、mariadb_ssh及redis。
你们可以想成就是在docker-compose中不同的services。
了不起就五个服务,而且这个设置中,我的maraidb服务还是挂在ssh服务内。
在这种环境下,四个服务,建一个class b的私有段子网络,就太浪费IP啦,又没建丛集。
如果不幸您的Docker环境碰到了我说的问题,以下提供我的解法供参考:
如何解决
第一招: 把没在使用中的网络删掉,请留意提示信息说明,急用可以试试不过我认为这是治标不治本,搞不好没有未用网络能删,或是就真的快满了。
docker network prune
第二招: 手动指定网络
1.先建好网络,再启动容器,手动建的network,在docker-compose停用时,不会被自动移除,至少我的环境是这样的。
docker network create demo_dlaravel_net --subnet 10.99.0.0/24
以deviny/phpenv为例,他的Project叫demo,那么就会有一个demo_dlaravel_net的网络,因此上方的命令中,我的网络名称叫demo_dlaravel_net。
请依你们自己的docker-compose.yml中的所在数据夹名称及网络名称设置。
deviny/phpenv并不是每个人都在用,这里提供我的custom.yml供参考,可能大家会比较有感
version: '3.6'
services:
#=== web service ======================
web:
build:
context: ./dockerfiles
dockerfile: Dockerfile-nginx
args:
USER_ID: ${USER_ID-1000}
GROUP_ID: ${GROUP_ID-1000}
image: ${PROJECT}_nginx
dns: 8.8.8.8
depends_on:
- php
ports:
- ${HTTP_PORT-1050}:80
#- ${HTTPS_PORT-1250}:443
volumes:
- ${FOLDER-./project}:/var/www/html
- ./etc:/etc/nginx/conf.d
networks:
- dlaravel_net
#=== php service ==========================
php:
build:
context: ./dockerfiles
dockerfile: Dockerfile-php-7.4-${CPU-x86_64}
args:
USER_ID: ${USER_ID-1000}
GROUP_ID: ${GROUP_ID-1000}
image: ${PROJECT}_php
volumes:
- ./etc/php:/usr/local/etc/php/conf.d
- ${FOLDER-./project}:/var/www/html
- ./etc/php-fpm.d/www.conf:/usr/local/etc/php-fpm.d/www.conf
- ./etc/cache:/home/dlaravel/.composer/cache
- ./etc/supervisor:/etc/supervisor/conf.d
environment:
- TZ=Asia/Taipei
- project=${HOST-localhost}
command: ["sudo", "/usr/bin/supervisord"]
networks:
dlaravel_net:
#=== top-level dlaravel_netowks key ======================
networks:
dlaravel_net:
第三招: 这算开大绝了,直调整daemon.json,但这需重新启动docker 。
Linux的环境在
/etc/docker/daemon.json
MacOS的环境在
~/.docker/daemon.json
例如: 像我这样,在Linux主机添加一堆子网
"default-address-pools": [
{"base":"172.17.1.0/24","size":24},
{"base":"172.17.2.0/24","size":24},
{"base":"172.17.3.0/24","size":24},
{"base":"172.17.4.0/24","size":24},
{"base":"172.17.5.0/24","size":24},
{"base":"172.17.6.0/24","size":24},
{"base":"172.17.7.0/24","size":24},
{"base":"172.17.8.0/24","size":24},
{"base":"172.17.9.0/24","size":24},
{"base":"172.17.10.0/24","size":24},
{"base":"172.17.11.0/24","size":24},
{"base":"172.17.12.0/24","size":24},
{"base":"172.17.13.0/24","size":24},
{"base":"172.17.14.0/24","size":24},
{"base":"172.17.15.0/24","size":24},
{"base":"172.17.16.0/24","size":24},
{"base":"172.17.17.0/24","size":24},
{"base":"172.17.18.0/24","size":24},
{"base":"172.17.19.0/24","size":24},
{"base":"172.17.20.0/24","size":24},
{"base":"172.17.21.0/24","size":24},
{"base":"172.17.22.0/24","size":24},
{"base":"172.17.23.0/24","size":24},
{"base":"172.17.24.0/24","size":24},
{"base":"172.17.25.0/24","size":24},
{"base":"172.17.26.0/24","size":24},
{"base":"172.17.27.0/24","size":24},
{"base":"172.17.28.0/24","size":24},
{"base":"172.17.29.0/24","size":24},
{"base":"172.17.30.0/24","size":24},
{"base":"172.17.31.0/24","size":24},
{"base":"172.17.32.0/24","size":24},
{"base":"172.17.33.0/24","size":24},
{"base":"172.17.34.0/24","size":24},
{"base":"172.17.35.0/24","size":24},
{"base":"172.17.36.0/24","size":24},
{"base":"172.17.37.0/24","size":24},
{"base":"172.17.38.0/24","size":24},
{"base":"172.17.39.0/24","size":24},
{"base":"172.17.40.0/24","size":24}
]
如果你再用命令查看,有很多子网遮罩都变成24啦,用都用不完了😆。
$ docker inspect $(docker network ls|tail -n+2|awk '{print $1}') -f "{{.IPAM}}"|sort
{default map[] []}
{default map[] []}
{default map[] [{10.99.33.0/24 10.99.33.1 map[]}]}
{default map[] [{172.17.10.0/24 172.17.10.1 map[]}]}
{default map[] [{172.17.1.0/24 map[]}]}
{default map[] [{172.17.12.0/24 172.17.12.1 map[]}]}
{default map[] [{172.17.16.0/24 172.17.16.1 map[]}]}
{default map[] [{172.17.2.0/24 172.17.2.1 map[]}]}
{default map[] [{172.17.21.0/24 172.17.21.1 map[]}]}
{default map[] [{172.17.25.0/24 172.17.25.1 map[]}]}
{default map[] [{172.17.4.0/24 172.17.4.1 map[]}]}
{default map[] [{172.17.6.0/24 172.17.6.1 map[]}]}
{default map[] [{172.17.7.0/24 172.17.7.1 map[]}]}
{default map[] [{172.17.8.0/24 172.17.8.1 map[]}]}
{default map[] [{172.17.9.0/24 172.17.9.1 map[]}]}
{default map[] [{172.18.0.0/16 172.18.0.1 map[]}]}
{default map[] [{172.25.0.0/16 172.25.0.1 map[]}]}
No Comment
Post your comment