If you attend many DevOps oriented meetups, it’s hard to avoid people people waxing rhapsodic about containerization strategies with Docker and similar technologies. The concept of having small, self-contained environments (rather like Go for operating systems) that can be readily provisioned and deprovisioned is exciting. With most of our production workloads running on short-lived EC2 instances, I haven’t had the cluster of longer lived compute hosts on which containerized micro-services made sense. Still, I wanted to at least get some hands on experience with the technology I’ve been reading so much about. Time to bust out some Vagrant!
Current versions of Vagrant have built-in support for Docker as both a provisioner and a provider. The provisioner functionality takes care of preparing the Docker host, while the provider is the portion responsible for managing the individual Docker containers. Docker is based upon process segmentation features in the Linux kernel (think back to jails if you’re an old timey unix user like myself). I run Windows as my primary desktop OS, which I thought had put Docker out of easy reach. Lo and behold, the Vagrant provisoner is actually quite spiffy for Windows users. In its default state (simply including `config.vm.provison “docker”`), the provisioner will detect that it is running on a non-Docker compatible OS and fire up a micro-VM of boot2dockerfor hosting containers). If you’re running on Linux, Vagrant will skip the VM and run the containers natively on the OS.
Once a suitable environment is available for running your containers, the Vagrant provider kicks in and takes care of downloading/building your Dockerfile and running the container. Vagrant does a nice job of abstracting concepts such as port forwarding and shared folders to their Docker equivalents, allowing you to set up persistent volumes and expose services in a way that is both Docker like yet still in familiar Vagrantfile syntax, keeping idiom changes to a minimum.
All is not quite sunshine and roses for Windows users, however. Rsync on Windows under Vagrant has often been an awkward combination. Vagrant 1.7.x and 1.8.x has had numerous gotchyas when trying to get this setup to work as smoothly as Unix-brethern. I had to pull in some specific manual source modifications to get rsync running. Even with this and other modifications, I’ve yet to successfully get the native boot2docker functionality working. Instead, my setup uses a host Vagrantfile to spin up an Ubuntu-based VM for the docker provisioner on which to install the Docker tool chain. While that combination of Windows host-Ubuntu VM-Docker Containers may sound a bit odd, it’s actually quite a smooth combination. I’m able to stand up the Kaggle Rstats image very easily with this setup.
So far I’ve limited my explorations to the equivalent of “Hello, World” exercises. After some head scratching on why my `vagrant up` commands were complaining that the container was shutting down immediately after start up, I realized that my Docker images had no interactive/long-running commands, and were therefore shutting down as they had no work to perform. That’s quite nifty from a small task worker perspective. Simply adjusting my command to `vagrant docker-run -t – R` dropped my into a working Rstats session.
A full copy of the less than 40 lines that make up my Vagrant setup are available at this gist. I also found this blog post very helpful in understanding the Vagrant approach to Docker in more depth. I’m looking forward to exploring the layer composition model of Docker as well as the value that configuration management tools such as Chef can bring to containers.