How make openvpn work with docker

后端 未结 6 419
既然无缘
既然无缘 2020-12-07 09:32

I have recently installed privacy vpn, and it turns out that enabled openvpn breaks docker.

When I try to run docker-compose up i get following error <

6条回答
  •  青春惊慌失措
    2020-12-07 10:01

    Disclaimer:

    This solution originally designed for next configuration:

    • Ubuntu 18.04
    • OpenVPN 2.4.4
    • Docker-CE 19.03.5
    • Docker-Compose 1.24.0
    • Bridge IPV4 networks
    • Docker-Swarm not used

    and may differ for other configurations.


    Problem

    Start your VPN connection.


    Case 1

    When you try to restart docker daemon you'll get in the logs:

    failed to start daemon: Error initializing network controller: list bridge addresses failed: PredefinedLocalScopeDefaultNetworks
    


    Case 2

    When you try to create bridge network (implicitly docker and docker-compose try to create this kind of network) within next cases:

    • docker create network without defining subnet parameter
    • docker-compose up without defining subnet parameter

    you'll get:

    ERROR: could not find an available, non-overlapping IPv4 address pool among the defaults to assign to the network
    

    Solution (TL;BPR)

    1. Select address range for docker network from the private address space that not planned be to use for resources inside your VPN. Imagine that it is 172.26.0.0/16.

    2. Add changes to the Docker's daemon config file daemon.json file. :

      {
          "bip": "172.26.0.1/17",
          "fixed-cidr": "172.26.0.0/17", 
          "default-address-pools" : [
              {
                  "base" : "172.26.128.0/17",
                  "size" : 24
              }
          ]
      }
      

      Where:

      • bip - aka «bridge ip»: specific bridge IP address for the docker0 bridge network, which used by default if other was not specified.
      • fixed-cidr - CIDR range for docker0 interface and local containers. Only needed if you want to restrict the IP range defined by bip.
      • default-address-pools - CIDR range for docker_gwbridge (needed for docker-swarm) interface and bridge networks. size parameter set the default submask for newly created networks inside this range.


      We divide our initial 172.26.0.0/16 range by equal 172.26.0.0 - 172.26.127.255 and 172.26.128.0 - 172.26.255.255 pools in this example.

      Be careful with daemon.json formating, otherwise you'd get the error like this when restart docker's daemon

      unable to configure the Docker daemon with file /etc/docker/daemon.json
      
    3. Run your VPN connection
    4. Find your device name by running the comand. Usually it something like tun0
      ip addr show type tun
      
    5. Show created routes
      ip route show dev tun0
      
    6. Find the pool that overlaps with our selected address, let it be:
      172.16.0.0/12 via 10.8.0.1
      
    7. Split that pool on subnets on chunks with our selected Docker pool 172.26.0.0/16. You can use this amazing calculator by David C. We've got:

      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
      
    8. Create /etc/openvpn/mynetwork-route-up.sh script, for OpenVPN for excluding our subnet from routes, with following contents (note that we excluded our network):

      #!/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
      
    9. Create /etc/openvpn/mynetwork-route-pre-down.sh script with following contents (note that we excluded our network):

      #!/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
      
    10. Make that scripts executable

      sudo chmod u+x /etc/openvpn/mynetwork-route-up.sh
      sudo chmod u+x /etc/openvpn/mynetwork-route-pre-down.sh
      
    11. Add this lines to the end of your .ovpn config

      script-security 2
      route-up /etc/openvpn/mynetwork-route-up.sh
      route-pre-down /etc/openvpn/mynetwork-route-pre-down.sh
      
    12. Restart your OpenVPN

    13. Run (for removing networks that may conflict when daemon will restart)

    docker network prune
    
    1. Restart Docker daemon
      sudo service docker restart
      

    Cause

    OpenVPN used frequently to route all traffic through tunnel, or at least, proxy private pools. So why docker fails, when it started?

    Case 1

    When you starting the Docker daemon, it checks daemon's config bridge network for overlaping with routes (up->down stacktrace):

    • 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
提交回复
热议问题