dockersand /
# Docker Sandboxes The Easy Way

Docker has become wildly successful for implementing all manner
of fast-boot/fast-destroy emphemeral computing.  Normally, you
configure a container to do one important thing - run a web server,
host a Jenkins instance ... Then just fire-and-forget afterwards.

But you can also use docker to build general purpose sandboxes.  To do
this, you need to make it easy to log into a running container just
like a "real" VM or server.  This repo provides a fast track to doing
just that.

## Things You Can Learn From This

* How to build a docker image from a dockerfile
* How to tag docker images
* How to use ansible to create and destroy a docker network
* How to use ansible to create, restart, and destroy docker servers
* How host and `ssh` keys are managed on a docker instance
* How to enable `ssh` access to a docker instance
* How to share files between docker containers or between the host and a container

But this is not a "toy" system.  What you see here is a public subset
of what we use all the time here at the TundraWare Intergalactic HQ.
We use this for software development, testing new distributed
computing ideas, and doing custom builds in a sanitized environment.

## Prep Work: What You Need To Do First

The content of this repo assumes you have done several things:

* You've got docker already running on your machine
* You've made docker access available to your own login
* You've got ansible installed on your machine
* `/shared` exists on your host machine with permissions `1777`

## Quickstart For The Impatient

Here's the 10,000 foot view of what you'll have to do once the
Prep Work above is done:

* Configuring sandbox hostname resolution
* Build a docker image from a dockerfile
* Use ansible to start a docker network and the sandboxes
* Login to your running sandboxes

## Configuring Sandbox Hostname Resolution

Various parts of this repo assume that there are (up to) 10 running
sandboxes whose names are `dockersand1` through `dockersand10`.  For this
to work, you have to configure name resolution to properly associate
these names with their equivant IP addresses.

Most likely, you don't have control of your DNS configuration.  The
easy way around this is to add the entries you find in
`dockerfiles/common/etc/dockersand.hosts` to your own `/etc/hosts`

## Building The docker Images

Getting a docker container running requires it to be built from an
"image".  Images are built from something called a "dockerfile".  It
is this file that specifies which Linux distro on which to base the
image.  The file also specifies any special configuration or software
installation you want in your containers.  By setting up the image
with this stuff in it ahead of time, it will be present every time you
start a new container.

There are two dockerfiles in this repo.  To build the corresponding
images, do this:

    cd dockerfiles
    ./ dockersand-centos7
    ./ dockersand-ubuntu

## Start The docker Network And Sandboxes

The creation and destruction of the sandboxes is automated using
ansible "playbooks".

In each case you are creating/destroying 10 separate sandboxes.

To build the sandboxes and their network:

    cd ansible
    ansible-playbook -i inventory/dockersand playbooks/dockersand/dockersand_build.yml

To destroy the sandboxes and their network:

    cd ansible
    ansible-playbook -i inventory/dockersand playbooks/dockersand/dockersand_destroy.yml

To rebuild the sandboxes and their network:

    cd ansible
    ansible-playbook -i inventory/dockersand playbooks/dockersand/dockersand_rebuild.yml

By default, both the build and rebuild create sandboxes based on the
centos7 image.  But you can override this on the command line to
specify a different image.  Just add this to the end of the playbook
command line:

    --extra-vars "dockersand_image=dockersand-ubuntu"

## Logging In

These sandboxes are setup so you can login from your host machine into
the running sandboxes using `ssh` keys. You will find the keys under
`dockerfiles/common/.ssh/`.  There is also an `ssh` configuration
stanza you should add to your own `~/.ssh/config` to get your client to
use the proper key.

However, it is also possible to login using name (`test`) and password (`test`).

In general, once you've properly set up your own `.ssh/config` and
installed keys, you'll do something like this:

    ssh dockersand8

Once you are logged in, you can promote yourself to `root` using the
`sudo` command without any further password required.

## Sharing Files

The sandboxes are created to share the `/shared` directory with the
host machine.  Any file you put there is visible from any of the
sandboxes and/or the host machine.  This makes it easy to share or
move data between the host and any of the sandboxes or between the
sandboxes themselves.

## Homework

Not only is this tooling useful for building and using sandboxes, it's
a good way to learn how docker and ansible work.  Take the time to
explore the various ansible files and dockerfile specifications. There
are comments throughout to help explain what's going on and why.

Here are a few ideas of how to expand on what you see here:

* Try creating your own, new dockerfile for a different
  distro like, say, debian or arch.

* Find where the docker network subnet is specified and change it
  to something else.  Don't forget to update `/etc/hosts` accordingly.

* While in one sandbox, ssh into another.  Notice that this just
  works.  That's because the images are built with the proper ssh keys
  in place everywhere - user and host.  Thus, every container has
  them.  Notice that the name-to-IP association does *not* exist in
  the container's own `/etc/hosts`.  Do some research to figure out
  why it isn't needed.

* The dockerfiles currently load a lot of software by default.
  Try factoring this out into separate ansible playbooks
  to load the software after the sandboxes are up and running.
  You'll have to parameterize it to account for the different
  software installation models and package names in the different

* You'll notice that there is no `dockersand0`.  You can reasonably
  guess that if such an endpoint existed, its IP would be one
  digit lower than the IP for `dockersand1`.  Try logging into
  that IP and see what is there.  You'll be surprised ..