docker-tuntap-osx icon indicating copy to clipboard operation
docker-tuntap-osx copied to clipboard

Thoughts on automation?

Open Mahoney opened this issue 3 years ago • 7 comments

Installed this yesterday, in the absence of https://github.com/docker/for-mac/issues/155 ever being addressed, and discovered it works perfectly, despite me being on Catalina (10.15.7) (so why can't Docker just fix it?!). Thanks so much! I've been wanting to make it easier to switch back and forth between running tests and the application under test on the host machine or inside docker, as it's so much faster to change things running locally, and much easier to debug them too.

However, I'd really like to automate running docker_tap_up.sh. Anyone got any thoughts on how to do it reliably? I can't find any hook that will trivially run a script when docker for mac (re)starts.

My only idea is to write a docker image that will, on start, use a mounted, named pipe to run commands on the host to run docker_tap_up.sh. Then run that image with --restart always (I can justify it running in the background forever - it can listen to network creation events to create the necessary routes on the host).

But that seems quite an arduous solution to write... anyone have any better ideas?

Mahoney avatar Nov 16 '20 08:11 Mahoney

@Mahoney That container idea is quite interesting and if you manage to get it working, I'm happy to add it to the project. An alternative would be to write a scheduled launched script which checks if the ifaces are up and runs if not. Either of these if made by someone I'm happy to add it to the project and make it a one-off installable service.

As for routes, this is a per-project thing and someone could be running multiple projects at the same time, so I believe it belongs there. What I have been doing lately is wrapping docker into my own management tool for nodejs which handles the up command and routes for me when a project is started. If you get the container idea working, we could make and push up a configurable container which creates these routes etc for us and every project that needs it can put it as an auto-restart service within their docker-compose file.

I quite like the ideas you have proposed, so I will look into that a bit and see what can be done. It would remove the last of the automation nuisances we have with this system ^_^

AlmirKadric avatar Nov 18 '20 07:11 AlmirKadric

I'll try and get it into a more manageable form, but I've spiked it and this works:

  • Create a program to run at startup on the host that evaluates commands passed to a network socket
    #! /usr/bin/env bash
    main() {
      local port=${1:-12345}
      echo "Listening for commands on port $port"
      while :; do
        while read -r cmd; do
          if [ "$cmd" ]; then
            case $cmd in
              'init')
                echo "Calling docker_tap_up.sh"
                if ./docker_tap_up.sh; then
                  echo "docker tap is up"
                else
                  echo "Failed to bring docker tap up"
                fi
                ;;
              *)
                echo "Ignoring unknown command $cmd"
                ;;
            esac
          fi
        done < <(nc -l "$port")
      done
    }
    
    main "$@"
    
  • Alter the docker_tap_up.sh script to call /sbin/ifconfig rather than ifconfig (is there a way to avoid this and have sudoers allow ifconfig on the path?)
  • Add the ifconfig call to sudoers so it can be executed without password:
    %admin ALL = (ALL) NOPASSWD: /sbin/ifconfig tap1 10.0.75.1/30 up
  • Create a tiny docker container that just writes to the pipe and goes into hibernation
    FROM busybox
    
    CMD [ "sh", "-c", "echo init | nc host.docker.internal 12345; sleep infinity" ]
    
    docker build . -t docker-tap-init && \
    docker run -d --name docker-tap-init --init --restart always docker-tap-init
    

Mahoney avatar Nov 18 '20 09:11 Mahoney

On linux I think all the networks using the bridge driver are addressable from the host, so I'd been planning on parsing the output of docker network ls and docker inspect <network_name> to automatically add routes for each bridge network. I was thinking of also getting the docker-tap-init docker container to listen to docker events to add & remove routes dynamically as networks are created and destroyed.

Mahoney avatar Nov 18 '20 09:11 Mahoney

Last thing I thought of was to bundle this all up in a brew recipe that would depend on docker for mac & tuntap, so setting up docker for mac with addressable containers would be a one line brew install.

Mahoney avatar Nov 18 '20 09:11 Mahoney

FWIW, I've got this working: https://github.com/Mahoney/docker-lifecycle-listener

with docker_tap_up.sh in /usr/local/etc/docker-lifecycle-listener.d/on_start/

And a script to automatically create the routes: https://github.com/Mahoney-forks/docker-tuntap-osx/blob/master/sbin/docker_tap_up_routes.sh can also be added to /usr/local/etc/docker-lifecycle-listener.d/on_start/ to get it working end to end.

Notice the inadequacies documented in docker_tap_up_routes.sh.

Mahoney avatar Dec 16 '20 11:12 Mahoney

I've packaged this up in my own brew tap, so you can install it as so:

brew install mahoney/tap/docker-tuntap-osx

Note the instructions in the caveats, you have to sudo chown a couple of things & do a brew services start.

You can get feedback thus:

tail -f /usr/local/var/log/docker-lifecycle-listener.log

I'd like to publicise this more widely (e.g. on the #docker-desktop-mac slack channel and on the https://github.com/docker/for-mac/issues/155 discussion), if @AlmirKadric is OK with me doing so.

Mahoney avatar Jan 08 '21 17:01 Mahoney

@Mahoney sorry for the late reply

I'd like to publicise this more widely (e.g. on the #docker-desktop-mac slack channel and on the docker/for-mac#155 discussion) if @AlmirKadric is OK with me doing so.

Go nuts, MIT FTW ^_^

I recently started another project which needs me to use docker like this on mac again So I'm hoping I will have time again to look at this project and give it a bit more love that it deserves I'll get back to you here once I get my head around all the issues this project has and have a strategy to address them all I'll try to make another major release to modernize this whole thing

Really annoying though that docker still hasn't addressed these issues within their own project -_- Things have come and gone, but I was hoping by now they would have had something tangible But they choose to ignore the issue "orz

AlmirKadric avatar Mar 22 '21 03:03 AlmirKadric