This article highlights the view from a user perspective, not so much from a system architecture perspective. Every section will give a quick recap of what you should have understood at this point. If you don’t understand it, try to read it again before you move on or read one of the additional information links.
In software engineering, the complexity of a problem is hidden behind layers of abstraction. This is also true for Kubernetes as it masks the complexity of orchestrating containers behind a less complex user interface. The rest of the article moves up the layer of abstraction until we reach the interface that helm provides.
Why We Need Containers – Making Software Portable
A developer usually starts coding and developing his application locally on his personal machine. This means not only writing his code but also using libraries of the underlying system or third parties. He might even develop a system consisting of two applications to solve the business problem at hand.
Once the system reached its first stable version he wants to deploy it to a server so that people can actually test and use it. This means he needs to package his software with all the external dependencies and move it to the server, which often leads to software working locally but failing on the server.
Developers need to debug and determine which dependency is different on the server, compared to their local machine. This is where containers and container runtimes (e.g. Docker) come to the rescue. Containers allow developers to package and ship their software, by creating an isolated image that can be run on any other machine that has the same container runtime and architecture – containers make software portable.
Recap: Containers enable packaging software in portable units, to make them run on any machine that has the same container runtime so that a developer does not need to manually ensure that all hosts have the same capabilities.
Why We Need Kubernetes – Scaling a System
While containers solve the problem of portability of software, several problems arise once we want to scale our system. As mentioned before a system can consist of several applications – e.g. imagine Google, which has its search engine, Gmail, Docs, calendar, etc. This means you have to deploy several containers, and in addition, the more consumers the more you have to scale your applications.
You can scale an application vertically or horizontally. Vertically means you put more computational power on your host so that it can process a larger load of users. Horizontallymeans you have multiple copies of the same application running on different hosts to serve more consumers, which is more flexible as you can adjust the number of hosts to the number of consumers.
This means you need to deploy several containers on many hosts and also need to make sure that applications are aware of each other. Therefore, you either need to write a piece of software or manually keep track of the mapping of containers and hosts. If a new version of an application is deployed, you need to update the containers on the respective hosts. Moreover, if a container fails you need to find the correct host and restart the container – In a nutshell, you need to orchestrate or manage your containers, which is exactly what Kubernetes is doing for you.
As mentioned above, this article will not discuss the system internals of Kubernetes, but it briefly highlights a High-Level view. A Kubernetes cluster consists of at least one master node and several worker nodes. The worker nodes serve as the hosts for the containers, whereas themaster node acts as the brain of the cluster and distributes containers between the worker nodes.
The master node also hosts the API server that allows the developers to interface with the Kubernetes cluster, in other words, to pass containers and the configurations, which should run on the cluster. The configurations are a set of yaml files that describe the desired state of Kubernetes resources. For instance, there is a deployment.yaml file that describes which container image should be run, how many instances should be run, and how much computational power one instance should get. In addition a service.yaml is used to describe how the deployment can be accessed by other services.
Along with that you often add artifacts like configmap.yaml or secrets.yaml, which holds values that should be injected as environmental variables when a container is started. While this is a lot of configuration, the work pays off. Kubernetes will take those configurations and deploy your application across the cluster, allowing you to scale it up and down within seconds. It constantly compares the status of the cluster to the provided desired state and tries to match it. This means if your application just stopped working, it will try to spin up a new instance of your service – it becomes a self-healing system.
Recap: A cluster is a set of host machines with a Kubernetes cluster being a self-healing system. It constantly compares and matches the actual state to the desired state. Therefore, it allows to manage and maintain containerized applications across multiple hosts by providing a set of yaml files that describe the desired state.
Why We Need Helm – Creating Deployment Templates
As mentioned above deploying applications to Kubernetes requires several configurations kept in several files. This is not a big problem if you deploy your system only once, but as soon as you start building generic systems, you might have to deploy the system several times and only slightly change some variables. This means you need to go into the individual files and adjust those values.
This is precisely where Helm comes into play. Helm is a tool that allows you to create deployment templates. This template is called a helm chart, which consists of the yaml files that look more or less like a regular Kubernetes yaml file but have some variables in them. Those variables can be defined through an additional values.yaml file.
So instead of manipulating the values directly, you can simply set them in the values.yaml file. Helm then injects those values into the files and creates your deployment configuration for you. So within one file, you can deploy complex systems within minutes. The idea is to share helm charts in repos, just like it is happening in docker with docker hub.
In addition, Helm allows you to keep track of your charts and allows you to roll back to a previous version of your chart, so-called revisions. This makes it easy to roll back in case a deployment has failed.
Recap: Helm is a templating tool that allows you to create deployment bundles, which you can share and customize by specifying certain values. This enables you to deploy services quickly and makes releases reproducible, so you can roll back a release when needed.