我最近安装了隐私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有以下版本字符串
OpenVPN 2.3.4 x86_64-pc-linux-gnu [SSL (OpenSSL)] [LZO] [EPOLL] [PKCS11] [MH] [IPv6] built on Jun 26 2017
很多人"解决了#34;这个问题通过禁用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
答案 0 :(得分:33)
使用以下内容创建/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脚本。
答案 1 :(得分:14)
如果在docker compose文件中定义子网CIDR,也可以使docker-compose工作:
networks:
your-network:
ipam:
config:
- subnet: 172.16.238.0/24
gateway: 172.16.238.1
另一个选项:首先使用子网CIDR创建网络,然后在docker compose文件中指定要使用此网络的网络:
docker network create your-network --subnet 172.24.24.0/24
在您的docker compose文件中:
networks:
your-network:
external: true
答案 2 :(得分:7)
此解决方案最初是为下一种配置设计的:
,其他配置可能有所不同。
启动您的VPN连接。
案例1
当您尝试重新启动docker daemon时,您将获得日志:
failed to start daemon: Error initializing network controller: list bridge addresses failed: PredefinedLocalScopeDefaultNetworks
案例2
在以下情况下,当您尝试创建网桥网络(隐式创建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
从private address space中选择docker网络的地址范围,该地址范围不打算用于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
-又名“网桥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
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
为OpenVPN创建/etc/openvpn/mynetwork-route-up.sh
脚本,用于从路由中排除我们的子网,并包含以下内容(请注意,我们排除了我们的网络):
#!/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
sudo service docker restart
OpenVPN经常用于通过隧道或至少代理专用池路由所有流量。那么,为什么docker在启动时会失败?
案例1
启动Docker守护程序时,它将检查守护程序的配置网桥网络是否与路由重叠(向上->向下堆栈跟踪):
您可以see here,也可以禁用在守护程序配置中创建默认网桥网络来修复此错误。
案例2
当Docker的组件libnetwork
尝试创建其网络时,它将检查所有可用地址是否与路由重叠。如果未找到任何内容,则返回错误(向上->向下堆栈跟踪):
当然,也存在其他出现此错误的情况。一定要赶上他们!
使用子网参数创建网络
Docker允许您显式传递子网地址范围,并且在这种情况下似乎不执行重叠检查。
https://github.com/docker/libnetwork/blob/922cd533eac14b6e0754756c5cacf9f44af5d699/network.go#L1657
在OpenVPN停止后创建一个网络,然后启动它
我不会对此进行深入研究,但是我认为OpenVPN不会检查重叠部分。
({https://stackoverflow.com/users/7918/jb)[jb]代表his great answer,这使我很想念这个答案。
要对Docker进行深入的网络了解,可以阅读以下文章:
答案 3 :(得分:2)
基于answer from Anas El Barkani,下面是使用PostgreSQL的完整分步示例。
未连接VPN时,创建永久docker network:
docker network create my-network --subnet 172.24.24.0/24
在docker-compose文件中,将网络指定为外部:
version: "2"
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
networks:
- default
ports:
- "127.0.0.1:5432:5432"
networks:
default:
external:
name: my-network
仅此而已。现在,您可以启用VPN,并照常启动/停止容器:
docker-compose up -d
docker-compose down
不需要每次都打开/关闭VPN,也不需要添加奇怪的脚本作为root。
答案 4 :(得分:2)
导致问题的默认路由由 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
错误。
答案 5 :(得分:0)
此处有一些其他上下文:仅当OpenVPN服务器(也称为访问服务器)配置为推送路由以通过VPN发送所有端点的Internet通信时,才会创建0.0.0.0和128.0.0.0路由。通过添加这些广泛的路由,可以在不干扰本地LAN上路由的情况下路由用户的Internet流量,并确保端点仍然能够将OpenVPN流量本身路由到本地路由器。
如果不需要通过OpenVPN服务器发送所有Internet流量,最好让您的VPN管理员创建一个配置文件,该配置文件仅将流量通过VPN路由到所需的目的地(例如私有IP地址范围)一切。那应该避免不得不弄乱端点上的路由。
答案 6 :(得分:0)
也许这样做的一种方法是将除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