如何让 openvpn 与 docker 一起工作
How make openvpn work with docker
我最近安装了 privacy vpn,结果发现启用 openvpn 中断 docker。
当我尝试 运行 docker-compose up
时出现以下错误
ERROR: could not find an available, non-overlapping IPv4 address pool among the defaults to assign to the network
禁用 vpn 可以解决问题(但我宁愿不禁用它)。有什么办法可以让这两者和平共处呢?我使用 debian jessie,我的 openvpn 有以下版本 string
OpenVPN 2.3.4 x86_64-pc-linux-gnu [SSL (OpenSSL)] [LZO] [EPOLL] [PKCS11] [MH] [IPv6] built on Jun 26 2017
很多人"solved"这个问题是通过禁用 openvpn 来解决的,所以我特地询问如何让这两个同时工作。
参考文献:
如果这有什么不同,我的 vpn 提供商是:https://www.ovpn.com/ 这里是(经过一些编辑的)配置文件:
client
dev tun
proto udp
remote host port
remote-random
mute-replay-warnings
replay-window 256
push "dhcp-option DNS 46.227.67.134"
push "dhcp-option DNS 192.165.9.158"
remote-cert-tls server
cipher aes-256-cbc
pull
nobind
reneg-sec 432000
resolv-retry infinite
comp-lzo
verb 1
persist-key
persist-tun
auth-user-pass /etc/openvpn/credentials
ca ovpn-ca.crt
tls-auth ovpn-tls.key 1
解决方案 (TL;DR;)
使用以下内容创建 /etc/openvpn/fix-routes.sh
脚本:
#!/bin/sh
echo "Adding default route to $route_vpn_gateway with /0 mask..."
ip route add default via $route_vpn_gateway
echo "Removing /1 routes..."
ip route del 0.0.0.0/1 via $route_vpn_gateway
ip route del 128.0.0.0/1 via $route_vpn_gateway
向文件添加可执行位:chmod o+x /etc/openvpn/fix-routes.sh
。将此文件的所有者更改为 root:chown root:root /etc/openvpn/fix-routes.sh
。
将以下两行添加到您的配置中:
script-security 2
route-up /etc/openvpn/fix-routes.sh
说明
Openvpn 为以下网络添加路由:0.0.0.0/1
和 128.0.0.0/1
(这些路由覆盖整个 IP 范围),并且 docker 无法找到创建它的 IP 地址范围自己的专用网络。
您需要添加默认路由(通过 openvpn 路由所有内容)并禁用这两个特定路由。 fix-routes
脚本可以做到这一点。
openvpn 添加自己的路由后调用此脚本。要执行脚本,您需要将 script-security
设置为 2
,这允许从 openvpn 上下文执行 bash 脚本。
谢谢
我要感谢author of this comment on github, also thanks to ovpn support。
如果您在 docker 撰写文件中定义子网 CIDR,您还可以获得 docker-撰写工作:
networks:
your-network:
ipam:
config:
- subnet: 172.16.238.0/24
gateway: 172.16.238.1
另一种选择:首先创建具有子网 CIDR 的网络,然后在 docker 撰写文件中指定您要使用此网络:
docker network create your-network --subnet 172.24.24.0/24
在您的 docker 撰写文件中:
networks:
your-network:
external: true
这里有一些额外的上下文:0.0.0.0 和 128.0.0.0 路由仅在 OpenVPN 服务器(也称为访问服务器)配置为推送路由以通过 VPN 发送所有端点的 Internet 流量时创建。通过添加这些广泛的路由,可以在不干扰本地 LAN 路由的情况下路由用户的 Internet 流量,并确保端点仍然能够将 OpenVPN 流量本身路由到本地路由器。
如果不需要通过 OpenVPN 服务器发送所有互联网流量,您最好让您的 VPN 管理员创建一个配置文件,该配置文件仅通过以下方式将流量路由到所需的目的地(例如私有 IP 地址范围) VPN 而不是一切。这应该避免弄乱端点上的路由。
也许一种方法是添加除 172.16.0.0/12 之外的所有路由以通过 VPN 进行路由,这样我们可以确保所有出去的事情都得到妥善处理:
sudo ip route add 192.0.0.0/2 via $route_vpn_gateway
sudo ip route add 128.0.0.0/3 via $route_vpn_gateway
sudo ip route add 176.0.0.0/4 via $route_vpn_gateway
sudo ip route add 160.0.0.0/5 via $route_vpn_gateway
sudo ip route add 168.0.0.0/6 via $route_vpn_gateway
sudo ip route add 174.0.0.0/7 via $route_vpn_gateway
sudo ip route add 173.0.0.0/8 via $route_vpn_gateway
sudo ip route add 172.128.0.0/9 via $route_vpn_gateway
sudo ip route add 172.64.0.0/10 via $route_vpn_gateway
sudo ip route add 172.32.0.0/11 via $route_vpn_gateway
sudo ip route add 172.0.0.0/12 via $route_vpn_gateway
# And finally delete the default route which handle 172.16.0.0/12
sudo ip route del 128.0.0.0/1 via $route_vpn_gateway
基于 ,这里有一个使用 PostgreSQL 的完整分步示例。
在未连接 VPN 的情况下,创建永久 docker network:
docker network create my-network --subnet 172.24.24.0/24
在 docker-compose 文件中,将网络指定为外部网络:
version: "2"<br>
services:
postgres:
container_name: postgres
image: postgres
volumes:
- ./volumes/postgres/data:/var/lib/postgresql/data
environment:
- POSTGRES_DB=dummy
- POSTGRES_USER=user
- POSTGRES_PASSWORD=123456
- POSTGRES_HOST=localhost
<b>networks:
- default</b>
ports:
- "127.0.0.1:5432:5432"<br>
<b>networks:
default:
external:
name: my-network</b>
</pre>
就是这样。现在您可以像往常一样启用您的 VPN 和 start/stop 容器:
docker-compose up -d
docker-compose down
无需每次都打开 VPN on/off,或以 root 身份添加奇怪的脚本。
免责声明:
此解决方案最初设计用于下一个配置:
- Ubuntu 18.04
- OpenVPN 2.4.4
- Docker-CE 19.03.5
- Docker-Compose 1.24.0
- 桥接 IPV4 网络
- Docker-Swarm 未使用
其他配置可能有所不同。
问题
开始您的 VPN 连接。
案例一
当您尝试重新启动 docker 守护程序时,您将在日志中看到:
failed to start daemon: Error initializing network controller: list bridge addresses failed: PredefinedLocalScopeDefaultNetworks
案例二
当您尝试创建桥接网络时(隐式地 docker
和 docker-compose
尝试创建这种网络)在下一个案例中:
docker create network
没有定义子网参数
docker-compose up
没有定义子网参数
你会得到:
ERROR: could not find an available, non-overlapping IPv4 address pool among the defaults to assign to the network
解决方案 (TL;BPR)
来自 private address space 的 docker 网络的 Select 地址范围未计划用于您的 VPN 内的资源。假设是172.26.0.0/16
.
将更改添加到 Docker 的守护程序配置文件 daemon.json
文件。 :
{
"bip": "172.26.0.1/17",
"fixed-cidr": "172.26.0.0/17",
"default-address-pools" : [
{
"base" : "172.26.128.0/17",
"size" : 24
}
]
}
其中:
bip
- 又名«bridge ip»:docker0
桥接网络的特定桥接IP地址,如果未指定其他则默认使用.
fixed-cidr
- docker0
接口和本地容器的 CIDR 范围。仅当您想限制 bip
. 定义的 IP 范围时才需要
default-address-pools
- docker_gwbridge
(docker-swarm
需要)接口和桥接网络的 CIDR 范围。 size
参数设置此范围内新建网络的默认子掩码。
在本例中,我们将初始 172.26.0.0/16
范围除以相等的 172.26.0.0 - 172.26.127.255
和 172.26.128.0 - 172.26.255.255
池。
小心 daemon.json
格式化,否则重启 docker 的守护程序时会出现这样的错误
unable to configure the Docker daemon with file /etc/docker/daemon.json
- 运行 你的 VPN 连接
- 通过运行 命令查找您的设备名称。通常它类似于
tun0
ip addr show type tun
- 显示创建的路线
ip route show dev tun0
- 找到与我们选择的地址重叠的矿池,让它成为:
172.16.0.0/12 via 10.8.0.1
使用我们选择的 Docker 池 172.26.0.0/16
在块上拆分子网上的池。您可以使用 this amazing calculator by David C。我们有:
172.16.0.1/13
172.24.0.1/15
172.26.0.0/16
172.27.0.1/16
172.28.0.1/14
创建 /etc/openvpn/mynetwork-route-up.sh
脚本,用于 OpenVPN 从路由中排除我们的子网,内容如下(注意我们排除了我们的网络):
#!/usr/bin/env bash
echo "Remove the route that conflicts with the Docker's subnet"
ip route del 172.16.0.0/12 via $route_vpn_gateway
echo "Bring back routes that don't intersect"
ip route add 172.16.0.0/13 via $route_vpn_gateway dev $dev
ip route add 172.24.0.0/15 via $route_vpn_gateway dev $dev
ip route add 172.27.0.0/16 via $route_vpn_gateway dev $dev
ip route add 172.28.0.0/14 via $route_vpn_gateway dev $dev
使用以下内容创建 /etc/openvpn/mynetwork-route-pre-down.sh
脚本(注意我们排除了我们的网络):
#!/usr/bin/env bash
echo "Remove manually created routes"
ip route del 172.16.0.0/13 dev $dev
ip route del 172.24.0.0/15 dev $dev
ip route del 172.27.0.0/16 dev $dev
ip route del 172.28.0.0/14 dev $dev
echo "Creating original route because OpenVPN will try to del that"
ip route add 172.16.0.0/12 via $route_vpn_gateway dev $dev
使该脚本可执行
sudo chmod u+x /etc/openvpn/mynetwork-route-up.sh
sudo chmod u+x /etc/openvpn/mynetwork-route-pre-down.sh
将此行添加到 .ovpn
配置的末尾
script-security 2
route-up /etc/openvpn/mynetwork-route-up.sh
route-pre-down /etc/openvpn/mynetwork-route-pre-down.sh
重启你的 OpenVPN
运行(用于删除守护程序重新启动时可能发生冲突的网络)
docker network prune
- 重新启动 Docker 守护进程
sudo service docker restart
原因
OpenVPN 经常用于通过隧道或至少代理专用池路由所有流量。那么为什么 docker 在开始时会失败?
案例一
当您启动 Docker 守护进程时,它会检查守护进程的配置桥接网络是否与路由重叠(向上->向下堆栈跟踪):
- docker-ce/components/engine/daemon/daemon.go:NewDaemon
- docker-ce/components/engine/daemon/daemon.go:restore
- docker-ce/components/engine/daemon/daemon_unix.go:initNetworkController
- docker-ce/components/engine/daemon/daemon_unix.go:initBridgeDriver
- docker-ce/components/engine/vendor/github.com/docker/libnetwork/netutils/utils_linux.go:ElectInterfaceAddresses
- docker-ce/components/engine/vendor/github.com/docker/libnetwork/netutils/utils_linux.go:FindAvailableNetwork
- docker-ce/components/engine/vendor/github.com/docker/libnetwork/netutils/utils_linux.go:CheckRouteOverlaps
- docker-ce/components/engine/vendor/github.com/docker/libnetwork/netutils/utils.go
您可以 see here,您也可以在守护程序配置中禁用创建默认桥接网络以修复此错误。
案例二
当 Docker 的组件 libnetwork
尝试创建它的网络时,它会检查所有可用地址是否与路由重叠。如果没有找到,它 returns 一个错误(向上->向下堆栈跟踪):
- [docker-ce/components/engine/daemon/network.go:createNetwork]
- docker-ce/components/engine/vendor/github.com/docker/libnetwork/controller.go:NewNetwork
- docker-ce/components/engine/vendor/github.com/docker/libnetwork/network.go:ipamAllocate
- docker-ce/components/engine/vendor/github.com/docker/libnetwork/network.go:ipamAllocateVersion
- docker-ce/components/engine/vendor/github.com/docker/libnetwork/network.go:requestPoolHelper
- docker-ce/components/engine/vendor/github.com/docker/libnetwork/ipam/allocator.go:RequestPool
- docker-ce/components/engine/vendor/github.com/docker/libnetwork/ipam/allocator.go:getPredefinedPool
当然,也存在出现此错误的其他情况。必须抓住他们!
解决方法(不推荐)
使用子网参数创建网络
Docker 允许您显式传递子网地址范围,并且在这种情况下似乎不执行重叠检查。
https://github.com/docker/libnetwork/blob/922cd533eac14b6e0754756c5cacf9f44af5d699/network.go#L1657
OpenVPN停止时创建网络,然后启动
我没有深入研究,但我认为,OpenVPN 不会检查重叠。
P.S.
谢谢(https://whosebug.com/users/7918/jb)[jb] for ,写这个答案给了我很多启发。
深入了解网络Docker,可以阅读这篇文章:
- «Configure Custom CIDR Ranges in Docker EE» 戴夫·汤普森
- «Plan your installation» 来自 Docker
导致问题的默认路由由 OpenVPN 服务器推送到 OpenVPN 客户端。
而不是创建一个脚本来删除路由,您可以简单地首先停止创建有问题的路由。
有两种方法可以做到这一点:
如果您可以更改 OpenVPN 服务器上的设置,请编辑配置并删除 redirect-gateway
选项。在我的 EdgeRouter 上,相关行如下所示:
openvpn-option "--push redirect-gateway def1"
一个 Linux 服务器我相信它看起来像这样:
push "redirect-gateway def1"
如果您无法更改 OpenVPN 服务器上的设置,您可以告诉您的 OpenVPN 客户端忽略来自服务器的推送路由。在我的 Linux 客户端上,相关行如下所示:
pull-filter ignore redirect-gateway
完成这些更改并重新启动 OpenVPN 服务后,您应该能够启动 Docker 容器而不会出现可怕的 could not find an available, non-overlapping IPv4 address
错误。
对我有用的是:
看完后
Creating network "airflow_default" with the default driver
ERROR: could not find an available, non-overlapping IPv4 address pool
among the defaults to assign to the network
只需手动创建该网络:
docker network create airflow_default --subnet 172.24.24.0/24
我最近安装了 privacy vpn,结果发现启用 openvpn 中断 docker。
当我尝试 运行 docker-compose up
时出现以下错误
ERROR: could not find an available, non-overlapping IPv4 address pool among the defaults to assign to the network
禁用 vpn 可以解决问题(但我宁愿不禁用它)。有什么办法可以让这两者和平共处呢?我使用 debian jessie,我的 openvpn 有以下版本 string
OpenVPN 2.3.4 x86_64-pc-linux-gnu [SSL (OpenSSL)] [LZO] [EPOLL] [PKCS11] [MH] [IPv6] built on Jun 26 2017
很多人"solved"这个问题是通过禁用 openvpn 来解决的,所以我特地询问如何让这两个同时工作。
参考文献:
如果这有什么不同,我的 vpn 提供商是:https://www.ovpn.com/ 这里是(经过一些编辑的)配置文件:
client
dev tun
proto udp
remote host port
remote-random
mute-replay-warnings
replay-window 256
push "dhcp-option DNS 46.227.67.134"
push "dhcp-option DNS 192.165.9.158"
remote-cert-tls server
cipher aes-256-cbc
pull
nobind
reneg-sec 432000
resolv-retry infinite
comp-lzo
verb 1
persist-key
persist-tun
auth-user-pass /etc/openvpn/credentials
ca ovpn-ca.crt
tls-auth ovpn-tls.key 1
解决方案 (TL;DR;)
使用以下内容创建 /etc/openvpn/fix-routes.sh
脚本:
#!/bin/sh
echo "Adding default route to $route_vpn_gateway with /0 mask..."
ip route add default via $route_vpn_gateway
echo "Removing /1 routes..."
ip route del 0.0.0.0/1 via $route_vpn_gateway
ip route del 128.0.0.0/1 via $route_vpn_gateway
向文件添加可执行位:chmod o+x /etc/openvpn/fix-routes.sh
。将此文件的所有者更改为 root:chown root:root /etc/openvpn/fix-routes.sh
。
将以下两行添加到您的配置中:
script-security 2
route-up /etc/openvpn/fix-routes.sh
说明
Openvpn 为以下网络添加路由:0.0.0.0/1
和 128.0.0.0/1
(这些路由覆盖整个 IP 范围),并且 docker 无法找到创建它的 IP 地址范围自己的专用网络。
您需要添加默认路由(通过 openvpn 路由所有内容)并禁用这两个特定路由。 fix-routes
脚本可以做到这一点。
openvpn 添加自己的路由后调用此脚本。要执行脚本,您需要将 script-security
设置为 2
,这允许从 openvpn 上下文执行 bash 脚本。
谢谢
我要感谢author of this comment on github, also thanks to ovpn support。
如果您在 docker 撰写文件中定义子网 CIDR,您还可以获得 docker-撰写工作:
networks:
your-network:
ipam:
config:
- subnet: 172.16.238.0/24
gateway: 172.16.238.1
另一种选择:首先创建具有子网 CIDR 的网络,然后在 docker 撰写文件中指定您要使用此网络:
docker network create your-network --subnet 172.24.24.0/24
在您的 docker 撰写文件中:
networks:
your-network:
external: true
这里有一些额外的上下文:0.0.0.0 和 128.0.0.0 路由仅在 OpenVPN 服务器(也称为访问服务器)配置为推送路由以通过 VPN 发送所有端点的 Internet 流量时创建。通过添加这些广泛的路由,可以在不干扰本地 LAN 路由的情况下路由用户的 Internet 流量,并确保端点仍然能够将 OpenVPN 流量本身路由到本地路由器。
如果不需要通过 OpenVPN 服务器发送所有互联网流量,您最好让您的 VPN 管理员创建一个配置文件,该配置文件仅通过以下方式将流量路由到所需的目的地(例如私有 IP 地址范围) VPN 而不是一切。这应该避免弄乱端点上的路由。
也许一种方法是添加除 172.16.0.0/12 之外的所有路由以通过 VPN 进行路由,这样我们可以确保所有出去的事情都得到妥善处理:
sudo ip route add 192.0.0.0/2 via $route_vpn_gateway
sudo ip route add 128.0.0.0/3 via $route_vpn_gateway
sudo ip route add 176.0.0.0/4 via $route_vpn_gateway
sudo ip route add 160.0.0.0/5 via $route_vpn_gateway
sudo ip route add 168.0.0.0/6 via $route_vpn_gateway
sudo ip route add 174.0.0.0/7 via $route_vpn_gateway
sudo ip route add 173.0.0.0/8 via $route_vpn_gateway
sudo ip route add 172.128.0.0/9 via $route_vpn_gateway
sudo ip route add 172.64.0.0/10 via $route_vpn_gateway
sudo ip route add 172.32.0.0/11 via $route_vpn_gateway
sudo ip route add 172.0.0.0/12 via $route_vpn_gateway
# And finally delete the default route which handle 172.16.0.0/12
sudo ip route del 128.0.0.0/1 via $route_vpn_gateway
基于
在未连接 VPN 的情况下,创建永久 docker network:
docker network create my-network --subnet 172.24.24.0/24
在 docker-compose 文件中,将网络指定为外部网络:
version: "2"<br> services: postgres: container_name: postgres image: postgres volumes: - ./volumes/postgres/data:/var/lib/postgresql/data environment: - POSTGRES_DB=dummy - POSTGRES_USER=user - POSTGRES_PASSWORD=123456 - POSTGRES_HOST=localhost <b>networks: - default</b> ports: - "127.0.0.1:5432:5432"<br> <b>networks: default: external: name: my-network</b> </pre>
就是这样。现在您可以像往常一样启用您的 VPN 和 start/stop 容器:
docker-compose up -d docker-compose down
无需每次都打开 VPN on/off,或以 root 身份添加奇怪的脚本。
免责声明:
此解决方案最初设计用于下一个配置:
- Ubuntu 18.04
- OpenVPN 2.4.4
- Docker-CE 19.03.5
- Docker-Compose 1.24.0
- 桥接 IPV4 网络
- Docker-Swarm 未使用
其他配置可能有所不同。
问题
开始您的 VPN 连接。
案例一
当您尝试重新启动 docker 守护程序时,您将在日志中看到:
failed to start daemon: Error initializing network controller: list bridge addresses failed: PredefinedLocalScopeDefaultNetworks
案例二
当您尝试创建桥接网络时(隐式地 docker
和 docker-compose
尝试创建这种网络)在下一个案例中:
docker create network
没有定义子网参数docker-compose up
没有定义子网参数
你会得到:
ERROR: could not find an available, non-overlapping IPv4 address pool among the defaults to assign to the network
解决方案 (TL;BPR)
-
来自 private address space 的 docker 网络的
Select 地址范围未计划用于您的 VPN 内的资源。假设是
172.26.0.0/16
.将更改添加到 Docker 的守护程序配置文件
daemon.json
文件。 :{ "bip": "172.26.0.1/17", "fixed-cidr": "172.26.0.0/17", "default-address-pools" : [ { "base" : "172.26.128.0/17", "size" : 24 } ] }
其中:
bip
- 又名«bridge ip»:docker0
桥接网络的特定桥接IP地址,如果未指定其他则默认使用.fixed-cidr
-docker0
接口和本地容器的 CIDR 范围。仅当您想限制bip
. 定义的 IP 范围时才需要
default-address-pools
-docker_gwbridge
(docker-swarm
需要)接口和桥接网络的 CIDR 范围。size
参数设置此范围内新建网络的默认子掩码。
在本例中,我们将初始
172.26.0.0/16
范围除以相等的172.26.0.0 - 172.26.127.255
和172.26.128.0 - 172.26.255.255
池。小心
daemon.json
格式化,否则重启 docker 的守护程序时会出现这样的错误unable to configure the Docker daemon with file /etc/docker/daemon.json
- 运行 你的 VPN 连接
- 通过运行 命令查找您的设备名称。通常它类似于
tun0
ip addr show type tun
- 显示创建的路线
ip route show dev tun0
- 找到与我们选择的地址重叠的矿池,让它成为:
172.16.0.0/12 via 10.8.0.1
使用我们选择的 Docker 池
172.26.0.0/16
在块上拆分子网上的池。您可以使用 this amazing calculator by David C。我们有:172.16.0.1/13 172.24.0.1/15 172.26.0.0/16 172.27.0.1/16 172.28.0.1/14
创建
/etc/openvpn/mynetwork-route-up.sh
脚本,用于 OpenVPN 从路由中排除我们的子网,内容如下(注意我们排除了我们的网络):#!/usr/bin/env bash echo "Remove the route that conflicts with the Docker's subnet" ip route del 172.16.0.0/12 via $route_vpn_gateway echo "Bring back routes that don't intersect" ip route add 172.16.0.0/13 via $route_vpn_gateway dev $dev ip route add 172.24.0.0/15 via $route_vpn_gateway dev $dev ip route add 172.27.0.0/16 via $route_vpn_gateway dev $dev ip route add 172.28.0.0/14 via $route_vpn_gateway dev $dev
使用以下内容创建
/etc/openvpn/mynetwork-route-pre-down.sh
脚本(注意我们排除了我们的网络):#!/usr/bin/env bash echo "Remove manually created routes" ip route del 172.16.0.0/13 dev $dev ip route del 172.24.0.0/15 dev $dev ip route del 172.27.0.0/16 dev $dev ip route del 172.28.0.0/14 dev $dev echo "Creating original route because OpenVPN will try to del that" ip route add 172.16.0.0/12 via $route_vpn_gateway dev $dev
使该脚本可执行
sudo chmod u+x /etc/openvpn/mynetwork-route-up.sh sudo chmod u+x /etc/openvpn/mynetwork-route-pre-down.sh
将此行添加到
.ovpn
配置的末尾script-security 2 route-up /etc/openvpn/mynetwork-route-up.sh route-pre-down /etc/openvpn/mynetwork-route-pre-down.sh
重启你的 OpenVPN
运行(用于删除守护程序重新启动时可能发生冲突的网络)
docker network prune
- 重新启动 Docker 守护进程
sudo service docker restart
原因
OpenVPN 经常用于通过隧道或至少代理专用池路由所有流量。那么为什么 docker 在开始时会失败?
案例一
当您启动 Docker 守护进程时,它会检查守护进程的配置桥接网络是否与路由重叠(向上->向下堆栈跟踪):
- docker-ce/components/engine/daemon/daemon.go:NewDaemon
- docker-ce/components/engine/daemon/daemon.go:restore
- docker-ce/components/engine/daemon/daemon_unix.go:initNetworkController
- docker-ce/components/engine/daemon/daemon_unix.go:initBridgeDriver
- docker-ce/components/engine/vendor/github.com/docker/libnetwork/netutils/utils_linux.go:ElectInterfaceAddresses
- docker-ce/components/engine/vendor/github.com/docker/libnetwork/netutils/utils_linux.go:FindAvailableNetwork
- docker-ce/components/engine/vendor/github.com/docker/libnetwork/netutils/utils_linux.go:CheckRouteOverlaps
- docker-ce/components/engine/vendor/github.com/docker/libnetwork/netutils/utils.go
您可以 see here,您也可以在守护程序配置中禁用创建默认桥接网络以修复此错误。
案例二
当 Docker 的组件 libnetwork
尝试创建它的网络时,它会检查所有可用地址是否与路由重叠。如果没有找到,它 returns 一个错误(向上->向下堆栈跟踪):
- [docker-ce/components/engine/daemon/network.go:createNetwork]
- docker-ce/components/engine/vendor/github.com/docker/libnetwork/controller.go:NewNetwork
- docker-ce/components/engine/vendor/github.com/docker/libnetwork/network.go:ipamAllocate
- docker-ce/components/engine/vendor/github.com/docker/libnetwork/network.go:ipamAllocateVersion
- docker-ce/components/engine/vendor/github.com/docker/libnetwork/network.go:requestPoolHelper
- docker-ce/components/engine/vendor/github.com/docker/libnetwork/ipam/allocator.go:RequestPool
- docker-ce/components/engine/vendor/github.com/docker/libnetwork/ipam/allocator.go:getPredefinedPool
当然,也存在出现此错误的其他情况。必须抓住他们!
解决方法(不推荐)
使用子网参数创建网络
Docker 允许您显式传递子网地址范围,并且在这种情况下似乎不执行重叠检查。
https://github.com/docker/libnetwork/blob/922cd533eac14b6e0754756c5cacf9f44af5d699/network.go#L1657
OpenVPN停止时创建网络,然后启动
我没有深入研究,但我认为,OpenVPN 不会检查重叠。
P.S.
谢谢(https://whosebug.com/users/7918/jb)[jb] for
深入了解网络Docker,可以阅读这篇文章:
- «Configure Custom CIDR Ranges in Docker EE» 戴夫·汤普森
- «Plan your installation» 来自 Docker
导致问题的默认路由由 OpenVPN 服务器推送到 OpenVPN 客户端。
而不是创建一个脚本来删除路由,您可以简单地首先停止创建有问题的路由。
有两种方法可以做到这一点:
如果您可以更改 OpenVPN 服务器上的设置,请编辑配置并删除
redirect-gateway
选项。在我的 EdgeRouter 上,相关行如下所示:openvpn-option "--push redirect-gateway def1"
一个 Linux 服务器我相信它看起来像这样:
push "redirect-gateway def1"
如果您无法更改 OpenVPN 服务器上的设置,您可以告诉您的 OpenVPN 客户端忽略来自服务器的推送路由。在我的 Linux 客户端上,相关行如下所示:
pull-filter ignore redirect-gateway
完成这些更改并重新启动 OpenVPN 服务后,您应该能够启动 Docker 容器而不会出现可怕的 could not find an available, non-overlapping IPv4 address
错误。
对我有用的是: 看完后
Creating network "airflow_default" with the default driver
ERROR: could not find an available, non-overlapping IPv4 address pool
among the defaults to assign to the network
只需手动创建该网络:
docker network create airflow_default --subnet 172.24.24.0/24