If you have always worked on monolithic architecture, you would have never crossed roads with Kubernetes (K8s). But you did hear about it. Right?
So, what the heck is this Kubernetes? I wondered for a long time till I got a project in microservices. Kubernetes is simpler than you think. It is really awesome.
In this article, I will scratch the surface of Kubernetes to introduce you with this technology. With the time, I will create more articles and take you on a ride of being a complete beginner to an expert Kubernetes developer.
Introduction
Suppose you are developing an application and want to serve it to millions of users. What will you require to make it scalable? A large number of servers? A load balancer? Database shards? What if you got a sudden huge traffic at one night? What if a server failed? How will you manage all this?
In order to cater all these problems, Google open sourced a technology called Kubernetes. This is production ready, highly scalable and developed with more than 15 years of experience in Google tech.
In Single Line…
Kubernetes is a framework which manages containerized applications (like docker) and does a lot of tasks automatically to scale the application.
But wait.. now what are containerized applications? What is a docker? 😁Don’t worry. We will learn everything today (in simple words).
Server vs Virtual Machines vs Containers
Let’s understand why containers are better than servers and virtual machines.
Servers
Servers are bare metal machines with operating system and options to install different software. You can easily deploy your monolithic application created in php, python, java, nodejs, ruby, rust etc. BUT… for a small application with less load, your CPU, memory will be underutilized and will go waste. For big application, you will need more servers and then upload your application on them and take care of load balancing and all. And what if your traffic went down? Either you will end up paying for extra server or switch it off. In any case, it’s a big trouble.
Also, in servers you can run multiple applications. So, you can run 10 different websites. But there is no proper way to allocate resources to them. You can’t easily allocate a part of CPU and memory to each website. So, maybe a single website utilize a lot of resource and let all others be unresponsive. You won’t know if you need a new server or more resources or just need to transfer that website to another machine.
Virtual Machines
Virtual Machines are used to virtually abstract a server into several small servers. Now we can easily run different websites on different virtual machines i.e. in different environments. All the resources will be allocated separately to all the virtual machines and hence they can’t interfere in each other. One problem solved.
But.. they are heavy weight. They have their own operating systems. A good portion of CPU and memory gets utilized by many operating systems unnecessarily.
Also, you will need to take care of scaling them yourself. If your website is loaded, you will need to run another virtual machine and deploy your application there. Or, you may increase or decrease resources, if available. If a machine failed, you will need to handle it too.
Some examples of virtual machine software are VMWare, VirtualBox, Hyper-V etc.
Containers
Just like virtual machines, containers are also used for abstraction. But, unlike virtual machines they are light weight. They share the operating system of container framework. So, they are universally consistent. You can deploy them anywhere and they will behave the same. The containers running on your local machine will be same as server as well as cloud providers like GCP, AWS, Azure etc. Docker is a container.
Together with container management framework like Kubernetes, we can easily automate a number of tasks required for scaling an application. You won’t need to take care of container failure, restarts, image creation, replication etc.
What Kubernetes can do?
Now you understood about containers. You application runs inside a container. Generally this architecture is used in microservices where we break our big application into some separate and independent applications. They all communicate through APIs or gRPC or Publisher/Subscriber system like SQS.
To manage these containers like automatically run them, restart them, increase/decrease their counts, load balance, provide authentication keys or secret keys, setting environment variables, assigning DNS and ip etc. we need a manager which Kubernetes is.
Kubernetes doesn’t interact with your application. It can’t build your application. The sole functions of K8s are related to containers and their management only.
It can do these tasks –
- Automatically create, stop, restart the clusters and deploy your application to them. Also assign DNS, IP address to them. This way you can have many clusters running on many physical servers but no need to worry about setting them. Kubernetes will handle all.
- It can load balance among multiple clusters and effectively send traffic to less strained containers. It’s the same tech which Google uses in their production servers. Very effective.
- It can manage your secret keys, oAuth tokens, passwords etc. securely.
How to work with Kubernetes?
In this article we won’t go deep and keep things simple. In future articles we will cover everything. But at this moment, we will give you a basic idea.
First of all, you must be thinking how applications are deployed on clusters? Suppose you create a Java project and you know that it starts from Main.java
file where we have our main()
method. There are two kinds of files to handle things – Kubernetes config files and Docker config files.
In Docker config file, you indicate everything you want to do when container starts. Here you create a command-value code. With it, you can install libraries, copy your code from local directory to container directory and indicate which file to run to start your program. This way your application will run. Here is a sample docker file (Just for reference. You don’t need to understand it right now) –
FROM golang:1.15-alpine AS build WORKDIR /src/ COPY ./ /src/ RUN apk add --no-cache ca-certificates git RUN CGO_ENABLED=0 GO111MODULE=on go build -o /bin/order-api FROM alpine:3.6 COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ COPY --from=build /bin/order-api /bin/order-api RUN mkdir -p /bin/config COPY --from=build /src/config/* /bin/config/ EXPOSE 8084 WORKDIR /bin/ ENV EXECUTION_CONTEXT=docker ENTRYPOINT ["./order-api"]
This file says that the container is running golang
project. We have copied the ssl certificates from our local machine to container. Similarly, we have copied the build from local machine to container. We opened 8084 port to run this project. At last we give command ./order-api
in ENTRYPOINT
to run application.
This file set up your application on container. You build the application locally and then run the executable in container.
To manage such containers, we use Kubernetes config file. There are different config files for different jobs like one for creating containers known as deployment file, one for security keys, one for setting DNS or ingress etc. Let’s see a deployment file –
apiVersion: apps/v1 kind: Deployment metadata: name: order-api labels: app: order-api namespace: prod spec: replicas: 2 selector: matchLabels: app: order-api template: metadata: labels: app: order-api spec: containers: - name: order-api image: 831022063613.dkr.ecr.us-east-1.amazonaws.com/project-fm/order-api:v1.0.59 imagePullPolicy: Always ports: - containerPort: 8084 protocol: TCP env: - name: EXECUTION_CONTEXT value: kubernetes
This is a deployment file. You don’t need to understand any of this yet. We will discuss this all in upcoming articles. Just understand few things like –
- We create Kubernetes configuration files either in
yaml
orjson
format. Here we used yaml format. - We indicate what kind of config file it is. Here we created a
Deployment
file which is responsible for creating/removing/updating pods or clusters. - We give value to a property
replicas
. This ensures the total number of pods to be created for this microservice. So if the value is 2, it will run 2 pods with same environment, code and everything and load balance them. Hence, if you are getting a lot of traffic, simply increase this count and run deployment command (which we will learn later). You are now ready to handle more and more traffic. And if resources turns out to be exhausted, you can always rent new server and increase pods there. - We can set the container image. Here we are using Amazon ECR which is a docker image and accessing its 8084 port (Recall, we opened this port in our docker file above).
- Also, we can set some environment variables to be accessed by containers.
Conclusion
Are you able to understand anything with this article? If yes, then it’s a huge success for me. These technologies ain’t so difficult, the only issue is the lack of right resources. Everywhere people feed so much information that it get’s so hard to digest. In this whole series, I will try my best to explain in steps and in a way that beginners can understand. I wish you a wonderful coding. Meet you in the next article.
Kubernetes Series
- Introduction to Kubernetes
- Introduction to Docker, Containers, Images & Repository
- Install and Run Docker Images
- Docker Image – FROM, RUN, COPY, ENTRYPOINT, CMD, EXPOSE explained
- Why docker run or start command not running my container?
- How to list all docker images in system?
- How to list all docker containers?
- How to start/stop a docker container?
- Difference between docker run and docker start
- How to bind docker container port with host?
- How to get logs of docker container?
- How to live stream logs of docker container?
- Set custom name to a docker container
- Access docker container filesystem & terminal
- Getting docker details using docker inspect
- Kyverno – Installation, Policies, Testing, Reporting, Monitoring, Security
- Complete Kubernetes Project Step By Step
- Introduction to Kubernetes Objects