Docker is one of the hottest up-and-coming IT trends around. Sometimes when you see a trend, it turns out to be more hype than reality. Since we use Docker in the Assimilation Suite for building and for testing, we’ve had a chance to examine Docker in some detail. Although there is plenty of hype around Docker, there is also a good bit of reality to all the hoopla surrounding it as well. Since our current release provides some support for Docker containers, we’re excited to announce that our next release will fully support Docker. This article provides an overview of how we are adding full Docker support to the Assimilation Suite.
Docker Support – what Is Docker?
Docker is an easy-to-use container management package. Its containers are based on Linux cgroups and namespaces – which create a virtual-machine-like environment with very low overhead. Containers are analogous to BSD jails, which in turn are extensions of chroot environments for UNIX systems. You can effectively start a new container with little overhead more than the normal overhead to start a process (a fork and exec). Docker provides a great many usability features on top of the basic Linux container capabilities.
Docker Support – and other encapsulation methods
From the perspective of the Assimilation software, Docker is an example of an encapsulation method. Other examples include Vagrant, LXC, LXD and Rocket. What these share in common is that in most respects they appear to applications to be separate OSes, and in most cases can’t be fully or easily observed from outside the encapsulated environment. For example, one cannot easily see the set of packages installed inside of a Docker container from the outside – one has to view it from the inside.
Adding complexity are virtual machine mechanisms like Vagrant – which is perfectly capable of running Docker containers inside itself. As long as we’re starting from scratch, it makes sense to provide support for this kind of situation.
Docker Support – what’s required?
Although we could put nanoprobes inside virtual machines, and there’s nothing wrong with that, Docker containers are intended to be single-process environments with minimal execution environments. As a result, installing nanoprobes inside Docker containers would not be the best choice. This article covers how we will support Docker without installing nanoprobes in the containers.
There are two basic things we require to manage a type of encapsulation. These are:
- A method to run commands inside an encapsulated environment, including setting environment variables. For Docker, this is accomplished by running this command: docker exec your-container-name your-command-line-here. For vagrant, this is accomplished by running vagrant ssh — your-command-line-here. For vagrant, you have to be in the correct directory for this to work.
- A method to discover the list of encapsulated environments of that type. For discovering Docker environments, we use this command: docker ps. For vagrant, we use this command: vagrant global-status.
These are the basics of what we need to be able to support a type of encapsulation. From this it would seem that all we need is the type of encapsulation and the name of the encapsulated entity (VM or container). Because we want to support nesting of containers, we need a route name an environment inside of another environment. For this purpose we use an access route string which is a route of how to get there. For example, perhaps we want to run a command on a Docker container named bilbo inside the Vagrant virtual machine called shire. For this case we specify this access path: vagrant/shire:docker/bilbo. We use a / delimiter to separate an encapsulation mechanism from an environment name, and a : delimiter to separate environments from each other.
Docker Support for Assimilation Discovery
When it comes to how to support containers, the question of how to represent them in the database comes up – and we’ve decided to add these various encapsulated environments almost exactly though they were regular systems. That is, they appear to be hosts for most purposes.
One of the key things that Assimilation nanoprobes do is discovery. Since we own all the discovery agents, it’s possible to add encapsulation support to them in a straightforward way.
The process of adding encapsulation support to involves a small amount of refactoring – so that operations that have to be performed in the container are called in the proper context – using the access path. The access path is implemented in an environment variable called ASSIM_PROXY_PATH. We then created a function called assim_run_in_context() which runs the given command in the requested environment – constructing the proper command to follow the given access path.
At this point in time, we have prototyped this implementation and applied the changes to the packages discovery script implementing both Docker and vagrant encapsulation functions. It is expected that Docker support will be available in the next release (1.1.6) of the Assimilation suite.