Tuesday, August 19, 2025

Kubernetes part7

Kubernetes part7

Class 91 Kubernetes Part7 August 19th 

Kubernetes volumes
Step1: Create Ec2 instance ubuntu 25 GB disk space c7.large
Installations
ubuntu@ip-10-0-0-23:~$ sudo -i
root@ip-10-0-0-23:~# apt update -y

minikuber installafirst need to Install docker 

Docker Installation :

root@ip-10-0-0-23:~# apt install docker.io -y

root@ip-10-0-0-23:~# systemctl status docker

Minikube installation:

curl -LO https://github.com/kubernetes/minikube/releases/latest/download/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube && rm minikube-linux-amd64


root@ip-10-0-0-23:~# minikube version
minikube version: v1.36.0
commit: f8f52f5de11fc6ad8244afac475e1d0f96841df1-dirty

root@ip-10-0-0-23:~# ll /usr/local/bin
total 129668
drwxr-xr-x  2 root root      4096 Aug 20 13:44 ./
drwxr-xr-x 10 root root      4096 Jun 10 10:00 ../
-rwxr-xr-x  1 root root 132766301 Aug 20 13:44 minikube*
Start the minikube
root@ip-10-0-0-23:~# minikube start --driver=docker --force

root@ip-10-0-0-23:~# minikube status
minikube
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured

Installation Kubectl:
https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/
root@ip-10-0-0-23:~# curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
root@ip-10-0-0-23:~# chmod 777 kubectl
root@ip-10-0-0-23:~# mv kubectl /usr/local/bin/
root@ip-10-0-0-23:~# kubectl version
Client Version: v1.33.4
Kustomize Version: v5.6.0
Server Version: v1.33.1

Kubernetes Volumes:
 Docker volume: data replicate from one container to another container
 pods are ephemeral temporary store

K8’s volume and liveness probes:

  • Basically these K8’s will works on short living data.So let unveil the power of volumes like emptyDir,HostPath, PV and 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 volumnes.
  • But before going into the types of volumes,Let’s understand some facts about pods and containers short live data

Scenario1: multiple container with a pod can share one volume because the volume is attached to pod 
Scenario2: If pod deleted container and volume also deleted ,new pod will create using replicate controller and it will create new volume but previous data will loss.
to over come this issue we are using Kubernetes Volumes 

Types of Volumes 
1.EmptyDir 
2.HostPath
3.Persist Volume
4.Persist Volume claim(PVC)

1.    Empty Dir

This Volume is user to share the data between multiple containers within a pod instead of the host machine or any master/workernode.

 EmptyDir volume is created when the pod is create and it exists as long as a pod

There no data available in the emptydir volume type when it is create for first

Container within the pod can access the other container data. However the mount path can be different for each container

If the containers ger crashed the, that will still persist and can be accessible by other or newly create containers.

Pod:pod is group of container, (for ex:-a pod has one container1 along with one more container default exist helper container we also called sidecar container, log information backup multiple purpose use),so the reason command give below script, once container create it will exit from the container, so that is the reason we give here while loop

Practical:    Here below script two containers creating and attach the volume, and mount volume in this path /opt/jenkins, if you are using multiple container ,you need specify any command other wise  pod will never create.
 
Step1:
root@ip-10-0-0-23:~# vi manifest.yaml
root@ip-10-0-0-23:~# cat manifest.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mydepl
spec:
  replicas: 1
  selector:
    matchLabels:
      app: swiggy
  template:    # Moved to top-level under spec
    metadata:
      labels:
        app: swiggy  # Must match selector
    spec:
      containers:
      - name: container1
        image: nginx
        command: ["/bin/bash", "-c", "while true; do echo welcome to DevOps class; sleep 5; done"]
        volumeMounts:
          - name: myvolume
            mountPath: "/opt/jenkins"
        ports:
        - containerPort: 80
      - name: container2
        image: nginx
        command: ["/bin/bash", "-c", "while true; do echo welcome to DevOps class; sleep 5; done"]
        volumeMounts:
          - name: myvolume
            mountPath: "/etc/docker"

      volumes:
      - name: myvolume
        emptyDir: {}

root@ip-10-0-0-23:~# vi  manifest.yaml
root@ip-10-0-0-23:~# kubectl create -f manifest.yaml
deployment.apps/mydepl created
root@ip-10-0-0-23:~# kubectl get pod
NAME                      READY   STATUS    RESTARTS   AGE
mydepl-5d6645bd5b-qg2g7   2/2     Running   0          12s
Step2: Need to check volume mouted or not 

We have taken emptydir volume, so not data exists , just create one file 
root@ip-10-0-0-23:~# kubectl exec -it mydepl-5d6645bd5b-qg2g7 -c container1 -- bash
root@mydepl-5d6645bd5b-qg2g7:/# cd /opt/jenkins
root@mydepl-5d6645bd5b-qg2g7:/opt/jenkins# ls

Create some file and directory , it will copy automatically another container:
root@mydepl-5d6645bd5b-qg2g7:/opt/jenkins# touch app.py data.dat conta.pdf
root@mydepl-5d6645bd5b-qg2g7:/opt/jenkins# mkdir tcs infosys
root@mydepl-5d6645bd5b-qg2g7:/opt/jenkins# ls -lrt
total 8
-rw-r--r-- 1 root root    0 Aug 20 14:48 data.dat
-rw-r--r-- 1 root root    0 Aug 20 14:48 conta.pdf
-rw-r--r-- 1 root root    0 Aug 20 14:48 app.py
drwxr-xr-x 2 root root 4096 Aug 20 14:48 tcs
drwxr-xr-x 2 root root 4096 Aug 20 14:48 infosys

Container2 automatically exist 
root@ip-10-0-0-23:~# kubectl exec -it mydepl-5d6645bd5b-qg2g7 -c container2 -- bash
root@mydepl-5d6645bd5b-qg2g7:/# cd /etc/docker
root@mydepl-5d6645bd5b-qg2g7:/etc/docker# ls -lrt
total 8
-rw-r--r-- 1 root root    0 Aug 20 14:48 data.dat
-rw-r--r-- 1 root root    0 Aug 20 14:48 conta.pdf
-rw-r--r-- 1 root root    0 Aug 20 14:48 app.py
drwxr-xr-x 2 root root 4096 Aug 20 14:48 tcs
drwxr-xr-x 2 root root 4096 Aug 20 14:48 infosys

Container2 create some files 
root@mydepl-5d6645bd5b-qg2g7:/etc/docker# touch jenkis.yaml docker.yaml subbu.txt
root@mydepl-5d6645bd5b-qg2g7:/etc/docker#
exit
command terminated with exit code 130
Container1 file came to automatically
root@ip-10-0-0-23:~# kubectl exec -it mydepl-5d6645bd5b-qg2g7 -c container1 -- bash
root@mydepl-5d6645bd5b-qg2g7:/# cd /opt/jenkins
root@mydepl-5d6645bd5b-qg2g7:/opt/jenkins# ls -lrt
total 8
-rw-r--r-- 1 root root    0 Aug 20 14:48 data.dat
-rw-r--r-- 1 root root    0 Aug 20 14:48 conta.pdf
-rw-r--r-- 1 root root    0 Aug 20 14:48 app.py
drwxr-xr-x 2 root root 4096 Aug 20 14:48 tcs
drwxr-xr-x 2 root root 4096 Aug 20 14:48 infosys
-rw-r--r-- 1 root root    0 Aug 20 14:51 subbu.txt
-rw-r--r-- 1 root root    0 Aug 20 14:51 jenkis.yaml
-rw-r--r-- 1 root root    0 Aug 20 14:51 docker.yaml

Step3: above example until pod running container to container replicate is doing , if pod delete
new pod will create but volume data will loss 

--Pod deleted 
root@ip-10-0-0-23:~# kubectl delete pod mydepl-5d6645bd5b-qg2g7
pod "mydepl-5d6645bd5b-qg2g7" deleted
-- Automatically new pod created 
root@ip-10-0-0-23:~# kubectl get pod
NAME                      READY   STATUS    RESTARTS   AGE
mydepl-5d6645bd5b-whtr8   2/2     Running   0          56s
--We will inside the container, volume no file exists
root@ip-10-0-0-23:~# kubectl exec -it mydepl-5d6645bd5b-whtr8 -c container1 -- bash
root@mydepl-5d6645bd5b-whtr8:/# cd /opt/jenkins/
root@mydepl-5d6645bd5b-whtr8:/opt/jenkins# ls
root@mydepl-5d6645bd5b-whtr8:/opt/jenkins#

