可能在一些舊版的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