If cloud-native technologies and containers are on your radar, you’ve probably encountered Docker and Kubernetes. Both of them are commonly mentioned when it comes to running containers, so this might lead you to wonder how Kubernetes and Docker are different. Read on to find out!
What Is a Container?
In my last job, I worked at a datacenter-monitoring company that delivered its software via the Software-as-a-Service (SaaS) model. Back in 2008, we built the application as one large program. That one program did All The Things. It received the monitoring metrics, stored the monitoring data, generated the user interface and graphs when users logged in, compared the data to alert thresholds and generated alerts, etc. (This “do everything in one program” approach is known as a monolithic architecture.)
There are a variety of drawbacks to such an architecture – if one customer ran a large report, it could consume all the CPU of the server, and delay more critical tasks, such as alert evaluation, for all customers on that server.
A more agile (sometimes!) and scalable (usually!) approach is to use microservices. A microservice architecture delivers an application as a set of small, independent services that communicate with each other over well defined APIs. For example, the report function could be split off into a microservice, that runs on its own set of servers. When a customer requests a report, the UI would make a request to the reporting service, passing in the parameters about which report, covering which timeframe, etc. Because the report service is running separately, then if it is slow, it only affects itself – other functions (alerting, etc) are not affected. It also meant that resources (compute power, memory, storage) could just be allocated to the services that needed them. Further, microservices enable the service to be upgraded independently. The reporting service can be upgraded and restarted without impacting any other functionality, for example (provided that the API’s don’t change).
What has this got to do with containers, Docker, and Kubernetes? Directly, not a lot – but we’ll get there! Whether an application is monolithic or broken up into microservices says nothing about whether containers are involved. Microservices reflect the software architecture. Containers, on the other hand, are an attribute of the way software is packaged for deployment.
Containers are a way of bundling an application and all of its dependencies into a package that can be easily and consistently deployed, regardless of environment. The container will include all needed binaries and libraries necessary to run the application.
Compare the ease of deploying a container (which will be based off a single image, containing all that is needed to run the application) with the older way of deploying just the application code. If the application needed a specific library (such as an encryption library), that would have to be installed separately using the operating system’s tools, so the application installation now required extra steps. Sometimes two applications that were desired to run on the same server would have incompatible library requirements. (One might need version 1.x, and another app needs version 2.x of the same library). Containers avoid all that – the application is packaged neatly with everything it needs to run.
Because microservices are often adopted to gain increased agility (the ability to release code quicker, and easier, with smaller more frequent updates, that allow quicker feedback and learning) they are often released using containers, which simplify (and in many cases automate) these processes. So that is the relationship – microservices based architectures are likely to use container based deployments, as using both paradigms maximizes agility. The combination of containerized microservices allows companies to cut their release cycle time from months to days (or often, multiple releases a day). In my previous job, we went from quarterly releases to weekly releases. And individual services could be updated more frequently than that.
So.. What is Docker?
“Docker” is a few things. A Docker image is a file containing the application and required libraries and dependencies which the application needs in order to run. The Docker image file can be used to start a container based on the image file – effectively, a running application. (Note that many containers can be launched from the same image). These “applications running in containers” are often referred to as Docker containers, because Docker was, a few years ago, practically the only runtime software used to launch containers. (Now over 50% of containers are launched with a different runtime, like containerd.) It is also a company that builds software and tooling to manage the use of containers. This software is often used by developers to create containers on their local workstations, or in their build environments.
Thus when used informally, Docker may mean any of: the container itself, the container runtime engine, the pattern of construction and deployment of an application in a container, or the company.
So.. then what is Kubernetes?
Deploying an application in a container is (kind of!) easy, but that is usually only half the battle. What happens if your application crashes and dies, and needs to be restarted? What happens if your application runs out of CPU resources, and you need to start more copies of the same application to handle the load? What happens if the server the containers are running on becomes unhealthy, and the containers need to be moved to another server?
These are the problems Kubernetes solves. Kubernetes is a container orchestration system, and deals with ensuring that your containerised applications keep running across a cluster of servers. Kubernetes moves administration from a single compute resource to a dynamic set of compute resources. It facilitates scheduling: optimised allocation of resources amongst the dynamic set of workloads and a dynamic set of resources. In short, it makes sure your applications that are running in containers, run in the way you want them to.
Tying it all together
So – Docker (or a similar container runtime engine) is needed to run a container on a server. Kubernetes is needed to coordinate the reliable running of containers across a cluster of servers.
So – hopefully that brings some clarity. Docker now is mostly used by developers to create images that package up applications (usually a microservice) into a container. That container will be deployed to a Kubernetes cluster, run in a container runtime (which could be Docker, but is increasingly likely not to be) where Kubernetes will make sure that the desired number of copies of that container are always running.
If you have further questions about containers, microservices, or Kubernetes – hit us up on Twitter at @SideroLabs.