container2 also data missing , we loss the data :

root@ip-10-0-0-23:~# kubectl exec -it mydepl-5d6645bd5b-whtr8 -c container2 -- bash
root@mydepl-5d6645bd5b-whtr8:/# cd /etc/docker
root@mydepl-5d6645bd5b-whtr8:/etc/docker# ls

Not over come the issue We are using Host path 

2.HostPath

This volume type is the advanced version of the previous volume type

Emptydir.

In EmptyDirmthe 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)

Step1: delete existing deployment 

root@ip-10-0-0-23:~# kubectl delete deploy mydepl

deployment.apps "mydepl" deleted

Step2: previous manifest file only below line are changed for hostpath

  volumes:

      - name: myvolume

        hostPath:

          path: /tmp/mydata/

root@ip-10-0-0-23:~# kubectl create -f manifest.yaml
deployment.apps/mydepl created

Container1 some  files are created 

root@ip-10-0-0-23:~# kubectl exec -it mydepl-57f4bc8d46-7dkqm -c container1 -- bash
root@mydepl-57f4bc8d46-7dkqm:/# cd /opt/jenkins/
root@mydepl-57f4bc8d46-7dkqm:/opt/jenkins# touch app.py jenkins.yaml java.jvm
root@mydepl-57f4bc8d46-7dkqm:/opt/jenkins# ls
app.py  java.jvm  jenkins.yaml

Container 2 need to check files came or not 
root@ip-10-0-0-23:~# kubectl exec -it mydepl-57f4bc8d46-7dkqm -c container2 -- bash
root@mydepl-57f4bc8d46-7dkqm:/# cd /etc/docker/
root@mydepl-57f4bc8d46-7dkqm:/etc/docker# ls
app.py  java.jvm  jenkins.yaml

Step2: Delete the pod 
root@ip-10-0-0-23:~# kubectl delete pod mydepl-57f4bc8d46-7dkqm
pod "mydepl-57f4bc8d46-7dkqm" deleted

root@ip-10-0-0-23:~# kubectl delete mydepl-57f4bc8d46-7dkqm
error: the server doesn't have a resource type "mydepl-57f4bc8d46-7dkqm"
root@ip-10-0-0-23:~# kubectl delete pod mydepl-57f4bc8d46-7dkqm
pod "mydepl-57f4bc8d46-7dkqm" deleted
root@ip-10-0-0-23:~# kubectl get po
NAME                      READY   STATUS    RESTARTS   AGE
mydepl-57f4bc8d46-6fgfl   2/2     Running   0          46s
root@ip-10-0-0-23:~# kubectl exec -it mydepl-57f4bc8d46-6fgfl -c container1 -- bash
root@mydepl-57f4bc8d46-6fgfl:/# cd /opt/jenkins/
root@mydepl-57f4bc8d46-6fgfl:/opt/jenkins# ls
app.py  java.jvm  jenkins.yaml
root@mydepl-57f4bc8d46-6fgfl:/opt/jenkins#
exit
root@ip-10-0-0-23:~# kubectl exec -it mydepl-57f4bc8d46-6fgfl -c container2 -- bash
root@mydepl-57f4bc8d46-6fgfl:/# cd /etc/docker/
root@mydepl-57f4bc8d46-6fgfl:/etc/docker# ls
app.py  java.jvm  jenkins.yaml
root@mydepl-57f4bc8d46-6fgfl:/etc/docker# touch test nexflex google
root@mydepl-57f4bc8d46-6fgfl:/etc/docker#
exit
root@ip-10-0-0-23:~# kubectl delete pod mydepl-57f4bc8d46-6fgfl
pod "mydepl-57f4bc8d46-6fgfl" deleted
root@ip-10-0-0-23:~# kubectl get pod
NAME                      READY   STATUS    RESTARTS   AGE
mydepl-57f4bc8d46-jww7m   2/2     Running   0          40s
root@ip-10-0-0-23:~# kubectl exec -it mydepl-57f4bc8d46-jww7m -c container1 -- bash
root@mydepl-57f4bc8d46-jww7m:/# cd /opt/jenkins/
root@mydepl-57f4bc8d46-jww7m:/opt/jenkins# ls
app.py  google  java.jvm  jenkins.yaml  nexflex  test

Here we did hostpath attached to node, whenevery pod delete it will create and attached volume from hostpath ,for single it will work, but real time we are using multi node, we have attached the hostpath single node,if multi node the pods not not created other node.

If Node deleted ,autoscale node also data will loss  to overcome this issue:

PV 
PVC 
We will store the data in cloud EBS storage for example take 100 GB  
Persistent volume (PV-1) 15 GB
Persistent volume (PV-2) 10 GB
Persistent volume (PV-3) 45 GB

We have left 30 GB left it is used for future 
Claim persistent volume 

I have  requirement to Pod creation, i need 13 GB ,for the we have claim that PVC (persistent volume claim) from PV ,PVC will check suitable PV either PV-1 ,PV2m PV-3 here PV1,PV3 suitable
Before pod create we should need create PVC

IF you are trying create Pod with 35 GB ,below case PVC searching for suitable PV there is not space available ,PVC went into pending state and also unable create po.


Step1:
EBS volume need to create ,based on the EBS-id need to create PV 
 Elastic Block store>Create volume >

my-app volume created

Step2: copy the volumeid vol-08360ae5933a3ef0a 

root@ip-10-0-0-23:~# vi pv.yaml
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-1
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteOnce
  awsElasticBlockStore:
    volumeID: vol-08360ae5933a3ef0a
    fsType: ext4
  persistentVolumeReclaimPolicy: Recycle

Step3:
-- it is just warning Create one PV-1
root@ip-10-0-0-23:~# kubectl create -f  pv.yaml
Warning: spec.persistentVolumeReclaimPolicy: The Recycle reclaim policy is deprecated. Instead, the recommended approach is to use dynamic provisioning.
persistentvolume/pv-1 created

Step4: Create one more PV-2
root@ip-10-0-0-23:~# vi pv.yaml
root@ip-10-0-0-23:~# cat pv.yaml
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-2
spec:
  capacity:
    storage: 2Gi
  accessModes:
    - ReadWriteOnce
  awsElasticBlockStore:
    volumeID: vol-08360ae5933a3ef0a
    fsType: ext4
  persistentVolumeReclaimPolicy: Recycle

root@ip-10-0-0-23:~# kubectl create -f  pv.yaml
Warning: spec.persistentVolumeReclaimPolicy: The Recycle reclaim policy is deprecated. Instead, the recommended approach is to use dynamic provisioning.
persistentvolume/pv-2 created

Step5: list of pv's  two pvs created (pv-1,pv-2)
root@ip-10-0-0-23:~# kubectl get pv
root@ip-10-0-0-23:~#

Step6: Now claim the PVC ,write pvc file 

root@ip-10-0-0-23:~# vi pvc.yaml
root@ip-10-0-0-23:~# cat pvc.yaml
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mypvc-1
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 3Gi

root@ip-10-0-0-23:~# kubectl create -f pvc.yaml
persistentvolumeclaim/mypvc-1 created

root@ip-10-0-0-23:~# kubectl create -f pvc.yaml
persistentvolumeclaim/mypvc-1 created
root@ip-10-0-0-23:~# kubectl get pvc
--Which we have create the volume

root@ip-10-0-0-23:~# kubectl get pv
we have claimed 3 gib  bound 

Step7: Now we need to attached this volume(PVC) to  po
Delete the existing deployment 
root@ip-10-0-0-23:~# kubectl get deploy
NAME     READY   UP-TO-DATE   AVAILABLE   AGE
mydepl   1/1     1            1           148m
root@ip-10-0-0-23:~# kubectl delete deploy mydepl
deployment.apps "mydepl" deleted
root@ip-10-0-0-23:~# kubectl get deploy
No resources found in default namespace.

Step8: Create deployment with new volume, only need to change below highlighted lines 
root@ip-10-0-0-23:~# vi manifest.yaml
root@ip-10-0-0-23:~# cat manifest.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mydepl
spec:
  replicas: 1
  selector:
    matchLabels:
      app: swiggy
  template:    # Moved to top-level under spec
    metadata:
      labels:
        app: swiggy  # Must match selector
    spec:
      containers:
      - name: container1
        image: nginx
        command: ["/bin/bash", "-c", "while true; do echo welcome to DevOps class; sleep 5; done"]
        volumeMounts:
          - name: myvolume
            mountPath: "/opt/jenkins"
        ports:
        - containerPort: 80
      - name: container2
        image: nginx
        command: ["/bin/bash", "-c", "while true; do echo welcome to DevOps class; sleep 5; done"]
        volumeMounts:
          - name: myvolume
            mountPath: "/etc/docker"

      volumes:
      - name: myvolume
        persistentVolumeClaim:
          claimName: pvc-1


root@ip-10-0-0-23:~# kubectl create -f manifest.yaml
deployment.apps/mydepl created


Step8: Whether pod created or not 
root@ip-10-0-0-23:~# kubectl get pod
NAME                      READY   STATUS    RESTARTS   AGE
mydepl-7b4979dff6-m559p   0/2     Pending   0          47s

To identify the error ,here clearly showing pvc-1 not found ,we have given name PVC mypvc-1
root@ip-10-0-0-23:~# kubectl describe pod mydepl-7b4979dff6-m559p

Events:
  Type     Reason            Age    From               Message
  ----     ------            ----   ----               -------
  Warning  FailedScheduling  2m21s  default-scheduler  0/1 nodes are available: persistentvolumeclaim "pvc-1" not found. preemption: 0/1 nodes are available: 1 Preemption is not helpful for scheduling.

Step9: Changed PCV name , after change configuration need to apply
persistentVolumeClaim:
          claimName: mypvc-1
root@ip-10-0-0-23:~# kubectl apply -f manifest.yaml
root@ip-10-0-0-23:~# kubectl apply -f manifest.yaml
Warning: resource deployments/mydepl is missing the kubectl.kubernetes.io/last-applied-configuration annotation which is required by kubectl apply. kubectl apply should only be used on resources created declaratively by either kubectl create --save-config or kubectl apply. The missing annotation will be patched automatically.
deployment.apps/mydepl configured

Now pod is running state 
root@ip-10-0-0-23:~# kubectl get pod
NAME                      READY   STATUS    RESTARTS   AGE
mydepl-587dc99798-9nr6z   2/2     Running   0          16s

root@ip-10-0-0-23:~# kubectl get pv


root@ip-10-0-0-23:~# kubectl get pvc
NAME      STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   VOLUMEATTRIBUTESCLASS   AGE
mypvc-1   Bound    pvc-8998df85-79c6-4df4-9241-3987bebe8519   3Gi        RWO            standard       <unset>                 30m

Step10: Try to go inside the po and create some file and delete the pod 
root@ip-10-0-0-23:~# kubectl exec -it mydepl-587dc99798-9nr6z -c container1 -- bash
root@mydepl-587dc99798-9nr6z:/# cd /opt/jenkins/
root@mydepl-587dc99798-9nr6z:/opt/jenkins# ls

Created some dummy file 
root@mydepl-587dc99798-9nr6z:/opt/jenkins# touch app.py docker manifest.yaml pv
root@mydepl-587dc99798-9nr6z:/opt/jenkins# ls
app.py  docker  manifest.yaml  pv

Step11: lets delete the po ,new pod created automatically 

root@ip-10-0-0-23:~# kubectl get po
NAME                      READY   STATUS    RESTARTS   AGE
mydepl-587dc99798-9nr6z   2/2     Running   0          8m58s
root@ip-10-0-0-23:~# kubectl delete pod  mydepl-587dc99798-9nr6z
pod "mydepl-587dc99798-9nr6z" deleted
root@ip-10-0-0-23:~# kubectl get po
NAME                      READY   STATUS    RESTARTS   AGE
mydepl-587dc99798-smm8q   2/2     Running   0          58s

-- see here i have went into container2 ,our file are exists 

root@ip-10-0-0-23:~# kubectl exec -it mydepl-587dc99798-smm8q -c container2 -- bash
root@mydepl-587dc99798-smm8q:/# cd /etc/docker
root@mydepl-587dc99798-smm8q:/etc/docker# ls
app.py  docker  manifest.yaml  pv


EBS safe and secure the data ever though pod delete and cluster delete or node delete.

Step12: Make sure the after cluster delete need delete EBS volume also 

root@ip-10-0-0-23:~# kubectl get -- all
NAME                          READY   STATUS    RESTARTS   AGE
pod/mydepl-587dc99798-smm8q   2/2     Running   0          7m20s

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   4h24m

NAME                     READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/mydepl   1/1     1            1           24m

NAME                                DESIRED   CURRENT   READY   AGE
replicaset.apps/mydepl-587dc99798   1         1         1       16m
replicaset.apps/mydepl-7b4979dff6   0         0         0       24m
root@ip-10-0-0-23:~# kubectl delete deploy mydepl
deployment.apps "mydepl" deleted


Under standing the Access modes:

Access modes determine how many pods can access a persistent volume(PV) or a persistent volume claim(PVC) simulataneously.There are several access modes that can be set on PV or PVC,inclusing:

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 its 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 servinf a read-only database.

ReadWritemany:This access mode allow 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.



--Thanks 

Monday, August 18, 2025

Kubernetes part6

Kubernetes part6

Class 90th Kubernetes Part6 August 18th 

Deamonsets and statefulsets :

cluster all are similar(replication cluster,replication sets,deployment,deamonsets,statefulsets)

all are same manifest files 

Deamon-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 node run a copy of a pod
  • When you create daemon set k8s schedule on 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 by default it will create only 1 pod in each node.
  • Deamon sets will not used for deployments on real-time,it is only to schedule.

cluster(cluster is group of servers,master and worker)

demon-sets :single pods for each instance ,whenevery create new instance automatically pod will created.  each worker node we have to install one pod or agent pod will give data to permutes will send to Grafana for dashboard visualize

demon-sets only for monitoring and logging purpose not used for deployment 

Practical:

Step1:

[root@ip-10-0-0-28 ~]# aws s3 ls

2025-08-16 16:58:08 ccitpublicbucket16

[root@ip-10-0-0-28 ~]#

[root@ip-10-0-0-28 ~]# export KOPS_STATE_STORE=s3://ccitpublicbucket16

[root@ip-10-0-0-28 ~]# kops create cluster --name kopsclstr.k8s.local --zones eu-west-2b,eu-west-2a --master-count 1 --master-size c7i-flex.large --master-volume-size 20 --node-count 2 --node-size t3.micro --node-volume-size=15 --image=ami-044415bb13eee2391

Cluster configuration has been created.

Suggestions:
 * list clusters with: kops get cluster
 * edit this cluster with: kops edit cluster kopsclstr.k8s.local
 * edit your node instance group: kops edit ig --name=kopsclstr.k8s.local nodes-eu-west-2b
 * edit your control-plane instance group: kops edit ig --name=kopsclstr.k8s.local control-plane-eu-west-2b

Finally configure your cluster with: kops update cluster --name kopsclstr.k8s.local --yes --admin

[root@ip-10-0-0-28 ~]# kops update cluster --name kopsclstr.k8s.local --yes --admin

Step2:1.Controlplane/master 2 worker node created successfully

Step3:
[root@ip-10-0-0-28 ~]# kubectl get node
NAME                  STATUS   ROLES           AGE    VERSION
i-000360c9c71860aa1   Ready    node            63s    v1.32.4
i-02e7e492877aa8af4   Ready    control-plane   3m9s   v1.32.4
i-0d56c24033208cb64   Ready    node            85s    v1.32.4
Step4: Create the pod using manifest file 
[root@ip-10-0-0-28 ~]# cat manifest.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: mydeamon
spec:
  selector:
    matchLabels:
      app: monitor
  template:    # Moved to top-level under spec
    metadata:
      labels:
        app: monitor  # Must match selector
    spec:
      containers:
      - name: container1
        image: nginx
        ports:
        - containerPort: 80

[root@ip-10-0-0-28 ~]# kubectl create -f manifest.yaml
daemonset.apps/mydeamon created

See here 2 pods created ,We have two worker nodes 
[root@ip-10-0-0-28 ~]# kubectl get pods
NAME             READY   STATUS    RESTARTS   AGE
mydeamon-cnp7z   1/1     Running   0          89s
mydeamon-nkr5t   1/1     Running   0          89s

[root@ip-10-0-0-28 ~]# kubectl get pods -w
NAME             READY   STATUS              RESTARTS   AGE
mydeamon-cnp7z   0/1     ContainerCreating   0          4s
mydeamon-nkr5t   0/1     ContainerCreating   0          4s
mydeamon-cnp7z   1/1     Running             0          8s
mydeamon-nkr5t   1/1     Running             0          8s

Step5: If you want increase worker nodes, need to edit the cluster 
[root@ip-10-0-0-28 ~]# kops get cluster
NAME                    CLOUD   ZONES
kopsclstr.k8s.local     aws     eu-west-2a,eu-west-2b

Suggestions:
 * list clusters with: kops get cluster

This command for worker node to change 
 * edit this cluster with: kops edit cluster kopsclstr.k8s.local
 * edit your node instance group: kops edit ig --name=kopsclstr.k8s.local nodes-eu-west-2b
This command for master to change 
 * edit your control-plane instance group: kops edit ig --name=kopsclstr.k8s.local control-plane-eu-west-2b

Step6: edit the worker node , here each region eu-west-2b 1 node that is the reason showing in cluster min and max showing 2

[root@ip-10-0-0-28 ~]# kops edit ig --name=kopsclstr.k8s.local nodes-eu-west-2b

Changed from 1 to 2
  machineType: t3.micro
  maxSize: 2
  minSize: 2

After change Cluster update the cluster using below command , after run this command instance
will increase.
[root@ip-10-0-0-28 ~]# kops update cluster --name=kopsclstr.k8s.local --yes --admin

Step7: Three worker nodes 
[root@ip-10-0-0-28 ~]# kubectl get node
NAME                  STATUS   ROLES           AGE   VERSION
i-000360c9c71860aa1   Ready    node            15m   v1.32.4
i-02e7e492877aa8af4   Ready    control-plane   17m   v1.32.4
i-05b2188bac81487ec   Ready    node            40s   v1.32.4
i-0d56c24033208cb64   Ready    node            15m   v1.32.4

See here 1 more pod created automatically ,along with workernode
[root@ip-10-0-0-28 ~]# kubectl get pods
NAME             READY   STATUS    RESTARTS   AGE
mydeamon-2tfcp   1/1     Running   0          16m
mydeamon-dzcnl   1/1     Running   0          2m31s
mydeamon-m8p4c   1/1     Running   0          16m

See below each pod attached one node 
[root@ip-10-0-0-28 ~]# kubectl get pods -o wide
NAME             READY   STATUS    RESTARTS   AGE     IP             NODE                  NOMINATED NODE   READINESS GATES
mydeamon-2tfcp   1/1     Running   0          19m     100.96.2.76    i-000360c9c71860aa1   <none>           <none>
mydeamon-dzcnl   1/1     Running   0          5m37s   100.96.3.238   i-05b2188bac81487ec   <none>           <none>
mydeamon-m8p4c   1/1     Running   0          19m     100.96.1.112   i-0d56c24033208cb64   <none>           <none>
[root@ip-10-0-0-28 ~]#
Note: Control plane pod are not create, only pod will create in worker node only

Step8: reduce the worker node automatically pods also got reduced
[root@ip-10-0-0-28 ~]# kops edit ig --name=kopsclstr.k8s.local nodes-eu-west-2b
[root@ip-10-0-0-28 ~]# kops update cluster --name=kopsclstr.k8s.local --yes --admin
 maxSize: 1
 minSize: 1

[root@ip-10-0-0-28 ~]# kubectl get pods
NAME             READY   STATUS    RESTARTS   AGE
mydeamon-dzcnl   1/1     Running   0          10m
mydeamon-m8p4c   1/1     Running   0          23m

[root@ip-10-0-0-28 ~]# kubectl get nodes
NAME                  STATUS   ROLES           AGE   VERSION
i-02e7e492877aa8af4   Ready    control-plane   28m   v1.32.4
i-05b2188bac81487ec   Ready    node            12m   v1.32.4
i-0d56c24033208cb64   Ready    node            27m   v1.32.4

Statefulsets:
Deployment and statefulset 
Deployment is used for application ,statefulset used for database 
For ex: 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 conversion 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 

Kubernets deployment suit perfectly here.Let’s assumer you deployed your stateless application as deployment with 10 pod replicas running in multiple worker node.

If pod 1 got terminated from node 1,the new pod will gets replaced on either node2 or node1 or anywhere in the cluster

This is possible because,the stateless application pod1 hasn’t stored any data on worker node1, hence can be easily replace by new pod running on a different worker node 2. If the pod is not storing the data then we called it as STATELESS.

Stateless applications:

  • It can’t store the data permanently
  • The word STATELESS means no past data
  •  It depends on non-persistent data means data is removed when Pod,node or cluster is stopped.
  • Non-persistent mainly used for logging info(ex: system log,container log etc)
  • In order to avoid this problem,we are using stateful application
  • A stateless application can be deployed as a set of identical replicas,and each repica can handle incoming requests independently without the need to coordinate with other replicas

For ex:- one worker node has two pods one is application and other one database ,if one pod db deleted
Replicaset it aware to create same node to create delete pod , it going to create another worker node 
and also not past data, so we are not used for stateless application for database.

STATEFUL application:
    Let’s say want to order some some products in amazon, you added some products to your shopping cart. After you added the books to you shopping cart, If forgot to switch off the stove In kitchen and you closed the web browser hurry. after some time you login the browser , the item should be there in cart

Stateful applications are applications that store data and keep tracking it.

Example of stateful applications:

 ALL RDS databases(Mysql,sql)

Elastic search,kafka,mongo DB,redis etc..

Any application that stores data

To get the code for stateful application use this link:

https://github.com/devops0014/ksg-stateful-set-application.git

Application stateless whenevery scalein pod will increase, stateful side whenevery scalein or scaleup previous pod copy and create new pod


Statefulset :First pod is primary pod, remaining pod are secondary pod, primary pod only has read/write permission. remaining pod only read access

Scaledown: in deployment it will delete any pod, but where as stateful set whetevery you have create new pod that is only deleted first.(first in last out)

Deployment :

It will create POD’s with random ID’s

Scale down the Pod’s in random id’s

POD’s are stateless POD’s

We use this for application deployment

Stateful set:

It will create POD’s with sticky ID’s

Scale down the POD’s in reverse order

POD’s are stateful POD’s

We use this for database deployment

Step1:
[root@ip-10-0-0-28 ~]# vi statefulset.yaml
[root@ip-10-0-0-28 ~]# cat statefulset.yaml
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mystate
spec:
  replicas: 4
  selector:
    matchLabels:
      app: zamoto
  template:    # Moved to top-level under spec
    metadata:
      labels:
        app: zamoto  # Must match selector
    spec:
      containers:
      - name: container2
        image: shaikmustafa/dm
        ports:
        - containerPort: 80

As you see here , base first pod copy second will create 
[root@ip-10-0-0-28 ~]# kubectl create -f statefulset.yaml
statefulset.apps/mystate created
[root@ip-10-0-0-28 ~]# kubectl get pods -w
NAME             READY   STATUS              RESTARTS   AGE
mydeamon-dzcnl   1/1     Running             0          76m
mydeamon-m8p4c   1/1     Running             0          90m
mystate-0        1/1     Running             0          8s
mystate-1        0/1     ContainerCreating   0          1s
mystate-1        1/1     Running             0          7s
mystate-2        0/1     Pending             0          0s
mystate-2        0/1     Pending             0          0s
mystate-2        0/1     ContainerCreating   0          0s
mystate-2        1/1     Running             0          3s
mystate-3        0/1     Pending             0          0s
mystate-3        0/1     Pending             0          0s
mystate-3        0/1     ContainerCreating   0          0s
mystate-3        1/1     Running             0          3s

Three Pods are created .

[root@ip-10-0-0-28 ~]# kubectl get pods
NAME             READY   STATUS    RESTARTS   AGE
mydeamon-dzcnl   1/1     Running   0          78m
mydeamon-m8p4c   1/1     Running   0          91m
mystate-0        1/1     Running   0          102s
mystate-1        1/1     Running   0          95s
mystate-2        1/1     Running   0          88s
mystate-3        1/1     Running   0          85s

Step2: Scaleup see create mystate4 set,
[root@ip-10-0-0-28 ~]# kubectl scale statefulset mystate  --replicas=5
statefulset.apps/mystate scaled

[root@ip-10-0-0-28 ~]# kubectl scale statefulset mystate  --replicas=5
statefulset.apps/mystate scaled
[root@ip-10-0-0-28 ~]# kubectl get pods -w
NAME             READY   STATUS              RESTARTS   AGE
mydeamon-dzcnl   1/1     Running             0          86m
mydeamon-m8p4c   1/1     Running             0          99m
mystate-0        1/1     Running             0          9m28s
mystate-1        1/1     Running             0          9m21s
mystate-2        1/1     Running             0          9m14s
mystate-3        1/1     Running             0          9m11s
mystate-4        0/1     ContainerCreating   0          2s
mystate-4        1/1     Running             0          3s

[root@ip-10-0-0-28 ~]# kubectl get pods
NAME             READY   STATUS    RESTARTS   AGE
mydeamon-dzcnl   1/1     Running   0          87m
mydeamon-m8p4c   1/1     Running   0          100m
mystate-0        1/1     Running   0          10m
mystate-1        1/1     Running   0          10m
mystate-2        1/1     Running   0          10m
mystate-3        1/1     Running   0          10m
mystate-4        1/1     Running   0          63s
Step2: Scaledown see here last three was terminated, mystate-0 and mystate-1 exist

[root@ip-10-0-0-28 ~]# kubectl scale statefulset mystate  --replicas=2
statefulset.apps/mystate scaled
[root@ip-10-0-0-28 ~]# kubectl get pods -w
NAME             READY   STATUS        RESTARTS   AGE
mydeamon-dzcnl   1/1     Running       0          87m
mydeamon-m8p4c   1/1     Running       0          101m
mystate-0        1/1     Running       0          11m
mystate-1        1/1     Running       0          11m
mystate-2        1/1     Terminating   0          11m
mystate-2        0/1     Completed     0          11m
mystate-2        0/1     Completed     0          11m
mystate-2        0/1     Completed     0          11m
[root@ip-10-0-0-28 ~]# kubectl get pods
NAME             READY   STATUS    RESTARTS   AGE
mydeamon-dzcnl   1/1     Running   0          89m
mydeamon-m8p4c   1/1     Running   0          102m
mystate-0        1/1     Running   0          12m
mystate-1        1/1     Running   0          12m

Step3: So far what we have created resource using all below is listed out 

pods:

[root@ip-10-0-0-28 ~]# kubectl get all
NAME                 READY   STATUS    RESTARTS   AGE
pod/mydeamon-dzcnl   1/1     Running   0          92m
pod/mydeamon-m8p4c   1/1     Running   0          106m
pod/mystate-0        1/1     Running   0          15m
pod/mystate-1        1/1     Running   0          15m

Services:

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   100.64.0.1   <none>        443/TCP   110m

Demon set:

NAME                      DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
daemonset.apps/mydeamon   2         2         2       2            2           <none>          106m

NAME                       READY   AGE
statefulset.apps/mystate   2/2     15m


Step3: deleted,service came by default  
[root@ip-10-0-0-28 ~]# kubectl delete ds mydeamon
daemonset.apps "mydeamon" deleted
[root@ip-10-0-0-28 ~]# kubectl delete statefulset mystate
statefulset.apps "mystate" deleted
[root@ip-10-0-0-28 ~]# kubectl get all
NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   100.64.0.1   <none>        443/TCP   113m


Namespaces : Particular about name based cluster to display instead of showing all the pod/service/deployment, resources isolated purpose we use namspaces which means sperate one to other

in Production mini two cluster 
Preprod cluster: Dev/test/uat
Prod cluster

so far we create created all resource default cluster namespaces. if you want to create which namespace your resource created.

Below command showing which namespace exists

[root@ip-10-0-0-28 ~]# kubectl get namespace
NAME              STATUS   AGE
default           Active   119m
kube-node-lease   Active   119m
kube-public       Active   119m
kube-system       Active   119m
[root@ip-10-0-0-28 ~]# kubectl get ns
NAME              STATUS   AGE
default           Active   119m
kube-node-lease   Active   119m
kube-public       Active   119m
kube-system       Active   119m

Here ,if you given command kubectl get po if you are in default namespace it will show only default namespace pos, dev namespace pod will not show.



Step1:
If you create any pod, by create by default, in default namespace only see below create one dummy pod 

[root@ip-10-0-0-28 ~]# kubectl run pod-1 --image=nginx
pod/pod-1 created
[root@ip-10-0-0-28 ~]# kubectl get pod
NAME    READY   STATUS    RESTARTS   AGE
pod-1   1/1     Running   0          21s
[root@ip-10-0-0-28 ~]# kubectl describe pod-1
error: the server doesn't have a resource type "pod-1"
[root@ip-10-0-0-28 ~]# kubectl describe pod  pod-1
Name:             pod-1
Namespace:        default

kube-public: whatevery the pods, in your cluster able to access every one.

Default:

As the name suggests, whenever we create any kubernetes object wuch as pod,replicas,etc it will create in th default namespace.

Kube-system (whet every you have installed sperate it will use this namespace for ex: metrics)

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-sensititve information that can be viewed by any  of the members who are part of the kubernetes cluster


[root@ip-10-0-0-28 ~]# kubectl get all -n  kube-system
(any scheduler information it will show)
[root@ip-10-0-0-28 ~]# kubectl get all -n  kube-node-lease
No resources found in kube-node-lease namespace.


Step2: Create own namespace 

[root@ip-10-0-0-28 ~]# kubectl create ns dev
namespace/dev created
[root@ip-10-0-0-28 ~]# kubectl get ns
NAME              STATUS   AGE
default           Active   141m
dev               Active   11s
kube-node-lease   Active   141m
kube-public       Active   141m
kube-system       Active   141m

-- No resource exist for the dev namespace 
[root@ip-10-0-0-28 ~]# kubectl get all -n dev
No resources found in dev namespace.

Create one pod with namespace dev 

[root@ip-10-0-0-28 ~]# kubectl run pod-2 --image=nginx -n dev
pod/pod-2 created
[root@ip-10-0-0-28 ~]# kubectl get all -n  dev
NAME        READY   STATUS    RESTARTS   AGE
pod/pod-2   1/1     Running   0          24s

see below default namespace dev pod is not showing, becauase  it will  create specified dev namespace 

[root@ip-10-0-0-28 ~]# kubectl get pod
NAME    READY   STATUS    RESTARTS   AGE
pod-1   1/1     Running   0          17m


Step3: Now planning deploy the specific namespace 

[root@ip-10-0-0-28 ~]# cat statefulset.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myspace
namespace: dev
spec:
  replicas: 4
  selector:
    matchLabels:
      app: zamoto
  template:    # Moved to top-level under spec
    metadata:
      labels:
        app: zamoto  # Must match selector
    spec:
      containers:
      - name: container2
        image: shaikmustafa/dm
        ports:
        - containerPort: 80


[root@ip-10-0-0-28 ~]# kubectl create -f statefulset.yaml
deployment.apps/myspace created

See here default Pods are not showing 

[root@ip-10-0-0-28 ~]# kubectl get po
NAME    READY   STATUS    RESTARTS   AGE
pod-1   1/1     Running   0          25m

with namespace dev 4 replica pod showing 

Deployment created in dev 
[root@ip-10-0-0-28 ~]# kubectl get deployment -n dev
NAME      READY   UP-TO-DATE   AVAILABLE   AGE
myspace   4/4     4            4           2m36s

[root@ip-10-0-0-28 ~]# kubectl get po -n dev
NAME                       READY   STATUS    RESTARTS   AGE
myspace-7bdfc8c57d-5qvdh   1/1     Running   0          25s
myspace-7bdfc8c57d-bvjtt   1/1     Running   0          25s
myspace-7bdfc8c57d-dpjsn   1/1     Running   0          25s
myspace-7bdfc8c57d-vh796   1/1     Running   0          25s
pod-2                      1/1     Running   0          8m59s

using command prompt able give  namespace 

[root@ip-10-0-0-28 ~]# kubectl create -f statefulset.yaml -n dev 

delete the deployment for particular name space dev 

[root@ip-10-0-0-28 ~]# kubectl delete deployment myspace -n dev
deployment.apps "myspace" deleted

--no resource exist
[root@ip-10-0-0-28 ~]# kubectl get deployment
No resources found in default namespace.
-- pods also deleted automatically 
[root@ip-10-0-0-28 ~]# kubectl get pods -n dev
NAME    READY   STATUS    RESTARTS   AGE
pod-2   1/1     Running   0          15m

Step4:

Service also we can create similar way 

[root@ip-10-0-0-28 ~]# vi service.yaml
[root@ip-10-0-0-28 ~]# cat service.yaml
---
apiVersion: v1
kind: Service
metadata:
  name: myservice
spec:
  type: LoadBalancer
  selector:
    app: zamoto
  ports:
    - port: 80
      targetPort: 80

Step5: See here service create dev namespace 

[root@ip-10-0-0-28 ~]# kubectl create -f service.yaml -n dev
service/myservice created
[root@ip-10-0-0-28 ~]# kubectl get svc -n dev
NAME        TYPE           CLUSTER-IP      EXTERNAL-IP                                                             PORT(S)        AGE
myservice   LoadBalancer   100.67.11.194   ac994ded082174dc5ae84c9e924446b1-69473691.eu-west-2.elb.amazonaws.com   80:30364/TCP   17s



Step6: If you want delete the namespace you need first delete the all resource of the namespace 

List of resource in dev namespace

[root@ip-10-0-0-28 ~]# kubectl get all -n dev
NAME                           READY   STATUS    RESTARTS   AGE
pod/myspace-7bdfc8c57d-b8swm   1/1     Running   0          19s
pod/myspace-7bdfc8c57d-brfd8   1/1     Running   0          19s
pod/myspace-7bdfc8c57d-j4tzx   1/1     Running   0          19s
pod/myspace-7bdfc8c57d-swf7j   1/1     Running   0          19s
pod/pod-2                      1/1     Running   0          25m

NAME                TYPE           CLUSTER-IP      EXTERNAL-IP                                                             PORT(S)        AGE
service/myservice   LoadBalancer   100.67.11.194   ac994ded082174dc5ae84c9e924446b1-69473691.eu-west-2.elb.amazonaws.com   80:30364/TCP   4m37s

NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/myspace   4/4     4            4           19s

NAME                                 DESIRED   CURRENT   READY   AGE
replicaset.apps/myspace-7bdfc8c57d   4         4         4       19s

[root@ip-10-0-0-28 ~]# kubectl delete deployment myspace -n dev
deployment.apps "myspace" deleted

[root@ip-10-0-0-28 ~]# kubectl delete svc --all  -n dev
service "myservice" deleted

[root@ip-10-0-0-28 ~]# kubectl delete pod --all  -n dev
pod "pod-2" deleted

[root@ip-10-0-0-28 ~]# kubectl get all -n dev
No resources found in dev namespace.

namespace to delete
[root@ip-10-0-0-28 ~]# kubectl delete ns dev
namespace "dev" deleted



Switching one tablespace to another space
[root@ip-10-0-0-28 ~]# kubectl config set-context  --current  --namespace=kube-public
Context "kopsclstr.k8s.local" modified.
[root@ip-10-0-0-28 ~]# kubectl get po
No resources found in kube-public namespace.

[root@ip-10-0-0-28 ~]# kubectl config view
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://api-kopsclstr-k8s-local-0kba4s-7dc9e9e90042d909.elb.eu-west-2.amazonaws.com
    tls-server-name: api.internal.kopsclstr.k8s.local
  name: kopsclstr.k8s.local
contexts:
- context:
    cluster: kopsclstr.k8s.local
    namespace: kube-public
    user: kopsclstr.k8s.local
  name: kopsclstr.k8s.local
current-context: kopsclstr.k8s.local
kind: Config
preferences: {}
users:
- name: kopsclstr.k8s.local
  user:
    client-certificate-data: DATA+OMITTED
    client-key-data: DATA+OMITTED



[root@ip-10-0-0-28 ~]# kubectl config set-context  --current  --namespace=default
Context "kopsclstr.k8s.local" modified.
[root@ip-10-0-0-28 ~]# kubectl get po
NAME    READY   STATUS    RESTARTS   AGE
pod-1   1/1     Running   0          52m
[root@ip-10-0-0-28 ~]# kubectl config view
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://api-kopsclstr-k8s-local-0kba4s-7dc9e9e90042d909.elb.eu-west-2.amazonaws.com
    tls-server-name: api.internal.kopsclstr.k8s.local
  name: kopsclstr.k8s.local
contexts:
- context:
    cluster: kopsclstr.k8s.local
    namespace: default
    user: kopsclstr.k8s.local
  name: kopsclstr.k8s.local
current-context: kopsclstr.k8s.local
kind: Config
preferences: {}
users:
- name: kopsclstr.k8s.local
  user:
    client-certificate-data: DATA+OMITTED
    client-key-data: DATA+OMITTED

For reference:


--Thanks 

Friday, August 15, 2025

Kubernetes part5

Kubernetes part5

Class 89th Kubernetes Part5 August 15th 

Step1: Install Kops 

[root@ip-10-0-0-22 ~]#   curl -Lo kops https://github.com/kubernetes/kops/releases/download/$(curl -s https://api.github.com/repos/kubernetes/kops/releases/latest | grep tag_name | cut -d '"' -f 4)/kops-linux-amd64

Install kubectl
[root@ip-10-0-0-22 ~]# kubectl version
Client Version: v1.33.4
Kustomize Version: v5.6.0
The connection to the server localhost:8080 was refused - did you specify the right host or port?

[root@ip-10-0-0-22 ~]# aws s3 ls
2025-08-16 16:58:08 ccitpublicbucket16

[root@ip-10-0-0-22 ~]# export KOPS_STATE_STORE=s3://ccitpublicbucket16

Step2: Create the cluster
[root@ip-10-0-0-22 ~]# kops create cluster --name kopsclstr.k8s.local --zones eu-west-2b,eu-west-2a --master-count 1 --master-size c7i-flex.large --master-volume-size 20 --node-count 2 --node-size t3.micro --node-volume-size=15 --image=ami-044415bb13eee2391

[root@ip-10-0-0-22 ~]#kops update cluster --name kopsclstr.k8s.local --yes --admin

Step3: Deployment file create for manifest,
[root@ip-10-0-0-22 ~]# cat manifest.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mydeploy
spec:
  replicas: 2  # Fixed: lowercase and proper spacing
  selector:    # Proper selector definition
    matchLabels:
      app: zamoto
  template:    # Moved to top-level under spec
    metadata:
      labels:
        app: zamoto  # Must match selector
    spec:
      containers:
      - name: container1
        image: shaikmustafa/mygame
        ports:
        - containerPort: 80

[root@ip-10-0-0-22 ~]# cat service.yaml
---
apiVersion: v1
kind: Service
metadata:
  name: myservice
spec:
  type: LoadBalancer
  selector:
    app: zamoto
  ports:
    - port: 80
      targetPort: 80
Step4: So far deployment
pod-->container 
rc/rs -->pod-->contrainer
deploy -->rs-->pod -->container 

Deployment feature: autoscaling,need to provide these information while deployment,if pod usage 60 % percentage usage pod will create, if usage is less pod will reduced

  1. replication 
  2. Scaling(manuall,autoscaling)  Autoscalimg: 
    desired:3
    min:2
    max10
  3. Rollback to any version
  4. no downtime
Step5: All instance created successfully.
[root@ip-10-0-0-22 ~]#  kops validate cluster --wait 10m
[ec2-user@ip-10-0-0-22 ~]$ kubectl get nodes
NAME                  STATUS   ROLES           AGE     VERSION
i-012484f05449c29f6   Ready    control-plane   3m36s   v1.32.4
i-0c9c5c020ce9ab366   Ready    node            73s     v1.32.4
i-0e71b4d0cc69c02c6   Ready    node            85s     v1.32.4
Step6: Using below command execute manifest file, 

[root@ip-10-0-0-22 ~]# kubectl create -f .
deployment.apps/mydeploy created
service/myservice created

Step7: Deployment create , along with replicaset will come
[root@ip-10-0-0-22 ~]# kubectl get deploy
NAME       READY   UP-TO-DATE   AVAILABLE   AGE
mydeploy   2/2     2            2           47s

[root@ip-10-0-0-22 ~]# kubectl get rs
NAME                  DESIRED   CURRENT   READY   AGE
mydeploy-77d4499fd4   2         2         2       104s

Step8: list of Pods 
[root@ip-10-0-0-22 ~]# kubectl get pods
NAME                        READY   STATUS    RESTARTS   AGE
mydeploy-77d4499fd4-7j2xs   1/1     Running   0          2m6s
mydeploy-77d4499fd4-kldnq   1/1     Running   0          2m6s

Step9:list of Services
[root@ip-10-0-0-22 ~]# kubectl get svc
NAME         TYPE           CLUSTER-IP      EXTERNAL-IP                                                               PORT(S)        AGE
kubernetes   ClusterIP      100.64.0.1      <none>                                                                    443/TCP        6m29s
myservice    LoadBalancer   100.71.88.229   a8ba63cae87274680944e81acc4a3da6-2050377277.eu-west-2.elb.amazonaws.com   80:30315/TCP   2m56s

Step10: loadbalancer  opened 
Step11:
[root@ip-10-0-0-22 ~]# kubectl get deploy
NAME       READY   UP-TO-DATE   AVAILABLE   AGE
mydeploy   2/2     2            2           11m
[root@ip-10-0-0-22 ~]# kubectl describe deploy
Name:                   mydeploy
Namespace:              default
CreationTimestamp:      Sun, 17 Aug 2025 13:31:01 +0000
Labels:                 <none>
Annotations:            deployment.kubernetes.io/revision: 1
Selector:               app=zamoto
Replicas:               2 desired | 2 updated | 2 total | 2 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  app=zamoto
  Containers:
   container1:
    Image:         shaikmustafa/mygame
    Port:          80/TCP
    Host Port:     0/TCP
    Environment:   <none>
    Mounts:        <none>
  Volumes:         <none>
  Node-Selectors:  <none>
  Tolerations:     <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  <none>
NewReplicaSet:   mydeploy-77d4499fd4 (2/2 replicas created)
Events:
  Type    Reason             Age   From                   Message
  ----    ------             ----  ----                   -------
  Normal  ScalingReplicaSet  11m   deployment-controller  Scaled up replica set mydeploy-77d4499fd4 from 0 to 2

Test our features 
No down time
Step12: Change the deployment file  image changed 
[root@ip-10-0-0-22 ~]# vi manifest.yaml

image: shaikmustafa/dm

[root@ip-10-0-0-22 ~]# kubectl apply -f manifest.yaml
Warning: resource deployments/mydeploy is missing the kubectl.kubernetes.io/last-applied-configuration annotation which is required by kubectl apply. kubectl apply should only be used on resources created declaratively by either kubectl create --save-config or kubectl apply. The missing annotation will be patched automatically.
deployment.apps/mydeploy configured

See without downtime ,deployed changed to another webpage


Step13: Though command also we can change  image
[root@ip-10-0-0-22 ~]# kubectl set image deploy mydeploy container1=shaikmustafa/cycle
deployment.apps/mydeploy image updated


Step14: Below command rollout can able check ,image deployed or not 
[root@ip-10-0-0-22 ~]# kubectl rollout status deploy mydeploy
deployment "mydeploy" successfully rolled out
Step15: shaikmustafa/paytm:movie
[root@ip-10-0-0-22 ~]# kubectl set image deploy mydeploy container1=shaikmustafa/paytm:movie
deployment.apps/mydeploy image updated
[root@ip-10-0-0-22 ~]# kubectl rollout status deploy mydeploy
Waiting for deployment "mydeploy" rollout to finish: 1 out of 2 new replicas have been updated...
Waiting for deployment "mydeploy" rollout to finish: 1 out of 2 new replicas have been updated...
Waiting for deployment "mydeploy" rollout to finish: 1 out of 2 new replicas have been updated...
Waiting for deployment "mydeploy" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "mydeploy" rollout to finish: 1 old replicas are pending termination...
deployment "mydeploy" successfully rolled out
[root@ip-10-0-0-22 ~]#

Step16:
Deployment -->RS 1--> 3 pods created First game
After Image updated --RS2 --> 1 pod will create after successfully deployed, remove one pod in Rs1, Same way 2 pod will create after successfully deployed , remove second pod  in Rs1
 Same way 3 prod will create after successfully deployed ,demote third pod, 
all pods deployed into new version application.
This called this strategy  in technically "rolling update strategy"



Step17: Planning to rollback the application 

After change Replicateset , previous set are not delete it should be presist , you can able to rollback 
previous application ,now below one is active one , now the application is paytm movie,
Planning to change Rs3 desire rollback 

[root@ip-10-0-0-22 ~]# kubectl get rs
NAME                  DESIRED   CURRENT   READY   AGE
mydeploy-547d4c47c7   0         0         0       50m
mydeploy-5f87bb8854   0         0         0       36m
mydeploy-77d4499fd4   0         0         0       65m
mydeploy-8565b4b985   2         2         2       30m

Undo command 
Here 3 is version 
[root@ip-10-0-0-22 ~]# kubectl rollout undo deployment mydeploy --to-revision=3
deployment.apps/mydeploy rolled back

[root@ip-10-0-0-22 ~]# kubectl rollout status deploy mydeploy
deployment "mydeploy" successfully rolled out
Application change to cycle


See here rs active state changed  from mydeploy-8565b4b985  to  mydeploy-5f87bb8854
[root@ip-10-0-0-22 ~]# kubectl  get rs
NAME                  DESIRED   CURRENT   READY   AGE
mydeploy-547d4c47c7   0         0         0       58m
mydeploy-5f87bb8854   2         2         2       44m
mydeploy-77d4499fd4   0         0         0       73m
mydeploy-8565b4b985   0         0         0       38m

This command will show like 1 pod i creating another pod is terminiated
-w mean watch

[root@ip-10-0-0-22 ~]# kubectl  get  po -w
NAME                        READY   STATUS              RESTARTS   AGE
mydeploy-5f87bb8854-b9rp7   0/1     ContainerCreating   0          0s
mydeploy-5f87bb8854-mrbws   1/1     Running             0          3s
mydeploy-8565b4b985-7pv2w   1/1     Terminating         0          57s
mydeploy-8565b4b985-d4lrj   1/1     Running             0          55s
mydeploy-8565b4b985-7pv2w   0/1     Completed           0          58s
mydeploy-8565b4b985-7pv2w   0/1     Completed           0          59s
mydeploy-8565b4b985-7pv2w   0/1     Completed           0          59s
mydeploy-5f87bb8854-b9rp7   1/1     Running             0          3s
mydeploy-8565b4b985-d4lrj   1/1     Terminating         0          58s

See here i have change version 4 

[root@ip-10-0-0-22 ~]#  kubectl rollout undo deployment mydeploy --to-revision=4
deployment.apps/mydeploy rolled back
[root@ip-10-0-0-22 ~]# kubectl  get  po -w
NAME                        READY   STATUS    RESTARTS   AGE
mydeploy-8565b4b985-7pv2w   1/1     Running   0          11s
mydeploy-8565b4b985-d4lrj   1/1     Running   0          9s

Planning to back to version 2 ,it should not available version 3 will change version 5

[root@ip-10-0-0-22 ~]#  kubectl rollout undo deployment mydeploy --to-revision=3
error: unable to find specified revision 3 in history

[root@ip-10-0-0-22 ~]#  kubectl rollout undo deployment mydeploy --to-revision=5
deployment.apps/mydeploy rolled back




Now the current application is Cycle 



Step18: see here history of deployment version 3 was removed 
[root@ip-10-0-0-22 ~]# kubectl rollout history deploy mydeploy
deployment.apps/mydeploy
REVISION  CHANGE-CAUSE
1         <none>
2         <none>
6         <none>
7         <none>


[root@ip-10-0-0-22 ~]#  kubectl rollout undo deployment mydeploy --to-revision=2
deployment.apps/mydeploy rolled back
[root@ip-10-0-0-22 ~]# kubectl  get  po -w
NAME                        READY   STATUS              RESTARTS   AGE
mydeploy-547d4c47c7-4cmnc   1/1     Running             0          4s
mydeploy-547d4c47c7-tfp6p   0/1     ContainerCreating   0          1s
mydeploy-5f87bb8854-b9rp7   1/1     Running             0          9m29s
mydeploy-547d4c47c7-tfp6p   1/1     Running             0          2s
mydeploy-5f87bb8854-b9rp7   1/1     Terminating         0          9m31s
mydeploy-5f87bb8854-b9rp7   0/1     Completed           0          9m32s
mydeploy-5f87bb8854-b9rp7   0/1     Completed           0          9m33s
mydeploy-5f87bb8854-b9rp7   0/1     Completed           0          9m33s

[root@ip-10-0-0-22 ~]# kubectl rollout history deploy mydeploy
deployment.apps/mydeploy
REVISION  CHANGE-CAUSE
1         <none>
6         <none>
7         <none>
8         <none>


Step19: delete the pod , need to check automatically created or not 

See  after deleted all pod ,created pod 5 sec automatically

[root@ip-10-0-0-22 ~]# kubectl get pods
NAME                        READY   STATUS    RESTARTS   AGE
mydeploy-547d4c47c7-4cmnc   1/1     Running   0          3m25s
mydeploy-547d4c47c7-tfp6p   1/1     Running   0          3m22s
[root@ip-10-0-0-22 ~]# kubectl delete pod --all
pod "mydeploy-547d4c47c7-4cmnc" deleted
pod "mydeploy-547d4c47c7-tfp6p" deleted
[root@ip-10-0-0-22 ~]# kubectl get pods
NAME                        READY   STATUS    RESTARTS   AGE
mydeploy-547d4c47c7-b22bc   1/1     Running   0          5s
mydeploy-547d4c47c7-t9x4z   1/1     Running   0          5s

Step20: manually scalein , first increase the pods

[root@ip-10-0-0-22 ~]# cat manifest.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mydeploy
spec:
  replicas: 4  # Fixed: lowercase and proper spacing
  selector:    # Proper selector definition
    matchLabels:
      app: zamoto
  template:    # Moved to top-level under spec
    metadata:
      labels:
        app: zamoto  # Must match selector
    spec:
      containers:
      - name: container1
        image: shaikmustafa/dm
        ports:
        - containerPort: 80

[root@ip-10-0-0-22 ~]# kubectl apply -f manifest.yaml
deployment.apps/mydeploy configured
[root@ip-10-0-0-22 ~]# kubectl get po
NAME                        READY   STATUS    RESTARTS   AGE
mydeploy-547d4c47c7-b22bc   1/1     Running   0          4m45s
mydeploy-547d4c47c7-sgkc7   1/1     Running   0          9s
mydeploy-547d4c47c7-t9x4z   1/1     Running   0          4m45s
mydeploy-547d4c47c7-zstz8   1/1     Running   0          9s


Scaledown using command:

[root@ip-10-0-0-22 ~]# kubectl scale deploy mydeploy  --replicas 2
deployment.apps/mydeploy scaled
[root@ip-10-0-0-22 ~]# kubectl get po
NAME                        READY   STATUS    RESTARTS   AGE
mydeploy-547d4c47c7-b22bc   1/1     Running   0          5m55s
mydeploy-547d4c47c7-t9x4z   1/1     Running   0          5m55s


Step21: Auto scaling ,Prod metric 

metric for the server 

https://kubernetes-sigs.github.io/metrics-server/

kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/high-availability.yaml





[root@ip-10-0-0-22 ~]# curl -LO https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/high-availability.yaml
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100  4871  100  4871    0     0  16938      0 --:--:-- --:--:-- --:--:-- 16938
[root@ip-10-0-0-22 ~]# sed -i 's|policy/v1beta1|policy/v1|g' high-availability.yaml
[root@ip-10-0-0-22 ~]# kubectl apply -f high-availability.yaml
serviceaccount/metrics-server unchanged
clusterrole.rbac.authorization.k8s.io/system:aggregated-metrics-reader unchanged
clusterrole.rbac.authorization.k8s.io/system:metrics-server unchanged
rolebinding.rbac.authorization.k8s.io/metrics-server-auth-reader unchanged
clusterrolebinding.rbac.authorization.k8s.io/metrics-server:system:auth-delegator unchanged
clusterrolebinding.rbac.authorization.k8s.io/system:metrics-server unchanged
service/metrics-server unchanged
deployment.apps/metrics-server configured
poddisruptionbudget.policy/metrics-server created
apiservice.apiregistration.k8s.io/v1beta1.metrics.k8s.io unchanged

Below command metric-server installed or not using below command 
[root@ip-10-0-0-22 ~]# kubectl get deployment metrics-server -n kube-system
NAME             READY   UP-TO-DATE   AVAILABLE   AGE
metrics-server   2/2     2            2           5m39s


[root@ip-10-0-0-22 ~]# cat hp.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
    name: nginx-hpa
spec:
    scaleTargetRef:
        apiVersion: apps/v1
        kind: Deployment
        name: mydeploy
    minReplicas: 1
    maxReplicas: 5
    metrics:
    - type: Resource
      resource:
        name: cpu
        target:
            type: Utilization
            averageUtilization: 50  # Target 50% CPU utilization

Deployment created ,autoscaling will work once 50 % cpu ultization, so you need give command stress to server.
[root@ip-10-0-0-22 ~]# kubectl create -f hp.yaml
horizontalpodautoscaler.autoscaling/nginx-hpa created


Step22: Go to inside the pod 
[root@ip-10-0-0-22 ~]# kubectl get po
NAME                        READY   STATUS    RESTARTS   AGE
mydeploy-547d4c47c7-b22bc   1/1     Running   0          25m
mydeploy-547d4c47c7-t9x4z   1/1     Running   0          25m
[root@ip-10-0-0-22 ~]# kubectl exec -it mydeploy-547d4c47c7-t9x4z -- bash
root@mydeploy-547d4c47c7-t9x4z:/#

Step23:
root@mydeploy-547d4c47c7-t9x4z:/# apt update -y

root@mydeploy-547d4c47c7-t9x4z:/# apt install stress -y

root@mydeploy-547d4c47c7-t9x4z:/# stress -c 2 400 -v
stress: FAIL: [305] (244) unrecognized option: 400
root@mydeploy-547d4c47c7-t9x4z:/# stress -c 2 -t 400 -v
stress: info: [306] dispatching hogs: 2 cpu, 0 io, 0 vm, 0 hdd
stress: dbug: [306] using backoff sleep of 6000us
stress: dbug: [306] setting timeout to 400s
stress: dbug: [306] --> hogcpu worker 2 [307] forked
stress: dbug: [306] using backoff sleep of 3000us
stress: dbug: [306] setting timeout to 400s
stress: dbug: [306] --> hogcpu worker 1 [308] forked

Step24: See below previous 2 pods only, after stress server 5 pods automatically created
See here 5 pods created


Step25: Once you cancel the stress automatically pod will reduced, it will take time 

Delete the cluster:
[root@ip-10-0-0-22 ~]# export KOPS_STATE_STORE=s3://ccitpublicbucket16
[root@ip-10-0-0-22 ~]# kops delete cluster --name kopsclstr.k8s.local --yes

Deleted kubectl config for kopsclstr.k8s.local

Deleted cluster: "kopsclstr.k8s.local"



--Thanks