It’s impossible to learn about containerization without hearing about Docker and Kubernetes. These two tools together dominate the world of containers, both being the de-facto standard in what they each do. When you’re first getting started learning about containers, it can be quite a challenge to figure out what the differences are between these two tools.
In my personal experience, I believed they were both a way to run containers, and that the biggest difference was in how they approached the issue of spinning up containers. As I started to look more into it, I figured out that this was of course not true. It turned out that Docker and Kubernetes aren’t competing with each other, rather they complement each other.
In this article you’ll get to learn about these differences as well. You’ll get an understanding of what each tool can accomplish separately, as well as how they complement each other in a production scenario. In the end, you’ll also get a short introduction to some alternatives, giving you a comprehensive look into the space these two tools live in.
As mentioned in the introduction, these two tools aren’t meant to be substitutions of each other, as they don’t have the same functionality. Because of this, it’s difficult to compare the two tools as it’s like comparing apples and oranges. They look the same, many will even put them in the same category, however they serve distinct purposes. You wouldn’t use an orange in an apple pie after all.
It’s exactly the same with Docker and Kubernetes. To the uninformed, they look to be exactly the same. They’re definitely in the same category, so it’s easy to be confused. However, you don’t want to use Docker when you should’ve used Kubernetes, as well as the other way around. To understand why this is, it’s important to first understand each tool properly.
What is Docker?
In short, Docker is a tool to package and distribute applications. Using a Dockerfile, you build an image from which you can spin up a container. A container is, roughly put, a very lightweight Virtual Machine (VM). There are some key reasons why a container isn’t actually a VM in practice, one of which is the clever way that containers use the host OS kernel directly, whereas a traditional VM would spin up an entirely virtualized machine with its own kernel. Containers only use the exact amount of resources it needs, and they add very little overhead when running.
While Docker allows you to run images that are based on regular OS’s like Ubuntu, in effect allowing you to run a full Linux server (or a personal Linux installation) in a container, that is rarely how it’s used. To be clear, there’s nothing stopping you from using a container as a full Linux server. It’s definitely possible, to an extent. You can spin up an Ubuntu container by executing
docker run -it ubuntu bash, and after about a minute you’ll have a running shell on an Ubuntu system. You’ll find that it’s a very limited Ubuntu installation, however you can just install all the tools you need for yourself. But, it’s a limited Ubuntu installation for a reason.
Generally, Docker is used to run applications using as few resources as possible. The more applications you have, and the more instances of your applications you have, the more important it becomes to have small images, as they are faster to spin up new containers of. This is an essential feature to have when you want to orchestrate your containers. Orchestration is the functionality you’re getting from using Kubernetes.
What is Kubernetes?
Once you’ve got your applications containerized, you need to run them somewhere, and there are many ways of doing this. You can use a simple turnkey solution like Azure App Service or Google App Engine. These services allow you to spin up a service in a cloud provider based on a Docker image, which will quickly give you a running application in the cloud with its own IP.
This isn’t the perfect solution for everyone however. Usually, this approach is mainly preferred by small-scale companies like startups. These services lets you get started quickly and without the need for an abundance of technical knowledge, but it has its drawbacks. Once you get to the point of growth where you need to hire dedicated infrastructure or DevOps engineers, you need a more structured approach to running your applications. This is where orchestration comes into play.
Orchestration means to take care of running your applications in the most optimal way possible. Using a good orchestrator, you simply declare how you want your applications to be run, and the orchestrator will handle all the under-the-hood mechanics of getting the containers to run the way you want them to.
For example, imagine that you have a webshop. Using containers, it’s very uncommon that you would only have a single instance of your webshop frontend running. Perhaps your webshop has grown quite big, and you want to run ten or 100 instances of your application. In this case, you would just tell Kubernetes to spin up the number of services you want, and it will make sure to create that amount of healthy instances. If an application suddenly fails, Kubernetes will know and it will kill it, immediately spinning up a new instance hoping that it was an ephemeral error.
This is a very simple overview of how Kubernetes works. A detailed overview of Kubernetes would cover multiple articles, as it also has support for a ton of other features way more complex, like autoscaling, controlling ingress, and running jobs on an interval.
When to Use Which?
As you can see, these two tools serve very different use cases. Rather than trying to figure out which tool to use, it’s more important to figure out when one of these two tools should be used. You’ll often find that you should be implementing both, especially as your company scales.
Docker will be the tool you use in the beginning of your toolchain. It’s the tool you will use to define an image of your application, which can then later be run as a container. With Docker, you are preparing your application to be run in production.
Once your application is fully ready to be deployed, you’ll start using Kubernetes to run it. Handing it over to Kubernetes, the tool will then take care of running the application and handle any incoming requests to the application.
Is Kubernetes the Only Orchestration Tool?
At this point, you may be wondering whether this means that you should use Kubernetes when you are containerizing applications. The simple answer is no. There are also other alternatives to using Kubernetes, like Docker Swarm. Docker Swarm is the orchestration tool that was developed by the Docker company as a solution to orchestrate containers. With Kubernetes coming out on June 7th 2014, and Docker Swarm being launched October 16th 2014, it was up to the community to decide which tool was the most appropriate to use for orchestration. It quickly became clear that the community much preferred working with Kubernetes, which is why you’re way more likely to hear about Kubernetes today than Docker Swarm.
It’s also important to understand that orchestration isn’t a new concept at all, and Kubernetes is just the tool for container orchestration. In the past, other tools have existed to help with orchestrating non-containerized applications, like DC/OS. However, in 2015 DC/OS saw the tendency in the industry and decided to sunset the platform in favor of becoming focused on providing a Kubernetes platform. This was a clear sign that Kubernetes was quickly becoming the preferred way of orchestrating workloads.
Does Kubernetes use Docker?
With all this talk about how Docker and Kubernetes works together, you’d imagine that Kubernetes uses Docker under the hood. The truth is that it doesn’t. With Kubernetes, you can choose what runtime you want to use, and at a point it was indeed possible to use Docker as the container runtime. However, for a long time this hasn’t been the default, with Kubernetes instead opting to use containerd as the runtime, which is an OCI-compliant runtime.
A while ago, Kubernetes decided to remove the dockershim, thereby removing the possibility of using Docker as the runtime completely. There are a few reasons for this, with the main one being that Docker mostly works as a GUI for developers, not a runtime that is easy to use for computer systems like Kubernetes. Most likely, this isn’t going to be relevant for you when using Kubernetes, as it doesn’t have any effect on regular applications. However, it’s a good thing to know. For example, if you are thinking about running CI/CD pipelines in Kubernetes, this means you can’t use the popular principle of Docker-in-Docker.
Now you know more about what the purpose of both Docker and Kubernetes is. You know that Docker is the tool to use when you need to develop and prepare your applications to be run, and Kubernetes is the tool to use when you need to get your applications deployed. You also know that it’s possible to find alternatives to Docker to orchestrate your containers. Lastly, you know that Kubernetes doesn’t actually use Docker, but instead uses an OCI-compliant runtime like containerd.
If you end up wanting to run your applications in Kubernetes, it’s important to know that your applications are running as expected, either by performing load testing or mocking services. In those cases, as well as during API debugging and contract testing, you can check out Speedscale.