Containerization

Kubernetes #1

By 01/28/2019 January 30th, 2019 No Comments

Kubernetes is an open-source orchestrator project enabling launching of containerized applications. At the beginning, this project was created by Google which brought it to life, inspired by many years of creating and running highly scalable systems in containers, through the orientation of the API application. Kubernetes, however, is much more than just a technology provided by Google.
Presently, this is an entire community working on the ever-richer ecosystem that this project has become. Thanks to the release of this software from of Google for the Open Source community, Kubernetes has become a platform that meets the requirements of, not only huge, highly scalable gaming web infrastructures, but it has also allowed to create infrastructure for cloud-native applications to smaller players who have only a few hosts.

Okay, let’s shake off this new-sexy-it gibberish and let’s get to the point. Let’s start by explaining what the scalable applications and the API-oriented platform are praised by bards in their songs. Let’s imagine a hypothetical situation when we have been tasked to run the infrastructure under the application for a constant load generated by a defined number of users, but (!) the load can change at any moment, increase to tens of thousands or hundreds of thousands or more.

Probably, this situation isn’t something uncommon – there is no thing better than well defined requirements of the application… but speaking honestly, this one cannot be defined, because you never know if the application will catch on and expand, especially at the very beginning of its operation. No one knows the behavior patterns of future users, mistakes in the code, issues requiring optimization. In order, for the example to become more real, let’s have a look at it trough the example of a well-known and liked platform enabling communication via web-cams. Of course, we’re not talking about the pages that you just thought of… oh, no, no! We’re talking about tutoring portals, for example. Let us move on. Normally, this site will have 2-3 thousand users, they all watch something, communicating etc. However, there are times in a year, or the day when tutors from Asian countries have to educate their clients on the other side of the globe, during their evening (we do know that tutoring happens always after work, regular classes, etc.).

So suddenly, on the page that was based on 5-10 instances of the application, we need a lot more of them in a matter of seconds. The standard monolithic architecture of the application would be uncomfortable here, you would have to add processors to VMs, add RAM, etc. This makes for poor scaling. Let’s imagine that one VM with the configuration of 4 vCPU and 64GB RAM served about 1000 users. The application kept the data and, in general, as soon as our potential client came to a given server, they stayed there (they were fixed, for example by means of a session). When the number of users went up, it was necessary to quickly, using a hand-operated mechanism, examine whether we had already saturated the server, or maybe someone else will fit in or use a load balancer to scatter the traffic. When we were lacking it was necessary to run out and get a new server. On paper, it seems trivial but in reality, it’s hard and will take up a lot of time. But we are only talking about scaling up. What about scaling down? Changing the version? Possible malfunctions? This is just one big massacre.

So, another approach was developed. What if, instead of large VMs you have small containers (or small VMs) performing a very specific function – e.g. one handling the login, the other is queuing messages (e.g. queries in GUI, messages between users etc.), the third is responsible for communication with the database, or just being the database? They all communicate with each other using API – that is, one could say, using an internal language of the application sent in the REST style, using JSON, YAML etc. (formal languages, universal and independent of the language in which the application is written). In addition, apart from the possible databases, none of the elements of the application infrastructure stores data, it’s just responsible for intercepting API data, processing it according to its function, forwarding to subsequent instances responsible for subsequent functions. So, generally speaking, instead of one huge binary and an army of libraries located on the monstrous VM, we have many binaries and many sets of libraries placed on many VMs or, in the case of Kubernetes containers, our microservices.

At the beginning it may seem unnecessarily complicated but let’s think that when we treat each of these functions as a defined infrastructural structure (e.g. in the code), calling them automatically turns out to be more natural. A smaller application requires relatively fewer dependencies and consequently its configuration during installation or upgrade may be simpler, end up with fewer errors. Because it does not hold user data, it is not associated with it. Thus, each user can go to another node of application servers each time, and this means that we do not have to worry about how some piece of infra will fall … or we will update it. Such an application can be written in different languages (depending on the module), which will communicate with each other using the API. Everything sounds wonderful … so where is the catch?

The proverbial hook is that the such new-wavy-jazzy-funky applications need an infrastructure platform that will support them. Why? Because pure Linux or bare VMs are too harsh to implement such a scalable, self-healing infrastructure – it would be disgustingly complicated and laborious. It would require either a huge number of hours of work involving the creation of vending machines or a huge technological pile for probably quite a sum of money… And finally, after months of difficult and arduous work, you would write Kubernetes.

The article has been published on IT Professional.