Case Study | Kubernetes
When containers were first introduced in 2008, Virtual Machines, or VMs, were the state-of-the-art option to optimize a data center’s physical resources. This arrangement worked well enough, but had some flaws: Virtual machines utilized too many resources because they required both a complete operating system, and emulated instructions to reach the physical CPU. The goal of containers is to maximize resource utilization to reach a similar bare-metal performance with the advantages of VMs. To do this, a common kernel is shared to all applications that can choose any operational resources as necessary. In other words, containers can run on bare metal while sharing resources, but without being able to access other containers’ resources.
How do containers ensure high availability, disaster recovery, or scalability? Container orchestration systems such as Kubernetes (nicknamed K8S) offer a solution. The systems are responsible for handling one or multiple clusters of machines and detect the availability of each image running on it. The size of the clusters can range from three machines to more than thousands of machines and containers, distributed among different cloud providers if needed. If a machine breaks down, the tool should be able to shift its containers to another node while keeping the entire cluster operational.
First released in 2014, Kubernetes is an open-source container orchestration tool that can automatically scale, distribute and manage fault tolerance on containers. Originally created by Google and then donated to Cloud Native Computing Foundation, Kubernetes is widely used in production environments to handle Docker containers and other container tools in a fault-tolerant manner. As an open-source product, it is available on various platforms and systems. The popularity of Kubernetes has steadily increased, with more than four major releases in 2017. K8s also was the most discussed project in GitHub during 2017, and was the project with the second most reviews.
Kubernetes offers a new way to deploy applications using containers. It creates an abstraction layer which can be manipulated with declarative rather than imperative programming. This way, it is much simpler to deploy and upgrade services over time. K8s can be deployed in very different scenarios depending on the size of the company and its objectives:
- In-house: Organizations can transform their own data center into a K8s cluster. In this case, companies can take full advantage of their own resources.
- Cloud: The setup process is similar to an in-house deployment, but includes virtual machines on the cloud. This allows for the creation of a virtually infinite number of machines, depending on demand.
- Hybrid: An organization’s data center might perform well for most of the day, but sometimes a peak occurs that local computing resources cannot handle. In this case, a hybrid solution works well. When necessary, K8s will create virtual machines on the cloud to better distribute computing resources when on-premise servers are full.
- On-premise: Some cloud providers have their own K8s implementation embedded. In this case, there is no need to deploy and configure Kubernetes itself; an organization just needs to manage the service. Since deploying Kubernetes can be tricky, this is a good solution for companies that do not have a big IT team capable of handling cluster configuration and maintenance.
- Multicloud: This is the next level of a hybrid cloud solution. Computing resources are deployed among two or more cloud vendors. In this case, companies need to avoid vendor lock-in and minimize risk if something goes wrong.
We have selected some common use cases to demonstrate Kubernetes’ capabilities. The use cases can be utilized together for different setups.
Self-Healing and Scaling Services
For simplicity, K8s process units can be detailed as pods and services. A pod is the smaller deployment unit available on Kubernetes. A pod can contain several containers that will have some related communication — such as network and storage. Services are the interface that provides accessibility to a set of containers. These services can be for internal or public access and can load balance several container instances.
Pods are mortal: once finished, they vanish from the cluster. Pod termination can be natural or through an error. A deployment is the most modern Kubernetes module to create and maintain pods. Using a single description file, a developer can specify everything necessary to deploy, keep running, scale, and upgrade the pod.
Serverless, with Server
Serverless architecture has taken the world by a storm since AWS launched Lambda. The principle is simple: just develop the code, and don’t worry about anything else. Server and scalability are handled by the cloud provider and code just has to be developed as functions that handle specific events: from HTTP requests to queue messages.
Vendor lock-in is the major disadvantage of this solution. It almost impossible to change cloud providers without refactoring most of the code. There are some solutions like Serverless that seek to standardize function code across clouds. Another solution is to use a Kubernetes cluster to create a vendor-free serverless platform. As mentioned above, K8S abstracts away the difference between cloud servers. Currently, two popular frameworks virtualize the cluster as a serverless platform: Kubeless and Fission.
Optimized Resource Usage with Namespaces
A K8s namespace is also known as a virtual cluster. Namespaces create a virtually separated cluster inside the real cluster. Clusters without namespaces probably have test, staging and production clusters. Virtual clusters usually waste some resources because they do not undergo continuous testing, and because staging is used from time to time to validate the work of a new feature. By using a virtual cluster, or a namespace, an operations team can use the same set of physical machines for different sets depending on a given workload.
Hybrid and Multiclouds
A hybrid cloud utilizes computing resources from a local, conventional data center, and from a cloud provider. A hybrid cloud is normally used when a company has some servers in an on-premise data center and wants to use the cloud’s unlimited computing resources to expand or substitute company resources. A multicloud, on the other hand, refers to a cloud that uses multiple cloud providers to handle computing resources. Multiclouds are generally used to avoid vendor lock-in, and to reduce the risk from a cloud provider going down while performing mission-critical operations.
Both solutions are addressed by Kubernetes Federation. Multiple clusters — one for each cloud or on-premise data center — are created that are managed by the Federation. The Federation synchronizes computing resources, and even allows cross-cluster discovery: virtually any pod can communicate with a pod in another cluster without knowing the infrastructure.
Pinterest’s Kubernetes Story
With over 250 million monthly active users and serving over 10 billion recommendations every single day, the engineers at Pinterest knew these numbers are going to grow day by day, and they began to realize the pain of scalability and performance issues.
Their initial strategy was to move their workload from EC2 instances to Docker containers; they first moved their services to Docker to free up engineering time spent on Puppet and to have an immutable infrastructure. The next strategy was to move to Kubernetes. Now they can take ideas from ideation to production in a matter of minutes, whereas earlier they used to take hours or even days. They have cut down so much overhead cost by utilizing Kubernetes and have removed a lot of manual work without making engineers worry about the underlying infrastructure.
“By moving to Kubernetes the team was able to build on-demand scaling and new failover policies, in addition to simplifying the overall deployment and management of a complicated piece of infrastructure such as Jenkins,” says Micheal Benedict, Product Manager for the Cloud and the Data Infrastructure Group at Pinterest. “We not only saw reduced build times but also huge efficiency wins. For instance, the team reclaimed over 80 percent of capacity during non-peak hours. As a result, the Jenkins Kubernetes cluster now uses 30 percent less instance-hours per-day when compared to the previous static cluster.”
Pokemon Go’s Kubernetes Story
How was Pokemon Go able to scale so efficiently became so successful? The answer is Kubernetes. Pokemon Go was developed and published by Niantic Inc., and grew to 500+ million downloads and 20+ million daily active users.
Pokemon Go engineers never thought their user base would increase exponentially to surpass expectations within a short time. They were not ready for it, and the servers couldn’t handle this much traffic.
Pokemon Go also faced a severe challenge when it came to vertical and horizontal scaling because of the real-time activity by millions of users worldwide. Niantic was not prepared for this.
The solution was in the magic of containers. The application logic for the game ran on Google Container Engine (GKE) powered by the open source Kubernetes project. Niantic chose GKE for its ability to orchestrate their container cluster at planetary-scale, freeing its team to focus on deploying live changes for their players. In this way, Niantic used Google Cloud to turn Pokémon GO into a service for millions of players, continuously adapting and improving. This gave them more time to concentrate on building the game’s application logic and new features rather than worrying about the scaling part.