Kubernetes is a Container Orchestrator open sourced by Google in 2014. Today it’s by far the most widespread orchestration tool on the market. Kubernetes has changed the IT landscape permanently. But what is an orchestrator? What makes Kubernetes so special? How does it work? These and more questions will be covere d in this blogpost.
I’d like to do a historical excurse to make it more tangible. So, let’s start at the very beginning. With containers. You can skip this if you are already familiar with Docker or other OCI compliant container technologies.
Exactly these super practical boxes that are used for shipping. The first containers were already used in the 18th century to simplify loading from ships to rail and vice versa. The containers commonly used nowadays have been internationally standardized in the 1960s. Besides significantly cutting the loading times, the common size also allows a much more efficient distribution of workload.
It’s no wonder that these advantages have also been well received in IT. In 2014 finally a company called Docker reached the mainstream. With Docker containers we finally got a format to package our application together with its runtime and libraries. This allows a great portability and since all containers on a single host run on the same Linux kernel, they are very efficient as well.
Just like the container for trading goods, containers in IT got standardized by the Open Container Initiative. And this is how we got alternative container runtimes like containerd or container image builder like Buildah.
What is Kubernetes?
While having a container and the container runtime is already quite feasible, we still got some significant problems:
- What happens if our container runtime is not available anymore?
- How can we split workloads across different machines?
- How to ensure an application is actually running?
- How can we communicate between the different applications?
- How to ensure every container has the computing resources it needs?
Container and their runtimes don’t give answers to these questions. This is where the container orchestrator comes in place.
If we stay at the transportation container analogy you can think of an orchestrator as a port authority that manages the container. It decides where each container will be stored or when it can be loaded. When a container is damaged the owner will be informed.
Today’s most popular orchestrator is Kubernetes (also short k8s). k8s was initially developed and open sourced by Google in 2014. The idea was based on Borg, the orchestrator Google uses internally. You can read more about the history in this blogpost by one of the founders of Kubernetes.
Kubernetes schedules your containers, balances them on the different server nodes, detects failures (via liveliness checks) and even tries to fix them for you. Kubernetes obviously knows all containers it executes. So, you can find all services there.
Of course, Kubernetes can do so much more. If you are interested, you can check the official documentation. I think you get the idea.
How does Kubernetes work?
A basic Kubernetes setup usually consists of at least one master node and 1…n worker nodes. In the easiest constellation both can be on the same machine. But this is obviously not recommended for productive usage.
The master permanently compares the current cluster state with the state you declared as desired. If there is a deviation, it tries to restore it. In Kubernetes this is called the reconciliation loop.
The worker nodes are the nodes where your actual applications will run. Every worker node has a lightweight agent called the kubelet that registers at the master to receive their commands. The kubelet makes sure your container is running and healthy.
Do you remember our analogy from before? With the port authority and the container? If Kubernetes is the port authority, then we obviously also need the ships. Let’s call them Pods. A Pod encapsulates an application’s container (or, in some cases, multiple containers), storage resources, a unique network IP, and options that govern how the container(s) should run. This is the smallest unit Kubernetes can actually handle.
I have talked about a desired state several times now. But how do we actually declare that? Well here is an example of how to define a simple Pod in YAML:
apiVersion: v1 kind: Pod metadata: name: myapp-pod labels: app: myapp spec: containers: - name: myapp-container image: busybox command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 3600']
There are different kinds of resources like Pod, Service, Deployment, DeamonSet etc. The metadata block is always the same for all kinds. They only vary in the specification (spec). As you can see here for Pods, we only define a list of containers that should be scheduled. In this cast we only execute a busybox container (minimal Linux distro). And within that container we execute a small shell script. That’s it!
This was my small introduction into the Kubernetes world. I hope you enjoyed it and it helped you to understand a bit about what Kubernetes does and how it works.
In the next blogpost we will install a first Kubernetes Cluster locally and play around a bit to get more familiar.
See you then! :)