Background
If you have been reading this blog you probably already know that my career has primarily been on the development side and I have never really done much operations. I have worked in organisations where development and operations were completely separate and also in organisations where devs ran and operated the applications they developed.
However, since December 2021, I embarked on a new adventure, one that was going to change my life forever.
I took on leadership of the Cloud Infrastructure teams at Kaluza. Yea, teamS, plural. This was a very different kind of challenge for me for many reasons, some of which are:
- I was going to lead a team of engineers who were experts in domains that I had little or no knowledge of
- I wouldn’t be able to guide them technically at all - well, maybe a little - from the basics of software engineering and computer science, but beyond that, would be stretch.
But being an engineering manager responsible for delivery and results through people development primarily, did I have to be the expert in the technologies that my team used?
As you progress in your career and take charge of larger teams and departments comprising of several people, 10s to 100s or more, your daily hands-on technical contributions will diminish, pretty quickly. You’ll be looking after the people responsible for maintaining and building those systems that you are accountable for. So you better be good at hiring the right people and asking the right questions at the right time.
This was a slightly difficult pill to swallow and every engineering manager with whom I shared this mismatch of background and team specialisation was like “Wow! you are brave!”. But there is nothing to be brave about this. The primary function of an engineering manager at my organisation is to ensure my people have the right skill-set and mindset and growth opportunities and are able to thrive in the role they are doing. Else it is my responsibility to create an environment where they can thrive. That’s how you ensure your organisation runs efficiently, by putting the right people in the right roles, that’s how you get things done.
However, as I took on this role, I realised that it is immensely useful to understand the language of my team. Of course, we speak English at work in the UK. Most of us come from a Computer Science background from university or school or several years of work experience. Thus we can all talk through a system design.
However, when it comes to specialisations, like Kubernetes, there is a certain domain language that I need to familiarise myself with, in order to be on the same page with the team. Else they would have to explain terminologies with every other term, slowing down discussions by magnitudes. This is something that can be learned over time by being around experts in the domain. And I have a habit of surrounding myself with all sorts of media and people to learn as much as possible about the technical stuff that my team works on, which has been immensely useful for me.
So what I intend to do here is to share some resources and present some concepts in Kubernetes that will help you grasp them relatively easily. This is why this series is titled Kubernetes Simplified. I do have another series in the works which is Kafka simplified. But I’ll release that later.
I don’t intend to dive deep into the concepts with practical examples and things. I intend to keep it at a high enough level for you to manage or develop applications that would be deployed on a Kubernetes cluster.
Kubernetes
Before we start talking about Kubernetes though, it is best to understand the WHY. Why did such a thing come into being? Why did engineers feel the need to make something like kubernetes in the first place?
Let’s look at some of the things that inspired the creation of Kubernetes. This post is primarily background information. But it’ll give you an idea of the evolution of software development and deployment that will help you appreciate Kubernetes better.
Traditional software deployment
Once upon a time, probably in the early noughties (2000s) or maybe slightly before that, we ran applications on physical servers. Operations (Ops) teams were responsible for purchasing the hardware required to ensure all applications could run smooth and do what they are supposed to do. Developers were asked to forecast data growth or the growth in application scale and applications were deployed on servers where they often had to share resources with not much control over how much of a certain type of resource, an application could or should consume. One or more applications would be deployed to a server. Sometimes a load balancer was put in place and multiple physical servers were setup behind this load balancer and multiple instances of the application would be deployed to various servers. Traffic to the application would be controlled using the load balancer software.
Challenges with this approach
- Resource hogging - an app could consume more resources than it should and negatively impact other apps on the same server. There was a lack of isolation at the application level.
- Poor resource utilisation - If the server was underutilised during a period of time, all that expensive hardware is wasted. The magnitude of waste was directly proportional to the scale at which the applications were deployed!
Virtualisation of hardware
This was the phase when companies still had physical servers but provisioned virtual machines for their applications to run. So a server with 32 cores would have a VM that consumed a certain number of cores and memory. This introduced a level of isolation that was unavailable in bare metal servers earlier! Applications running on VM 1 on machine A couldn’t access resources of another application running on VM 2 on the same machine.
Virtualisation allowed better utilisation of resources on the servers. It also enabled better scalability as applications could be added and updated easily compared how it was done before, reducing hardware costs by a magnitude that was unimaginable until then.
One physical server could be virtualised into a cluster of virtual machines!
Challenges
Each VM was still a full machine running its own operating system and applications and dependencies all on top of virtual hardware. Thus the minimum resources required to run multiple virtual machines was still quite a lot compared to what we do today with containers.
Containerisation of applications
Containers are the next level of what enabled us to better utilise resources on physical servers. They are a way of bundling applications and dependencies built for a certain processor architecture and operating system combination - thereby enabling you to deploy multiple containers on a machine with a certain operating system. Each container in this context could be a different app or different instances of the same app. They are basically an isolation mechanism on the host machine’s operating system that separates one app’s resource view from another app.
If you are confused, I’d strongly recommend reading this answer on stackoverflow. Or you could read an earlier post I wrote about this topic going slightly more into the details of the differences between containers and virtual machines.
Containerisation comes with various advantages:
- Faster deployments and creation of apps - compared to VM images, container images are a lot quicker to build and deploy
- DevOps separation - container images are published at build time, deployment is separate. Thus developer workflow is unaware of runtime infrastructure.
- Improved observability as you are able to surface OS level metrics and other information]
- Environment consistency - Application runs the same on the same OS on any hardware
- All of the qualities described earlier contributes to making loosely coupled distributed, elastic microservices.
- Resource utilisation and isolation improvements - run more containers on same machine and isolation ensures one app performance doesn’t impact another.
Challenges here
As we embrace microservices architecture, there will be a large number of containers to manage in production. Thus you need to manage all these and ensure there is no downtime. Imagine having to write all the software that would do that for you. A system that ensures your containers are constantly running and serving what it is supposed to, no matter what error it encounters. That’s what Kubernetes is. It takes care of scaling you application and failovers, it provides deployment patterns and much more.
What kubernetes gives you
A whole load of goodies if you ask me.
I don’t know if there is a point in listing them all here but I’ll definitely share some highlights and you can read all of it in the official kubernetes docs
- Service discovery and load balancing: exposes a container using DNS name or IP address, It also does load balancing to distribute network traffic and ensure that traffic to containers are manageable.
- Storage orchestration - manages mounting of storage - any system that you choose, local, public cloud etc.
- Automated rollouts and rollbacks - declaratively describe the desired state for your containers and Kubernetes will deal with getting to that state.
- Automated bin packing - You give kubernetes a cluster of nodes to use for running containerised tasks. You then define how much CPU and memory each container needs. Kubernetes then takes care of which node a container can run on to make the best use of available resources.
- self healing - automatically restart containers that fail, replaces containers, kills containers that do not respond to the health check that you defined and only exposes your containers when they are ready to serve requests.
- secret and config management - store and manage sensitive information like tokens, ssh keys, passwords and deploy and update such secrets without rebuilding your container images.
- Horizontal scaling - scaling your app up and down with a command, through UI or automatically based on resource usage
That sounds amazing! So I guess then everyone must be using Kubernetes already! Let’s hold that thought. Let’s explore why someone might not want to use Kubernetes.
What k8s is not?
Kubernetes is a container orchestration system, which enables you to run a distributed system well. However, if you only have a handful of applications that are distributed then going through learning and understanding Kubernetes to run them might be overkill.
Kubernetes is not a Platform as a Service, i.e. it does not hide the operating systems from the applications. It is very much a building block of a PaaS but not in itself a PaaS.
Kubernetes is not a Continuous integration or continuous deployment solution. It doesn’t build your application. It does not come out of the box with middleware like message buses, databases, or data processing frameworks, although with some learning, you could configure such services to run on kubernetes.
It is highly flexible, and this means, it comes with some (sensible) defaults but you have to know what you are doing to run a Kubernetes cluster.
Although I used the word orchestration earlier, Kubernetes, eliminates the need for orchestration. Where orchestration means - coordination a series of steps to execute in a certain order, Kubernetes continuously drives the current state towards a certain desired state, which is defined through configuration.
Outro
That’s the end of the first post but the beginning of many in this series. I hope that keeps you interested. I’ll try to make this consumable in other ways to enable you to breeze through this content easily.