A container is a unit of software that packages code with its required dependencies in order to run in an isolated, controlled environment. This allows you to run an application in a way that is predictable, repeatable, and without the uncertainty of inconsistent code execution across diverse development and production environments. A container will always start up and run code the same way, regardless of what machine it exists on.
Containers provide benefits on multiple levels. In terms of physical allocation of resources, containers provide efficient distribution of compute power and memory. However, containers also enable new design paradigms by strengthening the separation of application code and infrastructure code. This design separation also enables specialization within teams of developers, allowing developers to focus on their strengths.
Considering the breadth of what containers bring to the table, this article will bring you up to speed with the common, related terminology. After a general introduction to the benefits of containers, you will learn the nuance between terms such as “container runtimes”, “container orchestration”, and “container engines”. You will then apply this towards understanding the goals of containers, the specific problems they’re trying to solve, and the current solutions available.
Note: This article will abstract the feature sets and benefits of containers away from specific products where it makes sense. However, learning how to use containers will ultimately involve learning how to use Docker. Docker containers are not only one of the most popular stand-alone container solutions in their own right, but are also the de facto standard for many container related technologies.
Additionally, the focus here will only be on containers specialized in isolating single application processes, which is the contemporary implementation of containers most people currently associate with container technology. While container technologies such as LXC existed prior to technologies such as Docker, and even acted as the base of early development for parts of Docker, LXC is different enough in design and practical usage to be considered out of the scope of this article.
Containers are efficient with their consumption of resources — such as CPU compute power and memory — compared to options such as virtual machines. They also offer design advantages both in how they isolate applications and how they abstract the application layer away from the infrastructure layer.
At a project level, this abstraction enables teams and team members to work on their piece of the project without the risk of interfering with other parts of the project. Application developers can focus on application development, while infrastructure engineers can focus on infrastructure. Separating the responsibilities of a team in this case also separates the code, meaning application code won’t break infrastructure code and vice versa.
Containers provide a smoother transition between development and production for teams. For example, if you need to run a Node.js application on a server, one option is to install Node.js directly. This is a straightforward solution when you are a singular developer working on a singular server. However, once you begin collaborating with multiple developers and deploying to multiple environments, that singular installation of Node.js can differ across different team members using even slightly differing development environments.
At a development level, the portability of containers enables infrastructure design that doesn’t have to account for unpredictable application code execution. In this context, containers enable developers to:
These features may make containers appear similar to virtual machines, but the difference is in their underlying design and subsequent efficiency. Modern container technologies are designed specifically to avoid the heavy resource requirements of virtual machines. While containers share the same principles of portability and repeatability, they are designed at a different level of abstraction. Containers skip the virtualization of hardware and the kernel, which are the most resource intensive parts of a virtual machine, and instead rely on the underlying hardware and kernel of the host machine.
As a result, containers are comparatively lightweight, with lower resource requirements. Container technology has subsequently fostered a rich ecosystem to support container centered development, including:
Strictly speaking, these tools and benefits are auxiliary features on the edges of container technology. However, these are often bundled together as complete container solutions due to the ubiquity of their need.
Due to their broad set of use cases, “containers” can refer to multiple things. To help you understand the nuance between the interconnected concepts, here are some key terms that are often confused or used interchangeably in error:
runc, which is the most common, used by Docker, and written in Golang. An alternative is
crunfrom Red Hat written in C, and is meant to be faster and lightweight.
dockershimwhich has steadily been dropped in favor of the more fully featured
containerdfrom Docker, or the alternative
CRI-Ofrom Red Hat.
While these terms all refer to specific aspects of container technology, don’t be surprised if an informal discussion of containers confuses some of these hardline definitions. These definitions are important for your learning path, but be aware that people sometimes use these terms more loosely in everyday conversation.
Container solutions share some common problems that must be addressed in order to be successful:
While containers can offer different solutions, the solutions they offer stem from attempts to answer the same problems. These problems themselves evolve over time along with the needs and expectations of the end user, making this list ever evolving.
Realistically speaking, choosing a container is choosing a container engine. Most container engines use a combination of
runc as their OCI runtime in conjunction with
containerd as their CRI. As previously mentioned, the current landscape is dominated by Docker. Whether or not you choose Docker as your primary deployment solution, your learning path will likely cross with Docker.
The closest competitor is Red Hat’s solution stack of Podman, which manages the runtime of containers; Buildah, which builds container images; and Skopeo, which is an interface between container images and image registries.
Ultimately, the differences between these solutions hinge on how they handle root access and their usage of daemons. Docker requires root access in order to function, and this is an extra level of access that widens the plane of potential security concern. Docker also requires a daemon to always be always alive. The Podman solution stack requires neither of these things.
The next level of container deployment is automation, and container orchestration automates many steps by always adjusting towards an ideal, defined state across a deployment. As a whole orchestration involves provisioning, configuration, scheduling, scaling, monitoring, deployment, and more.
While a full dive into container orchestration is beyond the scope of this article, two prominent players are Docker with Docker Compose and Docker Swarm mode, and Kubernetes. In roughly order of complexity, Docker Compose is a container orchestration solution that deals with multi-container deployments on a single host. When there are multiple hosts involved, Docker Swarm mode is required.
Kubernetes is a purpose-built container orchestration solution. Whereas Docker’s orchestration solutions are balanced against their focus on the core container components, Kubernetes is scoped for extensibility and granular control in orchestration. This results in a tradeoff where Kubernetes deployments are more complex.
This article outlined what containers are and what benefits they bring to the table. Container technology is rapidly evolving, and knowing the terminology will be crucial to your learning journey. LIkewise, understanding the goals of containers and the landscape of competitors that led to their creation allows you to make an informed decision on adopting this technology for your specific needs. To learn more about how to set up and use containers, check out the rest of our Cloud Curriculum series on web containers.
If you’ve enjoyed this tutorial and our broader community, consider checking out our DigitalOcean products which can also help you achieve your development goals.
This curriculum introduces open-source cloud computing to a general audience along with the skills necessary to deploy applications and websites securely to the cloud.