In the cloud world, containers are the center point of a growing majority of deployments. By providing compartmentalization of workloads and the ability to run “serverless”, containers can speed up and secure deployments and create flexibility unreachable by old style application servers. This, of course, opens up a new arena of infrastructure - orchestrating the containers and the code within.
While a variety of tools have been developed to meet this need, none are as impactful to the industry as Kubernetes. It has emerged as the de facto container orchestration tool for many companies. Google created Kubernetes and released a version as open-source to the general public. It is now one of the flagship products looked after by the Cloud-native Computing Foundation (CNCF).
Kubernetes containers are portable, extensible, open-source platforms for managing containerized workloads and services, that facilitate both declarative configuration and automation. Containers are decoupled from the underlying infrastructure and you can port them across various clouds and kubernetes clusters.
To fully understand Kubernetes, first let’s look at how Kubernetes functions to solve various deployment challenges. If we back up far enough, we see traditional infrastructure deployments that include physical servers running application frameworks and serving the application(s) - in this case there are no true resource bounds for any onboard application and a server tasked with delivering more than one may be faced with underperformance as one app binds the lion’s share of available resources.
The opposite problem could often also be found - over-sized servers sitting idle, trapping financial and processing resources during times of low utilization. Many organizations struggled with scaling such solutions and finding the correct balance of upfront costs against future resource needs. Not ideal.
This gave rise to the next iteration of infrastructure - virtualization. Virtual Machines provided the ability to assign host resources more granularly and isolate workloads. Certain scalability challenges were solved with the ability to spin up additional virtual machines as needed, and consolidated hardware resources. However, each virtual machine was also running it’s own version of the operating system and all associated services, meaning the baseline resource needs were that of the entire OS, prior to adding any application workloads.
And that brings us to containers. Like their VM counterparts, each container has resources allocated to it (storage, CPU, RAM, etc.) but unlike VMs, they do not each require its own version of the OS. This boundary is relaxed allowing all containers to to share the base infrastructure, while isolating their workloads. As a result, containers are far more lightweight and flexible - they are highly elastic and resource efficient.
However, to truly harness the power of containers, they need management and orchestration. This is where Kubernetes enters the picture and takes the lead. Containers, just like VMs or physical servers, need proper management to achieve high availability. Kubernetes provides the framework to support scalable deployments - load balancing, storage management, and deployment automation and orchestration.
With new architecture comes new DevOps workflows. Containers alone cannot achieve the many goals associated with Continuous Integration, Delivery, and Deployment (CI/CD). By orchestrating with Kubernetes, the true power of containers is unleashed and DevOps pipelines can be automated in new and better ways.
Containers allow us to break out applications and services into self-contained microservices and connect them together, all while keeping their resource workloads separate. Each container can be updated or changed independently of all others - code can be pushed in smaller chunks and faults are easier to identify and correct.
Kubernetes provides a deep framework for connecting and managing these containers - from grouping microservices into application groups, to dynamically and efficiently placing each container for maximized resource benefit. Pair these functions with Kubernetes’ ability to create high availability deployments via automations and you have the ability to build a seamless pipeline that supports your development objectives and business goals. Let’s dig in deeper on how Kubernetes supports DevOps and the CI/CD pipeline.
First up is one of the most critical for a functional pipeline - deployment automation. In this case we are talking not only about automating code deployment but also deployment of containers and supporting infrastructure. New containers can be spun up automatically, in response to numerous triggers. Because of how Kubernetes handles configuration, anything that can be defined can be automated.
Kubernetes is declarative, meaning that you define your state and Kubernetes will attempt to achieve and maintain that state. A YAML configuration file can be created and stored in a Git repository, meaning it’s changes can be tracked like all other code. This configuration can define multiple aspects of your infrastructure deployment, including the container parameters, pods (groups of linked containers), and load balancers. The Kubernetes ConfigMap allows you to define application configurations and environment variables. Secret objects allow you to store passwords, OAuth tokens, and SSH keys external to the container, meaning they are easy to secure and update without having to rebuild the container image each time there is a change. This is often referred to as GitOps - as Git becomes the “single source of truth” for aspects of the deployment.
Through the declarative nature of the Kubernetes framework, automated rollouts and rollbacks become simplified through version control. When new code is ready to be pushed to a container, the new desired state is defined and Kubernetes orchestrates the creation of new containers and removal of existing ones. Should problems arise, the immutable nature of Kubernetes containers allows easy rollbacks to the previous state.
Kubernetes, through the use of these configurations, can easily scale infrastructure up and down based on the resource needs of the application. Additional containers can be built on the fly to serve additional load, for example, sudden and increased calls to a web service - new containers can come online to meet the additional demand and then be automatically destroyed when no longer needed, all based on defined parameters. This allows just-in-time allocation of resources without needing to oversize or over-allocate resources or any one service or container in anticipation of increased demand.
Your infrastructure and pipeline is not required to all be in the same cloud or all on-premises. With Kubernetes, your containers can be anywhere your infrastructure is, whether in the data center or across various clouds. Containers can be easily migrated thanks to compartmentalized workloads.
The need for frequent deployments is handled beautifully by Kubernetes thanks to the features we have already described. When time to push new code, the new configurations are pushed to the repository and Kubernetes begins spinning up new containers and deploying the updated code while coordinating the removal of the old. Should a service or container stop, Kubernetes can automatically restart it. Using liveness and readiness probes, Kubernetes can wait until the new deployment is healthy before destroying the old. And if both health checks fail, a single command can roll everything back.
Kubernetes has demonstrated itself as a solid and logical orchestration solution - it makes it easy to properly configure and works properly straight out of the box. From the smallest startup to the largest enterprises, Kubernetes has transformed DevOps and how we build and deploy software.
10 Infrastructure-as-code tools for automating deployments in 2022
DevOps observability: What is it and how to implement it?
Ace Your DevOps Game With this Ultimate List of Plugins in Jenkins