Skip to content

Instantly share code, notes, and snippets.

@krishnamurthydasari
Last active February 16, 2024 12:54
Show Gist options
  • Save krishnamurthydasari/fde5409852f2549791be7765c4b4441e to your computer and use it in GitHub Desktop.
Save krishnamurthydasari/fde5409852f2549791be7765c4b4441e to your computer and use it in GitHub Desktop.
Kubernetes Introduction
What are containers?
Containers are completely isolated environments, as in they can have their own processes or services, their own network interfaces, their own mounts, just like Virtual machines, except that they all share the same OS kernel.
What is Orchestrator?
Orchestrator is a platform which enables to control connectivity between containers and automatically scale up or down based on the load. This whole process of automatically deploying and managing containers is known as Container Orchestration.
What is Node?
A node is a machine physical or virtual on which kubernetes is installed. A node is a worker machine and this is were containers will be launched by kubernetes.
It was also known as Minions in the past. So you might here these terms used interchangeably.
What is Master node?
Master is another node with kunernetes installed and it is configured as a master. The master watches over the nodes in the cluster and it is responsible for actual orchestration of containers on the worker nodes.
Kubernetes Components
When you install Kubernetes on a System, you are actually installing the following components.
API Server
ETCD service
Kubelet service
Container Runtime
Controllers
Schedulers
1) The API server acts as the frontend for kubernetes. The users, management devices, Command line interfaces all talk to the API server to interact with the kubernetes cluster.
2) Next is the ETCD key store. ETCD is a distributed reliable key value store used by kubernetes to store all data used to manage the cluster. Think of it this way, when you have multiple nodes and multiple masters in your cluster, etcd stores all that information on all the nodes in the cluster in a distributed manner. ETCD is responsible for implementing locks within the cluster to ensure there are no conflicts between the Masters.
3) The scheduler is responsible for distributing work or containers across multiple nodes. It looks for newly created containers and assigns them to Nodes.
4) The controllers are the brain behind orchestration. They are responsible for noticing and responding when nodes, containers or endpoints goes down. The controllers makes decisions to bring up new containers in such cases.
5) The container runtime is the underlying software that is used to run containers. In our case it happens to be Docker.
6) And finally kubelet is the agent that runs on each node in the cluster. The agent is responsible for making sure that the containers are running on the nodes as expected.
Commands:
=========
kubectl get nodes
What is the flavour and version of Operating System on which the Kubernetes nodes are running?
kubectl get nodes -o wide
How many number of nodes including master node?
kubectl get nodes
Kubernetes version?
kubectl version --client (without --client it tries to show server version as well, with --client it only shows kubectl client version)
Minikube install:
=================
1) Install Kubectl
curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl
it is just a executable, so download it and add to the PATH
2) Install Hypervisor
In order to install Minikube, you need to have hypervisor. you can install virtualenv or any other hypervisors for this purpose.
But without hypervisor, you can install with docker runtime. (basically install runtime docker and then proceed with minikube install with --driver=none)
If you have virtualenv hypervisor then you dont need to add any nodes. when you install minikube, it will add one VM automatically.
3) Install Minikube
yum install docker
curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
chmod +x minikube
install minikube /usr/local/bin/ (adding to path)
yum install conntrack
minikube start --vm-driver=none
minikube status
PODS:
======
Kubernetes does not deploy containers directly on the worker nodes. The containers are encapsulated into a Kubernetes object known as PODs. A POD is a single instance of an application. A POD is the smallest object, that you can create in kubernetes.
PODs usually have a one-to-one relationship with containers running your application. To scale UP you create new PODs and to scale down you delete PODs. You do not add additional containers to an existing POD to scale your application.
Multi-Container PODs -
Now we just said that PODs usually have a one to one relationship with the containers, but, are we restricted to having a single container in a single POD? No! A single POD CAN have multiple containers, except for the fact that they are usually not
multiple containers of the same kind. If our intention was to scale our application, then we would need to create additional PODs. But sometimes you might have a scenario were you have a helper container, that might be doing some kind of supporting task for our web application such as processing a user entered data, processing a file uploaded by the user etc. and you want these helper containers to live along side your application container. In that case, you CAN have both of these containers part of the same POD, so that when a new application container is created, the helper is also created and when it dies the helper also dies since they are part of the same POD. The two containers can also communicate with each other directly by referring to each other as ‘localhost’ since they share the same network namespace. Plus they can easily share the same storage
space as well.
Create POD -
kubectl run nginx --image=nginx (this gets image from public docker hub)
kubectl get pods
[root@ip-172-21-0-78 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 48s
this will show Name of the POD (nginx), number of containers in POD (1/1) and status
kubectl describe pods (descibes all pods)
kubectl describe pod nginx (describes nginx pod)
kubectl get pods -o wide (this gives which node pod is running and node ip address)
[root@ip-172-21-0-78 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 9m58s
[root@ip-172-21-0-78 ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 1/1 Running 0 10m 172.17.0.3 ip-172-21-0-78.eu-west-2.compute.internal <none> <none>
YAML:
=====
It is a language to define data structures. Similar to XML and JASON. YAML file is used to represent data (a configuration data)
Key value pair:
Fruite: Apple
Vegetable: Carrot
Liquid: Water
Meat: Chicken
Keys and values are seperated by a : and to differentiate between keys and values, there should be a space after :
Arrays/Lists:
Fruites:
- Orange
- Apple
- Banana
Vegetables:
- Carrot
- Cauliflower
- Tomato
Dash (-) in the next line of any key represents that key as array or a list
Dictionary/Map:
Banana:
Calories: 105
Fat: 0.4g
Carbs: 27g
Grapes:
Calories: 62
Fat: 0.3g
Carbs: 16g
You must have equal number of empty spaces for Calories, Flat and Carbs to make Grapes and Banana as disctionary or a Map.
POD with YAML:
==============
Kubernetes uses YAML files as input for the creation of objects such as PODs, Replicas, Deployments, Services etc. All of these follow similar structure.
Example:
pod-definition.yaml -
````````````````````
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
type: front-end
spec:
containers:
- name: nginx-container
image: nginx
```````````````````
A kubernetes definition file always contains 4 top level fields.
apiVersion
kind
metadata
spec
These are top level or root level properties. Think of them as siblings, children of the same parent. These are all REQUIRED fields, so you MUST have them in your configuration file.
apiVersion:
The first one is the apiVersion. This is the version of the kubernetes API we’re using to create the object. Depending on what we are trying to create we must use the RIGHT apiVersion.
kind:
The kind refers to the type of object we are trying to create, which in this case happens to be a POD. So we will set it as Pod. Some other possible values here could be ReplicaSet or Deployment or Service, which is what you see in the kind field in the table on the right.
metadata:
The metadata is data about the object like its name, labels etc. As you can see unlike the first two were you specified a string value, this, is in the form of a dictionary. Under metadata, the name is a string value so you can name your POD myapp pod and the labels is a dictionary. So labels is a dictionary within the metadata dictionary. And it can have any key and value pairs as
you wish. For now I have added a label app with the value
kubectl apply -f pod-definition.yaml
Below yaml file will add environment variable to the container: To pass environment variable, add new propertry 'env' to container object. It is a sibling of name and image. env is an array/list, it expects name and value. So below yaml file is to create Postgres POD, with environment variable set as PASSWORD.
````````````````
apiVersion: v1
kind: Pod
metadata:
name: postgres
labels:
tier: db-tier
spec:
containers:
- name: postgres
image: postgres
env:
- name: POSTGRES_PASSWORD
value: mysecretpassword
```````````
Kubernetes Controllers:
======================
Controllers are the brain behind Kubernetes. they are processes that monitor kubernetes objects and respond accordingly. In this lecture we will discuss about one controller in particular. And that is the Replication Controller.
Replication Controller:
=======================
What if for some reason, our application crashes and the POD fails? Users will no longer be able to access our application. To prevent users from losing access to our application, we would like to have more than one instance or POD running at the same time. That way if one fails we still have our application running on the other one. The replication controller helps us run multiple instances of a single POD in the kubernetes cluster thus providing High Availability.
So does that mean you can’t use a replication controller if you plan to have a single POD? No! Even if you have a single POD, the replication controller can help by automatically bringing up a new POD when the existing one fails. Thus the replication
controller ensures that the specified number of PODs are running at all times. Even if it’s just 1 or 100.
rc-definition.yaml
````````````````````
apiVersion: v1
kind: ReplicationController
metadata:
name: myapp-rc
labels:
app: myapp
type: front-end
spec:
template:
metadata:
name: myapp-pod
labels:
app: nginx
type: front-end
spec:
containers:
- name: nginx-container
image: nginx
replicas: 3
`````````````````
Replica Set:
============
It’s important to note that there are two similar terms. Replication Controller and Replica Set. Both have the same purpose but they are not the same. Replication Controller is the older technology that is being replaced by Replica Set. Replica set is
the new recommended way to setup replication. However, whatever we discussed in the previous few slides remain applicable to both these technologies. There are minor differences in the way each works and we will look at that in a bit.
replicaset-definition.yaml
`````````````````
apiVersion: app/v1
kind: ReplicaSet
metadata:
name: nginx-replicaset
labels:
app: nginx
type: front-end
spec:
template:
metadata:
name: nginx-pod
labels:
app: nginx
type: front-end
spec:
containers:
- name: nginx-container
image: nginx
replicas: 3
selector:
matchLabels:
type: front-end
````````````````````
It is very similar to replication controller. As usual, first we have apiVersion , kind, metadata and spec. The apiVersion though is a bit different. It is apps/v1 which is different from what we had before for replication controller. For replication controller it was simply v1. If you get this wrong, you are likely to get an error that looks like this. It would say no match for kind ReplicaSet , because the specified kubernetes api version has no support for ReplicaSet. The kind would be ReplicaSet and we add name and labels in metadata.
The specification section looks very similar to replication controller. It has a template section were we provide pod definition as before. So I am going to copy contents over from pod definition file. And we have number of replicas set to 3. However, there is one major difference between replication controller and replica set. Replica set requires a selector definition. The selector section helps the replicaset identify what pods fall under it. But why would you have to specify what PODs fall under it, if
you have provided the contents of the pod definition file itself in the template? It’s BECAUSE, replica set can ALSO manage pods that were not created as part of the replicaset creation. Say for example, there were pods created BEFORE the creation of
the ReplicaSet that match the labels specified in the selector, the replica set will also take THOSE pods into consideration when creating the replicas.
But before we get into that, I would like to mention that the selector is one of the major differences between replication controller and replica set. The selector is not a REQUIRED field in case of a replication controller, but it is still available. When you skip it, as we did in the previous slide, it assumes it to be the same as the labels provided in the pod definition file. In case of replica set a user input IS required for this property. And it has to be written in the form of matchLabels as shown here. The matchLabels selector simply matches the labels specified under it to the labels on the PODs. The replicaset selector also provides many other options for matching labels that were not available in a replication controller.
create replicaset using below command
kubectl create -f replicaset-definition.yaml
kubectl get replicasets
kubectl get pods
kubectl delete pod podname
kybectl describe replicaset replicasetname
Scale:
------
1) You can update replicaset yaml file with desired number of pods and use below command
kubectl replace -f replicaset-definition.yaml
2) You can use scale command to scale up pods. This option helps scaling number of PODs in replicaset but it will not change anything in hte replicaset-definition.yaml file.
kubectl scale --replicas=6 -f replicaset-definition.yaml
or, you can use replicaset name
kubectl scale replicaset nginx-replicaset --replicas=6
Replcaset commands:
-------------------
kubectl create -f replicaset-definition.yaml
kubectl get replicaset
kubectl delete replicaset nginx-replicaset
kubectl replace -f replicaset-definition.yaml
kubectl scale --replicas=6 -f replicaset-definition.yaml
kubectl scale replicaset nginx-replicaset --replicas=6
kubectl edit replicaset nginx-replicaset (this command edits running configuration, again this will not chage actual yaml file you have)
**same scale or replace commands can be used to scale down and scale up replicas in replicaset.
Deployments:
============
Say for example you have a web server that needs to be deployed in a production environment. You need not ONE, but many such instances of the web server running for obvious reasons.
Secondly, when newer versions of application builds become available on the docker registry, you would like to UPGRADE your docker instances seamlessly. However, when you upgrade your instances, you do not want to upgrade all of them at once as we just did. This may impact users accessing our applications, so you may want to upgrade them one after the other. And that kind of upgrade is known as Rolling Updates.
Suppose one of the upgrades you performed resulted in an unexpected error and you are asked to undo the recent update. You would like to be able to rollBACK the changes that were recently carried out. Finally, say for example you would like to make multiple changes to your environment such as upgrading the underlying WebServer versions, as well as scaling your environment and also modifying the resource allocations etc. You do not want to apply each change immediately after the command is run, instead you would like to apply a pause to your environment, make the changes and then resume so that all changes are rolled out together.
All of these capabilities are available with the kubernetes Deployments.
So far in this course we discussed about PODs, which deploy single instances of our application such as the web application in this case. Each container is encapsulated in PODs. Multiple such PODs are deployed using Replication Controllers or Replica Sets. And then comes Deployment which is a kubernetes object that comes higher in the hierarchy. The deployment provides us with capabilities to upgrade the underlying instances seamlessly using rolling updates, undo changes, and pause and resume changes to deployments.
**So how do we create a deployment. As with the previous components, we first create a deployment definition file. The contents of the deployment definition file are exactly similar to the replicaset definition file, except for the kind, which is now going to be Deployment.
deployment-definition.yml
`````````````````````
apiVersion: app/v1
kind: Deployment
metadata:
name: myapp-deployment
labels:
app: myapp
type: front-end
spec:
template:
metadata:
name: myapp-pod
labels:
app: nginx
type: front-end
spec:
containers:
- name: nginx-container
image: nginx
replicas: 3
selector:
matchLabels:
type: front-end
`````````````````````
Deployment Commands:
--------------------
kubectl create -f deployment-definition.yaml
kubectl get deployments
kubectl get pods
kubectl describe deployment myapp-demployment
kubectl get all (this will list all objects deployments, replicasets and pods)
Deployments - Update and Rollback and Versioning
================================================
Before we look at how we upgrade our application, let’s try to understand Rollouts and Versioning in a deployment. Whenever you create a new deployment or upgrade the images in an existing deployment it triggers a Rollout. A rollout is the process of
gradually deploying or upgrading your application containers. When you first create a deployment, it triggers a rollout. A new rollout creates a new Deployment revision. Let’s call it revision 1. In the future when the application is upgraded – meaning
when the container version is updated to a new one – a new rollout is triggered and a new deployment revision is created named Revision 2. This helps us keep track of the changes made to our deployment and enables us to rollback to a previous version of
deployment if necessary.
Rollout commands
-----------------
You can see the status of your rollout by running the command: kubectl rollout status followed by the name of the deployment.
kubectl rollout status deployment/myapp-deployment
To see the revisions and history of rollout run the command kubectl rollout history followed by the deployment name and this will show you the revisions.
kubectl rollout history deployment/myapp-deployment
Deployment strategy:
--------------------
There are two types of deployment strategies. Say for example you have 5 replicas of your web application instance deployed.
One way to upgrade these to a newer version is to destroy all of these and then create newer versions of application instances. Meaning first, destroy the 5 running instances and then deploy 5 new instances of the new application version. The problem with this as you can imagine, is that during the period after the older versions are down and before any newer version is up, the application is down and inaccessible to users. This strategy is known as the Recreate strategy, and thankfully this is NOT the default deployment strategy.
The second strategy is were we do not destroy all of them at once. Instead we take down the older version and bring up a newer version one by one. This way the application never goes down and the upgrade is seamless.
Remember, if you do not specify a strategy while creating the deployment, it will assume it to be Rolling Update. In other words, RollingUpdate is the default Deployment Strategy.
Deployment:
-----------
So we talked about upgrades. How exactly do you update your deployment? When I say update it could be different things such as updating your application version by updating the version of docker containers used, updating their labels or updating the number of replicas etc. Since we already have a deployment definition file it is easy for us to modify this file. Once we make the necessary changes, we run the kubectl apply command to apply the changes. A new rollout is triggered and a new revision of
the deployment is created.
kubectl apply -f deployment-definition.yaml
But there is ANOTHER way to do the same thing. You could use the kubectl set image command to update the image of your application. But remember, doing it this way will result in the deployment definition file having a different configuration. So you must be careful when using the same definition file to make changes in the future.
kubectl set image deployment/myapp-deployment nginx=nginx:1.9.1
Recreate and Rolling Update:
----------------------------
The difference between the recreate and rollingupdate strategies can also be seen when you view the deployments in detail. Run the kubectl describe deployment command to see detailed information regarding the deployments. You will notice when the Recreate strategy was used the events indicate that the old replicaset was scaled down to 0 first and the new replica set scaled up to 5. However when the RollingUpdate strategy was used the old replica set was scaled down one at a time simultaneously scaling up the new replica set one at a time.
How udpate works:
-----------------
When a new deployment is created, say to deploy 5 replicas, it first creates a Replicaset automatically, which in turn creates the number of PODs required to meet the number of replicas. When you upgrade your application as we saw in the previous slide, the kubernetes deployment object creates a NEW replicaset under the hoods and starts deploying the containers there. At the same time taking down the PODs in the old replica set following a RollingUpdate strategy.
This can be seen when you try to list the replicasets using the kubectl get replicasets command. Here we see the old replicaset with 0 PODs and the new replicaset with 5 PODs.
Rollback:
---------
Kubernetes deployments allow you to rollback to a previous revision. To undo a change run the command kubectl rollout undo followed by the name of the deployment.
The deployment will then destroy the PODs in the new replicaset and bring the older ones up in the old replicaset .
kubectl rollout undo deployment/myapp-deployment
Kubectl run:
------------
This command infact creates a deployment and not just a POD. This is why the output of the command says Deployment nginx created. This is another way of creating a deployment by only specifying the image name and not using a definition file. A replicaset and pods are automatically created in the backend. Using a definition file is recommended though as you can save the file, check it into the code repository and modify it later as required.
kubectl run nginx --image=nginx
Commands Summary:
-----------------
Create:
kubectl create -f deployment.yaml
Get:
kubectl get deployments
Update:
kubectl apply -f deployments.yaml
kubectl set image deployment/myapp-deployment nginx=nginx:1.9.1
Status:
kubectl rollout status deployment/myapp-deployment
kubectl rollout history deployment/myapp-deployment
Rollback:
kubectl rollout undo deployment/myapp-deployment
****************
Kubernetes creates replicas in replicaset or in a deployment one at a time. once 1st replica is created, it will create second replica.
****************
Networking:
===========
Services:
=========
Kubernetes Services enable communication between various components within and outside of the application. Kubernetes Services helps us connect applications together with other applications or users. For example, our application has groups of PODs running various sections, such as a group for serving front-end load to users, another group running back-end processes, and a third group connecting to an external data source. It is Services that enable connectivity between these groups of PODs. Services enable the front-end application to be made available to users, it helps communication between back-end and front-end PODs, and helps in
establishing connectivity to an external data source. Thus services enable loose coupling between microservices in our application.
That is where the kubernetes service comes into play. The kubernetes service is an object just like PODs, Replicaset or Deployments that we worked with before. One of its use case is to listen to a port on the Node and forward requests on that port to a port on the POD running the web application. This type of service is known as a NodePort service because the service listens to a port on the Node and forwards requests to PODs. There are other kinds of services available which we will now discuss.
1) NodePort
2) ClusterIP
3) LoadBalancer
NodePort:
---------
The first one is what we discussed already NodePort were the service makes an internal POD accessible on a Port on the Node. The second is ClusterIP and in this case the service creates a virtual IP inside the cluster to enable communication between different services such as a set of front end servers to a set of backend servers. The third type is a LoadBalancer , were it provisions a load balancer for our service in supported cloud providers. A good example of that would be to distribute load across different web servers.
Let’s take a closer look at the Service. If you look at it, there are 3 ports involved. The port on the POD were the actual web server is running is port 80. And it is referred to as the targetPort , because that is were the service forwards the requests to. The second port is the port on the service itself. It is simply referred to as the port. Remember, these terms are from the viewpoint of the service. The service is in fact like a virtual server inside the node. Inside the cluster it has its own IP address. And that IP address is called the Cluster IP of the service. And finally we have the port on the Node itself which we use to access the web server externally. And that is known as the NodePort . As you can see it is 30008. That is because NodePorts can only be in a valid range which is from 30000 to 32767.
service-definition.yaml
```````````````````````
apiVersion: v1
kind: Service
metadata:
name: front-end
spec:
type: NodePort
ports:
- targetPort: 80
port: 80
nodePort: 30009
selector:
app: myapp
type: front-end
```````````````````````
Let us now look at how to create the service. Just like how we created a Deployment, ReplicaSet or Pod, we will use a definition file to create a service. The high level structure of the file remains the same. As before we have apiVersion , kind, metadata and spec sections. The apiVersion is going to be v1. The kind is ofcourse service. The metadata will have a name and that will be the name of the service. It can have labels, but we don’t need that for now. Next we have spec. and as always this is the most crucial part of the file as this is were we will be defining the actual services and this is the part of a definition file that differs between different objects. In the spec section of a service we have type and ports. The type refers to the type of service we are creating. As discussed before it could be ClusterIP , NodePort , or LoadBalancer . In this case since we are creating a NodePort we will set it as NodePort . The next part of spec is ports. This is were we input information regarding what we discussed on the left side of this screen. The first type of port is the targetPort , which we will set to 80. The next one is simply port, which is the port on the service object and we will set that to 80 as well. The third is NodePort which we will set to 30008 or any number in the valid range. Remember that out of these, the only mandatory field is port . If you don’t provide a targetPort it is assumed to be the same as port and if you don’t provide a nodePort a free port in the valid range between 30000 and 32767 is automatically allocated. Also note that ports is an array.
So note the dash under the ports section that indicate the first element in the array.
You can have multiple such port mappings within a single service.
So we have all the information in, but something is really missing. There is nothing here in the definition file that connects the service to the POD. We have simply specified the targetPort but we didn’t mention the targetPort on which POD. There could be 100s of other PODs with web services running on port 80. So how do we do that?
As we did with the replicasets previously and a technique that you will see very often in kubernetes, we will use labels and selectors to link these together. We know that the POD was created with a label. We need to bring that label into this service
definition file.
kubectl apply -f service-definition.yaml
kubectl get services
***
***
So far we talked about a service mapped to a single POD. But that’s not the case all the time, what do you do when you have multiple PODs? In a production environment you have multiple instances of your web application running for highavailability
and load balancing purposes.
In this case we have multiple similar PODs running our web application. They all have the same labels with a key app set to value myapp. The same label is used as a selector during the creation of the service. So when the service is created, it looks for matching PODs with the labels and finds 3 of them. The service then automatically selects all the 3 PODs as endpoints to forward the external requests coming from the user. You don’t have to do any additional configuration to make this happen. And if you are wondering what algorithm it uses to balance load, it uses a random algorithm. Thus the service acts as a built-in load balancer to distribute load across different PODs.
To summarize – in ANY case weather it be a single pod in a single node, multiple pods on a single node, multiple pods on multiple nodes, the service is created exactly the same without you having to do any additional steps during the service creation. When PODs are removed or added the service is automatically updated making it highly flexible and adaptive. Once created you won’t typically have to make any additional configuration changes.
ClusterIP:
----------
Similar to NodePort, what if we have same requirement but dont want to expose externally via node port? what if front end pods needs to connect to backend pods (when we have multiple backend pods). ClusterIP service type creates a cluster IP to forward request to backend pods but it is not exposed externally like NodePort.
Front end PODS - NodePort/LoadBalancer
Backend app layer - Cluster IP
Backend db layer - Cluster IP
clusterip-definition.yaml
`````````````````````````
apiVersion: v1
kind: Service
metadata:
name: back-end
spec:
type: ClusterIP
ports:
- targetPort: 80
port: 80
selector:
app: myapp
type: front-end
``````````````````````````
Load Balancer:
--------------
We will quickly recap what we learned about the two service types, so that we can work our way to the LoadBalancer type. We have a 3 node cluster with Ips 192.168.1.2,3 and 4. Our application is two tier, there is a database service and a front-end web service for users to access the application. The default service type – known as ClusterIP – makes a service, such as a redis or database service available internally within the kubernetes cluster for other applications to consume.
The next tier in my application happens to be a python based web front-end. This application connects to the backend using Service created for the redis service. To expose the application to the end users, we create another service of type NodePort. Creating a service of type NodePort exposes the application on a high end port of the Node and the users can access the application at any IP of my nodes with the port 30008.
Now, what IP do you give your end users to access your application? You cannot give them all three and let them choose one of their own. What end users really want is a single URL to access the application. For this, you will be required to setup a separate
Load Balancer VM in your environment. In this case I deploy a new VM for load balancer purposes and configure it to forward requests that come to it to any of the Ips of the Kubernetes nodes. I will then configure my organizations DNS to point to
this load balancer when a user hosts http://myapp.com. Now setting up that load balancer by myself is a tedious task, and I might have to do that in my local or on prem environment. However, if I happen to be on a supported CloudPlatform, like Google Cloud Platform, I could leverage the native load balancing functionalities of the cloud platform to set this up. Again you don’t have to set that up manually, Kubernetes sets it up for you. Kubernetes has built in integration with supported cloud platforms.
loadbalancer-definition.yaml
`````````````````````
apiVersion: v1
kind: Service
metadata:
name: front-end
spec:
type: LoadBalancer
ports:
- targetPort: 80
port: 80
selector:
app: myapp
type: front-end
`````````````````````
For example, you have a external load balancer configured on IPs 3.11.251.57 and 18.132.221.215 then you need to use below config file to create loadbalancer type service. This will make PODS listen on port 30008 and can be accessed by external IPs mentioned. You need to configure load balancer to direct requests to service ClusterIP.
apiVersion: v1
kind: Service
metadata:
name: front-end
spec:
type: LoadBalancer
ports:
- targetPort: 80
port: 80
nodePort: 30008
selector:
app: myapp
type: front-end
externalIPs:
- 3.11.251.57
- 18.132.221.215
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment