Kuber Net Es
Kuber Net Es
KUBERNETES
K 8S
WHY KUBERNETES
why KUBERNETES:
Containers are a good and easy way to bundle and run your applications. In a
production environment, you need to manage the containers that run the applications
and ensure that there is no downtime. In docker we used docker swarm for this. but any
how docker has drawbacks!
so we moved to KUBERNETES.
aechitecture:
HOW IT WORKS:
get pods
ETCD
API-SERVER
CLUSTER
1 2 3
How Pod creates:
5. Update the pod
create pods
data ETCD
API-SERVER CLUSTER
1. Request
4. Creates a pod in
worker node
2. Request
Scheduler Kubelet
Worker Node
cluster:
1.API Server
2.ETCD
3. Controllers-manager
4. Schedulers
we have 4 components in Worker Node.
1. Kubelet
2. Kube-Proxy
3. Pod
4. Container
api server:
It is used to accept the request from the user and store the request in ETCD.
It is the only component that interacts with the ETCD directly
ETCD:
It is like a database to our k8's
it is used to store the requests of our cluster like pods, nodes, configs, secrets, roles etc..
scheduler:
It is used to search pending tasks which are present in ETCD.
If any pending task found in ETCD, it will schedule in worker node.
It will decide in which worker node our task should gets executed.
It will decide by communication with the kubelet in worker node
Scheduler always monitor API-Server
The scheduler is a crucial component responsible for assigning pods to nodes
This will ensure that pods are scheduled on suitable nodes that meet their resource requirements
and constraints
HOW SCHEDULER DECIDES
The scheduler is going to decide the put the right pod in right node based on Size, Memory,
CPU etc..
pod-1 pod-3
pod-2
pod
6 cpu
pod
6 cpu
controllers:
The controller Manager collects the data/information from the API Server of the Kubernetes
cluster like the desired state of the cluster and then decides what to do by sending the
instructions to the API Server.
REQUEST
REPLICATION API-SERVER
CONTROLLERS
container:
It is a virtual machine which does not have any OS.
it is used to run the applications in worker nodes.
kubernetes cluster setup:
2 CPUs or more
2GB of free memory
20GB of free disk space
Internet connection
Container or virtual machine manager, such as:
Docker.
UPDATE SERVER:
1 apt update -y
2 apt upgrade -y
INSTALL DOCKER:
3 sudo apt install curl wget apt-transport-https -y
4 sudo curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
INSTALL MINIKUBE:
5 sudo curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
6 sudo mv minikube-linux-amd64 /usr/local/bin/minikube
7 sudo chmod +x /usr/local/bin/minikube
8 sudo minikube version
INSTALL KUBECTL:
9 sudo curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
10 sudo curl -LO "https://dl.k8s.io/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl.sha256"
11 sudo echo "$(cat kubectl.sha256) kubectl" | sha256sum --check
12 sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
13 sudo kubectl version --client
14 sudo kubectl version --client --output=yaml
15 sudo minikube start --driver=docker --force
KUBECTL:
kubectl is the CLI which is used to interact with a Kubernetes cluster.
We can create, manage pods, services, deployments, and other resources
We can also monitoring, troubleshooting, scaling and updating the pods.
To perform these tasks it communicates with the Kubernetes API server.
It has many options and commands, to work on.
The configuration of kubectl is in the $HOME/.kube directory.
The latest version is 1.28
SYNTAX:
kubectl [command] [TYPE] [NAME] [flags]
kubectl api-resources : to list all api resources
Lets start working on kubernetes!
Note:
Kubernetes will not deploy the containers directly on worker nodes.
Kubernetes has a object called POD which contains containers.
Lets learn about PODS
POD:
It is a smallest object that we can create in K8's.
It is a group of containers.
Pod acts like a single instance for our application.
Pods are ephemeral (short living objects)
Mostly we can use single container inside a pod but if we required, we can create
multiple containers inside a same pod.
when we create a pod, containers inside pods can share the same network
namespace, and can share the same storage volumes .
While creating pod, we must specify the image, along with any necessary
configuration and resource limits.
K8's cannot communicate with containers, they can communicate with only pods.
We can create this pod in two ways,
1. Imperative(command)
2. Declarative (Manifest file)
SINGLE CONTAINER POD
Container Container
Pod-1 Pod-2
Node-1
Basically, each pods needs only one container. But sometimes we need
2 containers in one pod.
MULTI CONTAINER POD
App-Cont Helper-Cont
Pod
Node
Helper containers are additional containers included in a pod to perform some tasks that
support the primary container which are running in the pod.
How Helper container works:
A helper container is used to collect the logs from the primary container.
Helper containers can be used to run monitoring and metrics collection agents from
the main application container.
Helper containers can assist in syncing files or data between containers in a pod. For
example, a pod might have a main application container and a helper container
responsible for syncing configuration files or other shared resources.
The Declarativ tive way we need to create a Manifest file in YAML Extension.
This file contains the desired state of a Pod.
It takes care of creating, updating, or deleting the resources.
This manifest file need to follow the yaml indentation.
YAML file consist of KEY-VALUE Pair.
Here we use create or apply command to execute the Manifest file.
CREATE: if you are creating the object for first time we use create only.
APPLY: if we change any thing on files and changes need to apply the resources.
MANIFEST FILE:
apiVersion: This is the version of API from
Kubernetes which is used to create objects.
INSTALLATION:
DOWNLOAD THE FILE: kubectl apply -f https://github.com/kubernetes-sigs/metrics-
server/releases/latest/download/components.yaml
SEE THE DEPLOYMENT: kubectl -n kube-system get deploy metrics-server
EDIT THE DEPLOYMENT : kubectl -n kube-system edit deploy metrics-server
Add these commands under the container args
- /metrics-server
- --kubelet-insecure-tls
- --kubelet-preferred-address-types=InternalIP
MONITOR:
Check the Node metrics: kubectl top nodes
Now create some pods and check the pod metrics : kubectl top pod
Labels, Selectors, and Node Selectors:
Labels:
Labels are used to organize Kubernetes Objects such as Pods, nodes, etc.
You can add multiple labels over the Kubernetes Objects.
Labels are defined in key-value pairs.
Labels are similar to tags in AWS or Azure where you give a name to filter
the resources quickly.
You can add labels like environment, department or anything else
according to you.
Label-Selectors:
Once the labels are attached to the Kubernetes objects those objects will
be filtered out with the help of labels-Selectors known as Selectors.
Node selector means selecting the nodes. Node selector is used to choose the
node to apply a particular command.
This is done by Labels where in the manifest file, we mentioned the node label
name. While running the manifest file, master nodes find the node that has
the same label and create the pod on that container.
Make sure that the node must have the label. If the node doesn’t have any
label then, the manifest file will jump to the next node.
apiVersion: v1
kind: Pod
metadata:
name: pod-1
labels:
env: testing
department: DevOps
spec:
containers:
- name: containers1
image: ubuntu
command: ["/bin/bash", "-c", "while true; do echo This is our Pod; sleep 5 ; done"]
To see the list of pods with labels: kubectl get pods --show-labels
Now, I want to list those pods that have the label env=testing.
kubectl get pods -l env=testing
kubectl get pods -l department!=DevOps
As we have discussed earlier, there are two types of label-selectors
equality and set-based.
This is the example of equality based where we used equalsTo(=).
Now, Suppose I forgot to add the label through the declarative(via
manifest) method. So, I can add labels after creating the pods as well
which is known as the imperative(via command) method.
Lets list all those pods that have an env label with value for either testing
or development.
The reason why we are not able to access the application: In Kubernetes, if you
want to access the application we have to expose our pod. To Expose these pods
we use Kubernetes services.
KUBERNETES SERVICES
Service is a method for exposing Pods in your cluster.
Each Pod gets its own IP address But we need to access from IP of the Node..
If you want to access pod from inside we use Cluster-IP.
If the service is of type NodePort or LoadBalancer, it can also be accessed.
from outside the cluster.
It enables the pods to be decoupled from the network topology, which makes
it easier to manage and scale applications
TYPES:
CLUSTER-IP
NODE PORT
LOAD BALANCER
TYPES OF SERVICES
ClusterIP: A ClusterIP service provides a stable IP address and DNS name for
pods within a cluster. This type of service is only accessible within the cluster
and is not exposed externally.
NodePort: A NodePort service provides a way to expose a service on a static
port on each node in the cluster. This type of service is accessible both within
the cluster and externally, using the node's IP address and the NodePort.
LoadBalancer: A LoadBalancer service provides a way to expose a service
externally, using a cloud provider's load balancer. This type of service is
typically used when an application needs to handle high traffic loads and
requires automatic scaling and load balancing capabilities.
ExternalName: This is a similar object service to ClusterIP but it does have
DNS CName instead of Selectors and labels. In other words, services will be
mapped to a DNS name. You can view the Service YML file and see how to use
this service.
COMPONENTS OF SERVICES
A service is defined using a Kubernetes manifest file that describes its properties
and specifications. Some of the key properties of a service include:
Selector: A label selector that defines the set of pods that the service will
route traffic to.
Port: The port number on which the service will listen for incoming traffic.
TargetPort: The port number on which the pods are listening for traffic.
Type: The type of the service, such as ClusterIP, NodePort, LoadBalancer, or
ExternalName.
CLUSTER-IP:
To deploy the application we create a container, which stores inside the pod.
After container is created we will be not able to access the application.
Because we cannot access the pods and ports from the cluster.
To Avoid this we are creating the Services.
In this code we are exposing the applcation.
here we use clusterip service
By using this we can access application inside
the cluster only.
But if we want to access the application from
outside we need to use nodeport.
ClusterIP will assign one ip for service to
access the pod.
Just Replace ClusterIP=NodePort
kubectl apply -f filename.yml
In this code we are exposed the application from
anywhere (inside & outside)
We need to Give public ip of node where pod is running.
Node Port Range= 30000 - 32767
here i hae defined port number as 30001
if we dont specify the port it will assign automatically.
kubectl apply -f filename.yml.
NodePort expose service on a static port on each node.
NodePort services are typically used for smaller
applications with a lower traffic volume.
To avoid this we are using the LoadBalancer service.
Just Replace NodePort=LoadBalancer
In LoadBalaner we can expose application externally with the
help of Cloud Provider LoadBalancer.
it is used when an application needs to handle high traffic
loads and requires automatic scaling and load balancing
capabilities.
After the LoadBalancer service is created, the cloud provider
will created the Load Balancer.
This IP address can be used by clients outside the cluster to
access the service.
The LoadBalancer service also automatically distributes
incoming traffic across the pods that match the selector
defined in the YAML manifest.
access : publicip:port and LB url
http://a0dce056441c04035918de4bfb5bff97-40528368.us- east-
1.elb.amazonaws.com/
ExternalName:
apiVersion: v1
kind: Service
metadata:
name: k8-service
namespace: dev
spec:
type: ExternalName
externalName: k8.learning.com
COMMANDS FOR SERVICES:
1. Creates a new service based on the YAML file
kubectl create -f filename
once you delete the pod we cannot able to access the pod,
so it will create a lot of difficulty in Real time
Before Kubernetes, other tools did not provide important and customized
features like scaling and replication.
When Kubernetes was introduced, replication and scaling were the premium
features that increased the popularity of this container orchestration tool.
Replication means that if the pod's desired state is set to 3 and whenever any
pod fails, then with the help of replication, the new pod will be created as soon
as possible. This will lead to a reduction in the downtime of the application.
Scaling means if the load becomes increases on the application, then
Kubernetes increases the number of pods according to the load on the
application.
ReplicationController is an object in Kubernetes that was introduced in v1 of
Kubernetes which helps to meet the desired state of the Kubernetes cluster
from the current state. ReplicationController works on equality-based
controllers only.
IF WE DELETE RC, PODS ARE ALSO GETS DELETED, BUT IF WE DON’T WANT TO
DELETE PODS, WE WANT TO DELETE ONLY REPLICA SETS THEN
kubectl delete rc rc_name --cascade=orphan
kubectl get rc rc_name
kubectl get pod
Now we deleted the RC but still pods are present, if we want to assign this pods to
another RC use the same selector which we used on the RC last file.
THE DRAWBACK
RC used only equality based selector
ex: env=prod
To manage this replica set we need a higher-level object called deployment which
provide additional functionality like rolling updates and roll backs.
Deployments use ReplicaSets under the hood to manage the actual pods that run
the application.
DEPLOYMENT:
It has features of Replicaset and some other extra features like updating and
rollbacking to a particular version.
The best part of Deployment is we can do it without downtime.
you can update the container image or configuration of the application.
Deployments also provide features such as versioning, which allows you to
track the history of changes to the application.
It has a pause feature, which allows you to temporarily suspend updates to
the application
Scaling can be done manually or automatically based on metrics such as CPU
utilization or requests per second.
Deployment will create ReplicaSet, ReplicaSet will created Pods.
If you delete Deployment, it will delete ReplicaSet and then ReplicaSet will
delete Pods.
Replicas: Number of pod copies we need to create
Matchelabel: label we want to match with pods
Template: This is the template of pod.
DEPLOYMENT SCALING:
Lets assume we have 3 pods, if i want to scale up it to 10 pods (manual scaling)
kubectl scale deployment/nginx-deployment --replicas=10
Lets assume we have 10 pods, if i want to scale down it to 5 pods (manual scaling)
kubectl scale deployment/nginx-deployment --replicas=5
KUBERNETES AUTO-SCALING:
As you know, to run the application we need CPU and memory. Sometimes,
there will be a chance where the CPU gets loaded, and this might fail the server
or affect the application. Now, we can’t afford the downtime of the applications.
To avoid this, we need to increase the number of servers or increase the capacity
of servers.
Just take an example we have some OTT platforms like Netflix, Prime, Aha &
Hotstar. If any web show or movie is coming on the platform the audience is
eagerly waiting for that. Then, the OTT platform can’t handle the lot of users that
might crash the application. This will lead to a loss of business and the OTT
platform can’t afford this business loss. Now, they have two options to solve this.
First, The Platform knows that they need a particular amount of servers such
as 100. So, they can buy those servers forever but in this situation, when the
load decreases then the other servers will become unused. Now, if the server
is unused, still they have paid for those servers which is not a cost-effective
method.
Second, The Platform doesn’t know when the load will increase. So, they have
one option which is autoscaling in which when the CPU utilization crosses a
particular number, it creates new servers. So, the platform can handle loads
easily which is very cost effective as well.
Types of Autoscaling
Horizontal Pod AutoScaling: In this type of scaling, the number of servers will
increase according to CPU utilization. In this, you define the minimum
number of servers, maximum number of servers, and CPU utilization. If the
CPU utilization crosses more than 50% then, it will add the one server
automatically.
Vertical Pod AutoScaling: In this type of scaling, the server will remain the
same in numbers but the server’s configuration will increase such as from
4GB RAM to 8GM RAM, and the same with the other configurations. But this
is not cost-effective and business-effective. So, we use Horizontal Pod
AutoScaling.
Key Features of Horizontal Pod AutoScaler:
Lets assume, if we have 4 pods, while trying to update them atleast 3 of them
are available and 1 should be updated in the mean time.
DAEMON-SET:
It is used to run a copy a pod to each worker node.
It is used to perform some tasks like monitoring, Log collection etc.. that need
to run on every node of the cluster.
A DaemonSet ensures that all eligible nodes run a copy of a Pod
When you create daemon set k8s schedules one copy of pod in each node.
If we added new node it will copy the pod automatically to new node.
If I remove on node from cluster the pod in that node also removed.
Deleting a DaemonSet will clean up the Pods it created.
Daemon-set does not contains replicas, because bydefault it will create only 1
pod in each node.
Daemon sets will not used for deployments on real-time, it is only to schedule
pods.
NAMESPACE:
Namespaces are used to group the components like pods, services, and
deployments.
This can be useful for separating environments, such as development,
staging, and production, or for separating different teams or applications.
In real-time all the frontend pods are mapped to one namespace and
backend pods are mapped to another namespace.
It represents the cluster inside the cluster.
You can have multiple namespaces within one Kubernetes cluster, and
they are all logically isolated from one another.
Namespaces provide a logical separation of cluster resources between
multiple users, teams, projects, and even customers.
Within the same Namespace, Pod to Pod communication.
Namespaces are only hidden from each other but are not fully isolated from
each other.
Nodes and Kubernetes Volumes do not come under the namespaces and are
visible to every namespace.
One service in a Namespace can talk to another service in another Namespace.
The name of resources within one namespace must be unique.
When you delete a namespace all the resources will gets deleted.
There are some pre-existed Kubernetes namespaces are present in our
cluster.
To see the list of names spaces : kubectl get ns
a. default
b. kube-system
c. kube-public
Default:
As the name suggests, whenever we create any Kubernetes object such as
pod, replicas, etc it will create in the default namespace.
kube-system
This namespace contains the Kubernetes components such as kube-
controller-manager, kube-scheduler, kube-dns or other controllers.
kube-public
This namespace is used to share non-sensitive information that can be
viewed by any of the members who are part of the Kubernetes cluster.
When should we consider Kubernetes Namespaces?
Isolation: When there are multiple numbers of projects running then we can
consider making namespaces and put the projects accordingly in the
namespaces.
Permission: If some objects are confidential and must need access to the
particular persons then, Kubernetes provides RBAC roles as well which we can
use in the namespace. It means that only authorized users can access the
objects within the namespaces.
COMMANDS:
kubectl get ns : used to get namespaces
kubectl create ns mustafa : used to create new namespace
kubectl config set-context --current --namespace=mustafa : to check to namespace
kubectl config view --minify | grep namespace : to verify the name space.
When you delete a namespace all the resources will gets deleted.
kubectl get pods -n mustafa : used to get pods from namespace
kubectl describe pod nginx -n development : describe a pod in namespace
kubectl delete pod nginx -n development : delete a pod in namespace
POD FILE NODEPORT FILE
ResourceQuota is one of the rich features of Kubernetes that helps to manage and
distribute resources according to the requirements.
Just assume that we have 2 teams (Team-A & Team-B) who are working on single
kubernetes cluster.
Team-A
Team-B
In this situation Team-A needs more CPU’s & Memory because of heavy workload
tasks.
Team-A
We need more CPU’s & Memory, Team-B
Because we have more work to do
If the CPUs and other resources go to another team then it might increase the
chance of failure.
Team-A
Team-B
To resolve this issue, we can allocate particular CPU cores and Memory to every
project.
By default pod in Kubernetes will run with no limits on CPU and memory.
You can specify the RAM, Memory, or CPUs for each container and pod.
The scheduler decides which node will create pods, if the node has enough CPU
resources available then, the node will place the pods.
CPU is specified in units of cores and memory is specified in units of bytes.
As you know, the Kubernetes cluster can be divided into namespaces and if we
create a container with no CPU limits then the container will have default limits.
A namespace can be assigned to ResourceQuota objects, this will help to limit
the amount of usage to the objects within the namespaces. You can limit the
computer (CPU), Memory, and Storage.
Restrictions that a resource-quotas imposes on namespaces
Every container that is running on the namespace must have its own CPU limit.
The total amount of CPU used by all the containers in the namespace should not
exceed a specified limit.
Lets understand the ResourceQuota with funny scenario. Assume that there is
medical college which has 25 seats only. So the college management assigned 10
seats for girls and 15 seats for boys who has more than 80% in Intermediate.
15 seats 10 seats
College (cluster)
4 cores 2 cores
100 MB 50 MB
Also we have a condition that students must has min 80% in Intermediate. In the same
way pod/container must contains the CPU limits. All the pods/containers in the
namespace should not exceed a specified limit.
There are two types of restrictions that need to be mentioned while using ResourceQuota
Limit: Limit specifies that the container, pod, or namespace will have the limit
resources where if the objects will exceed the limit then, the object won’t create.
Request: The request specifies that the container, pod, or namespace needs a
particular amount of resources such as CPU and memory. But if the request is
greater than the limit then, Kubernetes won’t allow the creation of pods or
containers.
Now, there are some conditions or principles for requests and limit which needs to be
understood.
1. If the requests and limits are given in the manifest file, it works accordingly.
2. If the requests are given but the limit is not provided then, the default requests will be used.
3. If the requests are not provided but the limit is provided then, the requests will be equal to
the limit.
If the requests and limits are given in the manifest file, it works accordingly.
Describe the pod and you will get limits and requests of the container
If the requests are given but the limit is not provided then, the default limit
will be used.
Describe the pod and you will get only requests of the container
If the requests are not provided but the limit is provided then, the requests
will be equal to the limit.
Describe the pod and you will get only limits of the container
Hands on : Resource Quota
create a ResourceQuota:
rq.yml
To see list of RQ : kubectl get resourcequota
Now lets try to create a pod with then limits an see the resource quota again
pod.yml
To see list of RQ : kubectl get resourcequota
If we execute this pod, we will get an error
because the pod limits and requests are
greater than the resource quota limits and
requests.
CONFIG MAPS:
ConfigMap is used to store the configuration data in key-value pairs within Kubernetes.
But the data should be non confidential data.
This is one of the ways to decouple the configuration from the application to get rid of
hardcoded values.
Also, if you observe some important values keep changing according to the
environments such as development, testing, production, etc ConfigMap helps to fix this
issue to decouple the configurations
So we can set the configuration of data of application separately
But it does not provider security and encryption. If we want to provide encryption use
secrets in Kubernetes.
Limit of config map data in only 1 MB (we cannot store more than that)
But if we want to store a large amount of data in config maps we have to mount a
volume or use a separate database or file service.
USE CASES IN CONFIG MAPS:
Configure application settings: By using this config maps, we can store the
configuration data that helps to run our application like database connections
and environment variables
Configuring a pod or container: It is used to send a configuration data to a pod or
container at runtime like CLI or files.
Sharing configuration data across multiple resources: By using this configuration
data multiple resources can access, such as a common configuration file for
different pods or services.
We can store the data: By using this config maps, we can store the data like IP
address, URL's and DNS etc...
SOME POINTS ABOUT CONFIGMAPS:
Creating the configMap is the first process which can be done by commands
only or a YAML file.
After creating the configMap, we use the data in the pod by injecting the pods.
After injecting the pods, if there is any update in the configuration we can
modify the configMap, and the changes will be reflected in the injected pod.
Creating ConfigMap from literal:
we have created the configMap through — from-literal which means you just
need to provide the key value instead of providing the file with key-value pair
data.
cat config-map-data.txt
Name=Mustafa
Course=Python
Duration=60 days
cat one.env
Tool=Kubernetes
Topic=Config Maps
Course=DevOps
We have created multiple files in a directory with different extensions that have different
types of data and created the configMap for the entire directory.
mkdir folder1
cat folder1/file1.txt
key1=value1
key2=23
cat folder2/file2.txt
key1=value1
key2=23
command to create config map:
kubectl create cm mummy --from-file=folder1/
CREATE A YAML FOR CONFIG-MAPS:
The imperative way is not very good if you have to repeat the same tasks again and again.
Now, we will look at how to create configMap through the YAML file.
In side the folder you will get file names as file1 POD.YML
and file2. kubectl apply -f pod.yml
SECRETS:
There are lot of confidential information that needs to be stored on the server
such as database usernames, passwords, or API Keys.
To keep all the important data secure, Kubernetes has a Secrets feature that
encrypts the data.
Secrets can store data up to 1MB which would be enough.
Secrets can be created via imperative or declarative ways.
Secrets are stored in the /tmps directory and can be accessible to pods only.
After creating the Secrets, applications need to use the credentials or database
credentials which will be done by injecting with the pods.
Creating Secret from literal:
we have created the Secrets through --from-literal which means you just need to
provide the key value instead of providing the file with key-value pair data.
you can see the key and encrypted value because Kubernetes encrypts the
secrets.
cat first.conf
username=sm7234
password=admin@123
cat mustafa.env
Name=mustafa
Place=Hyderabad
Compamy=TCS
mkdir folder1
cat folder1/file1.txt
Name=Mustafa
Place=Hyderabad=23
cat folder2/file2.txt
database=mysq1
password=mypassword
command to create secret:
kubectl create secret generic secret-from-folder --from-file=folder1/
In side the folder you will get file names as keys POD.YML
open the file using cat then we will get labels kubectl apply -f pod.yml
Injecting secret and creating a file in the pod with the
selected key pairs
This concept also will works as same as previous
topic. But Inside the pod we can declare the
filenames by our own inside the env-values
folder.
In side the folder you will get file names as file1 POD.YML
and file2. kubectl apply -f pod.yml
There are 2 possible ways to store the data in config maps
Use cases:
To Install the dependencies before running the application on the main
container
Clone a git repository into the volume
Generate configuration files dynamically
Database Configuration
lets create a new pod in which we have created two containers and the first
container is initcontainer.
when we create the pod, cont-1 command will gets executed and after 15 seconds
cont-2 will be in running state then cont-2 command will gets executed.
describe the pods for every 15 sec we will see the difference
If we describe the pod, we can see cont-1 status is running and cont-2 status is waiting
if we describe the same pod after 15 seconds container-2 is also in running state.
when the container 2 is running check the logs of the pod : kubectl logs -f pod/initcontainer
KUBERNETES JOBS:
It is a resource that is used to achieve a particular work like backup script and, once the work
is completed the pod will be deleted.
Use cases:
Database backup script needs to run
Running batch processes
Running the task on the scheduled interval
Log Rotation
Key Features:
One-time Execution: If you have a task that needs to be executed one time whether it’s
succeed or fail then the job will be finished.
Parallelism: If you want to run multiple pods at the same time.
Scheduling: If you want to schedule a specific number of pods after a specific time.
Restart Policy: You can specify whether the Job should restart if fails.
Work completed and pod deleted:
job.yml
The above manifest file will creates 3 pods and it will execute the commands.
activeDeadlineSeconds are used to terminate the pods after 10 seconds.
After 30 seconds all the pods will gets deleted.
As we can observe the logs here, when i run
the manifest file in first 2 seconds the pods
are in creating state.
The above manifest file for every one minute new pod will gets creates and it will
execute the commands. After 30 seconds pods will gets deleted. After 1 min new pod
created.
As we can observe the logs here, when i run
the manifest file one pod is created.
Last night i had a call with mobile customer care, and i explained my issue
with her and requested to resolve the issue. She asked to stay on call for some time.
Meanwhile the call was dropped due to network issues
Again i called to same number, but this time another person pick the call. He
don't know what the conversation we had with the first person. Again i had to
repeat the details of my problem to the second person, though it is an
inconvenience but it still works out
Kubernetes Deployment suits perfectly here. Let’s assume you deployed your
stateless application as a Deployment with 10 Pod replicas running in multiple
worker nodes.
If one of those Pods running in a particular worker node got terminated due to
some issue
The ReplicaSet Controller takes care of replacing the bad Pod with a new
healthy Pod either on the same node or on a different node.
Here replicaSet's will only take care of those 10 pods are running in the cluster
or not.
It doesn't take care of in which worker node they are running!
If pod 1 got terminated from node 1, then new pod will gets replaced on
either node 2 or node 1 or anywhere in the cluster.
This is possible because, the stateless application Pod 1 hasn’t stored any data
on worker node 1, hence can be easily replaced by new pod running on a
different worker node 2
The interesting thing to understand here is, the StatefulSet Controller managed to
bind the exact same Persistent Volume to two Shopping Cart Pods associated to
that customer at two different point of time.
STATEFUL APPLICATION:
Stateful applications are applications that store data and keep tracking it.
when we delete pods in stateful set last pod will be deleted first
and primary pod deletes last
DEPLOYMENT STATEFUL SET
It will create POD's with random ID's It will create POD's with sticky ID's
Scale down the POD's in random ID's Scale down the POD's in reverse order
We use this for application deployment We use this for database deployment
K8'S VOLUME AND LIVENESS PROBES:
Basically these K8's will works on short living data. So lets unveil the power of
volumes like EmptyDir, HostPath, PV & PVC.
The data is a very important thing for an application. In K8's, data is kept for a
short time in the applications in the pods/containers. By default the data will no
longer available. To overcome this we will use Kubernetes Volumes.
But before going into the types of Volumes. Let’s understand some facts about
pods and containers' short live data.
The volumes reside inside the Pod which stores the data of all containers in
that pod.
pod
cont-1 cont-2
volume
(data)
If the container gets deleted, then the data will persist and it will be available
for the new container which was created recently.
pod
volume
(data)
Multiple containers within a pod can share one volume because the volume is
attached to the pod.
pod
cont-1 cont-2
volume
(data)
If the Pod gets deleted, then the volume will also get deleted which leads to a
loss of data for all containers permanently.
pod
cont-1 cont-2
volume
(data)
After deleting the pod, the new pod will be created with volume but this time
volumes don’t have any previous data or any data.
pod
cont-1 cont-2
volume
(no-data)
Types of volumes:
1. EmptyDir
2. HostPath
3. Persistent Volume
4. Persistent Volume Claim(PVC)
1. EMPTY DIR:
This volume is used to share the volumes between multiple containers within
a pod instead of the host machine or any Master/Worker Node.
EmptyDir volume is created when the pod is created and it exists as long as a
pod.
There is no data available in the EmptyDir volume type when it is created for
the first.
Containers within the pod can access the other containers' data. However, the
mount path can be different for each container.
If the Containers get crashed then, the data will still persist and can be
accessible by other or newly created containers.
In the above file, it will creates 2 containers inside a pod. if you create a file in any container, then the file will be
available on both the containers.
kubectl exec -i -t devops --container cont-1 -- /bin/bash
By using the above command create a file in cont-1 and it will be available on cont-2 as well
Pod
cont-1 cont-2
DATA
volume
(data)
2. HOSTPATH:
This volume type is the advanced version of the previous volume type
EmptyDir.
In EmptyDir, the data is stored in the volumes that reside inside the Pods only
where the host machine doesn’t have the data of the pods and containers.
hostpath volume type helps to access the data of the pods or container
volumes from the host machine.
hostpath replicates the data of the volumes on the host machine and if you
make the changes from the host machine then the changes will be reflected to
the pods volumes(if attached).
In the above file, it will creates a pod. if you create a file in container, by using the command
docker exec -it pod-1 -c container1 /bin/bash
file will gets created. Now even if you delete the pod then another pods will gets created with same data.
Because we are using HostPath which creates local volume in our host machine.
Host
volume
(data)
PERSISTENT VOLUME:
Persistent means always available.
Persistent Volume is an advanced version of EmptyDir and hostPath volume
types.
Persistent Volume does not store the data over the local server. It stores the data
on the cloud or some other place where the data is highly available.
In previous volume types, if pods get deleted then the data will be deleted as
well. But with the help of Persistent Volume, the data can be shared with other
pods or other worker node’s pods as well after the deletion of pods.
PVs are independent of the pod lifecycle, which means they can exist even if no
pod is using them.
With the help of Persistent Volume, the data will be stored on a central location
such as EBS, Azure Disks, etc.
PERSISTENT VOLUME:
One Persistent Volume is distributed across the entire Kubernetes Cluster. So
that, any node or any node’s pod can access the data from the volume
accordingly.
In K8S, a PV is a piece of storage in the cluster that has been provisioned by an
administrator.
If you want to use Persistent Volume, then you have to claim that volume with
the help of the manifest YAML file.
When a pod requests storage via a PVC, K8S will search for a suitable PV to
satisfy the request.
If a PV is found that matches the request, the PV is bound to the PVC and the pod
can use the storage.
If no suitable PV is found, K8S then PVC will remain unbound (pending).
PERSISTENT VOLUME CLAIM:
To get the Persistent Volume, you have to claim the volume with the help of PVC.
When you create a PVC, Kubernetes finds the suitable PV to bind them together.
After a successful bound to the pod, you can mount it as a volume.
Once a user finishes its work, then the attached volume gets released and will be
used for recycling such as new pod creation for future usage.
If the pod is terminating due to some issue, the PV will be released but as you
know the new pod will be created quickly then the same PV will be attached to the
newly created Pod.
After bounding is done to pod you can mount it as a volume. The pod specifies the
amount and type of storage it needs, and the cluster provisions a persistent
volume that matches the request. If its not matches then it will be in pending
state.
FACTS ABOUT EBS:
Now, As you know the Persistent Volume will be on Cloud. So, there are some facts
and terms and conditions are there for EBS because we are using AWS cloud for our
K8 learning. So, let’s discuss it as well:
EBS Volumes keeps the data forever where the emptydir volume did not. If the
pods get deleted then, the data will still exist in the EBS volume.
The nodes on which running pods must be on AWS Cloud only(EC2 Instances).
Both(EBS Volume & EC2 Instances) must be in the same region and availability
zone.
EBS only supports a single EC2 instance mounting a volume
Create an EBS volume by clicking on ‘Create volume’.
Pass the Size for the EBS according to you, and select the Availability zone where your
EC2 instance is created, and click on Create volume.
EBS
we have deleted the pod, and then because of replicas the new pod was created
quickly. Now, we have logged in to the newly created pod and checked for the file
that we created in the previous step, and as you can see the file is present which is
expected.
vim pvc.yml
vim pv.yml
apiVersion: v1
apiVersion: v1 kind: PersistentVolumeClaim
kind: PersistentVolume metadata:
metadata: name: my-pvc
name: my-pv spec:
spec: accessModes:
capacity: - ReadWriteOnce
storage: 10Gi resources:
accessModes: requests:
- ReadWriteOnce storage: 10Gi
awsElasticBlockStore:
volumeID: vol-0e5bdf9400dbb7b57
kubectl apply -f pv.yml
fsType: ext4
kubectl apply -f pvc.yml
kubectl get pv,pvc
vim deploy.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: pvdeploy kubectl apply -f deploy.yml
spec: kubectl get deploy
replicas: 1 kubectl get rs
selector:
matchLabels: kubectl get po
app: swiggy
template:
metadata:
labels: kubectl exec pvdeploy-86c99cf54d-d8rj4 -it -- /bin/bash
app: swiggy cd /tmp/persistent/
spec:
ls
containers:
- name: raham vim raham
image: centos exit
command: ["bin/bash", "-c", "sleep 10000"]
volumeMounts:
- name: mypd now delete the pod and new pod will created then in that
mountPath: "/tmp/persistent" pod you will see the same content.
volumes:
- name: mypd
persistentVolumeClaim:
claimName: my-pvc
Access Modes
access modes determine how many pods can access a Persistent Volume (PV) or a Persistent Volume
Claim (PVC) simultaneously. There are several access modes that can be set on a PV or PVC, including:
ReadWriteOnce: This access mode allows a single pod to read and write to the PV or PVC. This is
the most common access mode, and it’s appropriate for use cases where a single pod needs
exclusive access to the storage.
ReadOnlyMany: This access mode allows multiple pods to read from the PV or PVC, but does not
allow any of them to write to it. This access mode is useful for cases where many pods need to read
the same data, such as when serving a read-only database.
ReadWriteMany: This access mode allows multiple pods to read and write to the PV or PVC
simultaneously. This mode is appropriate for use cases where many pods need to read and write to
the same data, such as a distributed file system.
Execute: This access mode allows the pod to execute the data on the PV or PVC but not read or
write to it. This mode is useful for use cases where the data is meant to be executed by the pods
only, such as application code.
PROBES (HEALTHCHECK):
PROBES: used to determine the health and readiness of containers running within pods. Probes
are 3 types:
1. Readiness probes are used to indicate when a container is ready to receive traffic.
2. Liveness probes are used to determine whether a container is still running and responding to
requests.
3. Startup Probe are used to determines whether the application within the container has
started successfully. It's used to delay the liveness and readiness probes until the application
is ready to handle traffic.
request
container
WHY PROBES?
In K8s, its common to scale up and scale down the pods. But when the pod is created newly it
will take some time to start the container and run the applications.
If a pod is not ready to receive traffic, it may receive requests that it cannot handle, that
causes downtime for our application.
Similarly, if a container is not running correctly, it may not be able to respond to requests,
resulting in the pod being terminated and replaced with a new one.
To overcome this issues, we are using Probes.
TYPES OF PROBES:
There are several types of probes that can be used in Kubernetes which includes HTTP, TCP, and
command probes.
If you see the YML file, there is one condition if the
file healthy is not present in /tmp directory then
livenessProbe will recreate the container. So, we
have deleted that file.
After that enter into the pod kubectl exec -it pod_name -c cont_name /bin/bash
Now check the health status echo $? If it returns 0 then application is running into the
container.
there is one condition if the file healthy is not present in /tmp directory then livenessProbe
will recreate the container. So, we have deleted that file.
After deleting the file, if you run kubectl describe pod pod-name you will see in the last two
lines that the container is failing because the condition is not meeting.
RBAC (Role Based Access Control):
I am a Developer
I am a Developer
I want to see the pods
I want to delete the pods I am a DevOps Guy
I want to create, delete
the pods
Role-Based Access Control (RBAC) is a critical security feature in Kubernetes
that allows you to define and manage access to resources based on roles and
permissions. RBAC ensures that only authorized users, processes, or services
can interact with specific resources within a Kubernetes cluster.
In Kubernetes, there are two types of accounts
1. User Account
2. Service Account
User account: User accounts are used to log into a Kubernetes cluster and
manipulate resources therein. Each user account is associated with a unique set
of credentials, which are used to authenticate the service’s requests.
I will choose client certificate to create a user which is very easy to create.
This certificates are used to create users. When a user perform any command like kubectl get
po then K8's API will authenticate and authorize the request.
1. Roles are the basic building blocks of RBAC. A role defines a set of permissions for a user or group.
For example, you might create a role called “admin” that gives the user or group full access to all
resources in the cluster.
(or)
Role is a set of permissions that define what actions (verbs) are allowed on specific resources (API
groups and resources) within a particular Namespace.
Roles are Namespace-scoped, meaning they apply only to resources within that Namespace.
2. ClusterRoles are special roles that apply to all users in the cluster. For example, you might create a
ClusterRole called “cluster-admin” that gives the user or group full access to all resources in the
cluster.
These are not Namespace-specific. They define permissions for cluster-wide resources.
3. Role bindings connect users/groups to roles. For example, you might bind the “admin” role to the
“admin” user. This would give the “admin” user all the permissions defined in the “admin” role.
It grants the permissions to particular namespaces only.
make sure to check check the configs before going to test the role (kubectl config view --minify)
After creating the clusterrole and attached that role to cluster role binding, its time to check weather
mustafa user can have access to work with resources in all namespaces or not.
HELM
Helm is a Kubernetes package manager in which the multiple numbers of
YAML files such as the backend, and frontend come under one roof(helm) and
deploy using helm.
HELM = + +
Install HEML:
curl -fsSL -o get_helm.sh
https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
chmod 700 get_helm.sh
./get_helm.sh
helm version
HELM commands:
If you want to dry-run the chart before installation : helm install devops --
debug --dry-run .
Validate all the YAML files in our HELM charts : helm list .
Git as the Source of Truth: In GitOps, all our configurations like (deployments,
services, secrets etc..) are stored in git repository.
If we deploy any application, there is no GUI to see the status of the deployment.
so we are facing some security challenges and need to install some third party
tools.
Points to be noted:
1. Once if we implement ArgoCD, if we make any changes manually in our
cluster using the kubectl command, Kubernetes will reject those request
from that user. Because when we apply changes manually, ArgoCD will check
the actual state of the cluster with the desired state of the cluster (GitHub).
2. If we make any changes in the GitHub like increasing the replicas in
deployment ArgoCD will take the changes and applies in our cluster. So that
we can track each and every change and it will maintain the history.
3. We can easily rollback using git if something went wrong.
4. If our entire cluster gets deleted due to some network or other issues, we
don’t need to worry about it, because all our configuration files are safely
stored in GitHub. So we can easily re-apply those configuration files.
Access controls:
1. In K8s, we use RBAC concept to give cluster permissions which is high
configurations and high maintenance. But in ArgoCD, just look over here
m
er
ge
re
qu
ops team es
t
merge request
fresher
uest
req
erge
m The boss
(Admin)
Person who accepts pull requst
devops
FEATURES:
Automated deployment of applications to specified target environments
Ability to manage and deploy to multiple clusters
Multi-tenancy and RBAC policies for authorization
Rollback/Roll-anywhere to any application configuration committed in the Git repository
Health status analysis of application resources
Automated configuration drift detection and visualization
Automated or manual syncing of applications to its desired state
Web UI which provides a real-time view of application activity
CLI for automation and CI integration
Webhook integration (GitHub, BitBucket, GitLab)
Access tokens for automation
PreSync, Sync, PostSync hooks to support complex application rollouts (e.g.blue/green & canary
upgrades)
Audit trails for application events and API calls
Prometheus metrics
Parameter overrides for overriding helm parameters in Git.
FINAL PROJECT: