Kubernetes is a container orchestration tool. It is used for managing the life cycle of containers. It does away with the manual process of deploying and scaling containerized workloads. It was initially developed by Google but is currently managed by the Cloud Native Computing Foundation.
In this article, we will talk about what Kubernetes is, why it is a preferred tool for container orchestration, the underlying architecture of Kubernetes, and some Kubernetes objects you are most likely to come across while working with Kubernetes.
Kubernetes is a tool for elegant orchestration of complex business requirements, such as highly available microservices, and is one of the enabling technologies of the 12-factor application.
We can hardly speak of Kubernetes without mentioning containers. Kubernetes is built upon the foundation of containers. Containers have been of significant benefit to the software development field, specifically in the deployment process. Some of the benefits containers bring to the table are portability, agility, speed, immutability, idempotency and fault isolation.
While containers have become a standard for deployment across several platforms because of the benefits they bring, they also introduce some level of complexity in application workloads. Some of these complexities affect monitoring, data storage, security and orchestration. It is these challenges presented by containers that Kubernetes solves.
There are several container orchestration tools such as Docker Swarm, Google Container Engine, Amazon ECS, Azure Container Service, CoreOS fleet and others, each with their own unique offerings. However, Kubernetes is the most popular and has become the de facto standard for container orchestration. This is largely because it is open source, has many options it offers and has a large community that supports and uses it.
Kubernetes, as the most popular container orchestration platform, plays an integral role in orchestrating many enterprise applications. For those considering Kubernetes, it's good to have a basic understanding of how Kubernetes works, and why it has managed to claim such a large market share. Let's start with a comparison.
The definition of Kubernetes we listed at the start of the blog is well known in many business technology communities. However, a second statement (while less recognized) is just as important:
Kubernetes is NASCAR.
I should clarify that I don’t mean Kubernetes is NASCAR in the same way that Kubernetes SIG Security co-chair, CNCF Ambassador, and chaotic goose Ian Coldwater means this, which is that there are so many logos vying for eyes in the Cloud Native landscape that it would make even the ghost of Ol’ Dale Earnhart blush.
What's that? Is that like NASCAR
— Ian Coldwater :package::boom: (@IanColdwater) November 13, 2020
What's that? Is that like NASCAR
What I mean by this statement is that the architecture of Kubernetes is all about these steps:
So, in essence, Kubernetes is NASCAR.
Kubernetes is a free and open source software derived from Google’s Borg code, with an initial release in June of 2014
Kubernetes is free to use for all organizations, and uses the is released under the Apache 2.0 license. There are many contributors and a plethora of vibrant communities supporting it. As enterprise-grade software build for the enterprise, there’s quite a few players participating and vying for attention in the marketplace (see NASCAR).
There are several cloud platforms that provide Kubernetes as a service. These platforms make your work easier by providing you with an interface that makes it easy to deploy applications on Kubernetes without having to worry about setting up and managing the various components of your cluster. Some of them are:
Everything (!) in how Kubernetes is implemented comes down to GoLang goroutines. If you’re not from a team that’s doing Go(lang), you might be more familiar with the now-ubiquitous programming model of Node.JS’s event-loop architecture for web, except goroutines are way more performant.
After much research and photoshop, I am proud to give you the finalized #nodejs System diagram. pic.twitter.com/HMEWN11jAr
— Totally Radical Richard 🤙 (@TotesRadRichard) July 31, 2014
After much research and photoshop, I am proud to give you the finalized #nodejs System diagram. pic.twitter.com/HMEWN11jAr
Why does Kubernetes need a performant concurrency system? Because Kubernetes, as a platform, orchestrates the events required to reach an eventually consistent (read: future) state described in YAML or JSON by the Kubernetes API.
Let’s take a look at the basic unit of Kubernetes, the Pod. Containers are run inside pods, and a pod can have more than one container. Pods in Kubernetes are ephemeral in nature: when they are destroyed all data they generate that is not stored in persistent storage is lost.
If I send this API object to Kubernetes, the responsibility of Kuberenetes will be to ensure that the state described in the API object is represented in the system. In this case, that there’s a Pod (collection of containers) named ‘postgres’ running the ‘postgres’ image and listening for that traffic on port 5432, checking that the port is listening after 5 seconds, and every five seconds thereafter, and finally running the command ‘pg_isready’ to ensure that, at the application level, postgres is ready to handle requests on that listening port.
Lots of work to do! And that there might be thousands of these pods, and thousands more still of other API objects such as Deployments, ReplicaSets, Persistant Volume Claims, Services, and more? To think that all of this state management can happen on much smaller virtual (!) hosts than you might expect.
The Kubernetes Control Plane () takes care of this at breakneck speed, asynchronously firing off events to other parts of the system, which process these requests in order. If the previously instantiated postgres container crashes (into a barrier wall, to the cheer of the crowd)? The Kubernetes Control Plane immediately (without remorse, or pause for reflection, the trophy in glinting in their eyes) fires off an event to begin working towards rebuilding the state requested.
Kubernetes in one thought? Eventually-consistent orchestration of containers and supporting elements by a fast event loop. In one word? NASCAR.
Other Kubernetes objects you are likely to use in the deployment process are:
ReplicaSets ensure that the correct number of pods are always running at any given time. They keep track of the desired number of pods and the current number of pods running in the cluster. They can be used to deploy pods but the recommended approach is to use deployments.
Deployments are used for managing pods. They are preferred to ReplicaSets. Deployments also use ReplicaSets for managing pods. When a deployment is created, it first creates a ReplicaSet which then creates the pods. Deployments have extra functionality and can be used to automatically rollout new changes or rollback to a previous version of your app.
In Kubernetes, a service is used to expose pods. Each pod is assigned its own IP address, and a set of pods are given a single DNS. Traffic coming into pods is load-balanced. There are different types of services, such as LoadBalancer, ClusterIP, and NodePort. When this service is created it is assigned an IP address, and every other object that wants to communicate with pods this service is attached to can use the IP address of that service.
Ingress helps to manage external access to services in the cluster. An ingress controller is installed in the cluster, and then an ingress rule is set up for a particular service(s). Using these rules, the ingress controller will automatically redirect traffic to specific services based on the paths specified.
Secrets are used for storing and managing sensitive data that are to be made accessible to pods running in the cluster. The data stored in secrets are usually small and in text format.
There are several other Kubernetes objects such as configmaps, daemonsets, namespaces and even custom resources. The ones mentioned here are the ones you will most likely interact with when deploying simple applications in Kubernetes.
Kubernetes is used for orchestrating server resources to be highly available and up to date. It is, after all, cluster management software at it’s core.
However, the original intention behind Kubernetes was to fulfil large organizations' desires to implement concepts like DevOps and the 12-Factor Application without having to re-invent the wheel. It’s an open source standard for accomplishing the architectural patterns required to do both DevOps and 12-Factor.
Kubernetes, specifically the Kubernetes Control Plane, is composed of a component services following the event-loop architecture:
All together, they’re responsible for ensuring that any API objects we send the kube-api-server get implemented as running containers and component services.
In Kubernetes, applications are deployed to clusters. A cluster is a group of nodes that work together to handle your application workload. Clusters consist of the master and worker nodes. It can have one or more master nodes and zero or more worker nodes. Clustering helps in fault tolerance. For example, you can have multiple nodes on the same cluster running the same containers. If one of the nodes fails, the other nodes can handle the traffic coming into the application.
The master node is the node that controls and manages the worker nodes. For example, it is responsible for scheduling and also detecting/responding to events on the cluster. The components of the master node make up the control plane of the cluster.
Cloud-control-manager: Kubernetes uses cloud controllers to provide a consistent standard across different cloud providers. The cloud-control-manager is used to manage controllers that are associated with specific cloud platforms. These controllers abstract resources provided by these cloud platforms and map them to Kubernetes objects.
The nodes handle most of the work in the Kubernetes clusters. While the master is responsible for organizing and controlling the nodes, containers are run on the nodes, they also relay information back to the master, and use network proxies to manage access to the containers. The components of the node are:
Addons make use of Kubernetes resources to implement cluster features. If an addon is namespaced, it is placed in the kube-system namespace. Some of these addons are:
Autoscaling: Just as with horizontal scaling, Kubernetes can also provision new pods (to run containers) to handle traffic as the need arises. When the requests reduce, it also kills the pods to suit the current needs of the system. It does this automatically, and you don’t need to interfere. Just define this in your object configuration file, and Kubernetes will do the rest for you.
Self-healing: Sometimes things can go wrong with the containers running your application. Maybe they stop service traffic because of an error with one of them. Kubernetes has health checks that help identify when these containers are healthy. If they are not, the pods housing these containers are restarted or killed. New ones are then provisioned immediately to replace the old ones. This prevents your applications from having downtime.
Load balancing: Kubernetes exposes containers/pods using DNS names. Sometimes, they may be multiple pods running the same application in containers. Kubernetes manages the routing of traffic between these multiple pods. You can also provision a load balancer easily using the Kubernetes LoadBalancer service type and also set up an ingress to route traffic to different services. When there is high traffic to the pods, Kubernetes can also provision new pods and distribute traffic to these pods to create a balance.
Secrets management: One challenge faced in the deployment process is managing secrets and making sure that you do not expose sensitive information about your application. Kubernetes provides a secure system of storing and updating these secrets without rebuilding your containers or exposing them. The secrets are also easily accessible by your running applications.
Storage orchestration: Another challenge faced with deployed applications is persistent storage. With Kubernetes, you can easily provision persistent storage and mount it to your running containers.
Automatic rollouts and rollbacks: In your object configuration file, you can specify the current state of your containers, and Kubernetes will automatically remove the existing (old containers) and rollout new ones based on the specification. You can also rollback to previous versions of your deployed applications in case there is an error with the newly deployed one.
Automatic bin packing: Kubernetes can schedule pods on specific nodes based on their required resources and other restrictions defined for them. For example, a particular container may require a machine that has a certain CPU or Memory capacity. Kubernetes will only schedule those pods on the nodes that have such resources. Also, if a particular machine has insufficient resources to run a particular pod, Kubernetes can schedule the pod on another node that can support it.
Cost management: Because of its auto-scaling capacity, Kubernetes helps in saving costs. For example, imagine you run a business, and at festive seasons the traffic to your website increases. This means that you may need to get more processing power (machines or CPU or Memory). Before Kubernetes, it may mean that you have to purchase new hardware. If you are using a cloud platform, you may need to manually provision new resources for your machines. This may increase the chances of introducing errors since you have to configure your machines and set up load-balancing or be a waste of resources since you may not need the resources you purchase anymore.
Kubernetes creates these resources on-demand and destroys them immediately there is no need for them. It eliminates errors since the state of your resources has already been defined in your object configuration file and it is done automatically. It also saves you cost since you do not need to purchase resources you do not need at a later time.
Resource allocation: In Kubernetes, you can specify the resources that your different containers should request and the limits of their consumption. This way, you can properly utilize the resources that are available on your machines.
If you saw the list above, and you're still asking yourself why you might want to use Kubernetes, ask yourself instead how you’re supposed to achieve all of this at once:
Dump the big-iron mainframe!
Runs on commodity hardware in any public or private cloud
Reduce cloud costs!
Improves elasticity of resources
Keep my CISO happy!
Security quality gates for deployed software, rolling patching of deployments
Keep my developers happy!
One of the most in-demand technologies and skills
Keep my QAC team sane!
Enables CI/CD and DevOps practices at scale
Horizontal Pod Autoscaling scales with sensors like CPU use, (autoscaling/v1) or whatever you choose (autoscaling/v2beta2)
Future-proof my storage strategy while capitalizing on existing investments!
Persistent Volume Claims, and auto-provisioning of SAN resources, like Trident for NetApp
Kubernetes is here to stay, and will be relevant for a long, long time. It’s only going to get more important as architectures change to ARM in the datacenter: concurrency is king.
With as many logos on it’s jacket as we’ve shown, it’s going to be very important to a lot of people. Yes, more important than NASCAR.
If you're considering Kubernetes for your application, OpenLogic can help plan and support your journey. Talk to an expert today to see how OpenLogic can help.
TALK TO AN EXPERT
Looking for additional reading on Kubernetes, containers, or container orchestration? These resources are worth your time: