September 22nd, 2023
Kubernetes cluster on Localhost

VM setup

Install Multipass on Linux

# use local git pointing
git remote set-url origin /mnt/h_drive/hdrive_data/Resources/wordpress_nginx/git-repo/git-repo/kubernetes.git


# Install Multipass on Linux so that multiple VM can be run locally.
Ref: https://multipass.run/install

# Set external path for base of multipass
https://multipass.run/docs/configure-multipass-storage#heading--linux

# K8s on multipass
https://microk8s.io/docs/install-multipass

# Launch an instance (by default you get the current Ubuntu LTS)
multipass launch --name foo
multipass launch --name k8smaster-vm --cpus 4 --disk 20G --memory 4G

# See your instances
multipass list

# Stop and start instances
multipass stop foo bar
multipass start foo

# enter shell using multipass
multipass shell foo

# Clean up what you don’t need
multipass delete bar

# ============
# Configure instance cpu, disk and memory

multipass stop foo
multipass set local.foo.cpus=4
multipass set local.foo.disk=20G
multipass set local.foo.memory=4G

# Get the details of cpu, disk and memory
multipass get local.foo.cpus
multipass get local.foo.disk
multipass get local.foo.memory

How to Install Kubernetes Cluster on Ubuntu 22.04

https://www.linuxtechi.com/install-kubernetes-on-ubuntu-22-04/

Prerequisites

  • Minimal install Ubuntu 22.04
  • Minimum 2GB RAM or more
  • Minimum 2 CPU cores / or 2 vCPU
  • 20 GB free disk space on /var or more
  • Sudo user with admin rights
  • Internet connectivity on each node

Lab Setup

  • Master Node: 10.21.172.44 – k8smaster
  • First Worker Node: 10.21.172.143 – node1

1) Set hostname on Each Node

  • Login to to master node and set hostname using hostnamectl command
$ multipass shell foo
$ sudo hostnamectl set-hostname "k8smaster"
$ exec bash
  • On the worker nodes, run
$ sudo hostnamectl set-hostname "node1"   // 1st worker node
$ exec bash

Add the following entries in /etc/hosts file on each node

10.21.172.44   k8smaster
10.21.172.143  node1

2) Disable swap & Add kernel Parameters

Execute beneath swapoff and sed command to disable swap. Make sure to run the following commands on all the nodes.

$ sudo swapoff -a
$ sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab

Load the following kernel modules on all the nodes

$ sudo tee /etc/modules-load.d/containerd.conf <<EOF
overlay
br_netfilter
EOF
$ sudo modprobe overlay
$ sudo modprobe br_netfilter

Set the following Kernel parameters for Kubernetes, run beneath tee command

$ sudo tee /etc/sysctl.d/kubernetes.conf <<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF

Reload the above changes, run

$ sudo sysctl --system

3) Install Containerd Runtime

In this guide, we are using containerd runtime for our Kubernetes cluster. So, to install containerd, first install its dependencies.

$ sudo apt-get update
$ sudo apt install -y curl gnupg2 software-properties-common apt-transport-https ca-certificates

Enable docker repository

$ sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmour -o /etc/apt/trusted.gpg.d/docker.gpg
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

Now, run following apt command to install containerd

$ sudo apt update
$ sudo apt install -y containerd.io

Configure containerd so that it starts using systemd as cgroup.

$ containerd config default | sudo tee /etc/containerd/config.toml >/dev/null 2>&1
$ sudo sed -i 's/SystemdCgroup \= false/SystemdCgroup \= true/g' /etc/containerd/config.toml

Restart and enable containerd service

$ sudo systemctl restart containerd
$ sudo systemctl enable containerd

4) Add Apt Repository for Kubernetes

Kubernetes package is not available in the default Ubuntu 22.04 package repositories. So we need to add kubernetes repositories, run following command.

$ curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo gpg --dearmour -o /etc/apt/trusted.gpg.d/kubernetes-xenial.gpg
$ sudo apt-add-repository "deb http://apt.kubernetes.io/ kubernetes-xenial main"

Note: At time of writing this guide, Xenial is the latest Kubernetes repository but when repository is available for Ubuntu 22.04 (Jammy Jellyfish) then you need replace xenial word with ‘jammy’ in ‘apt-add-repository’ command.

5) Install Kubectl, Kubeadm and Kubelet

Post adding the repositories, install Kubernetes components like kubectl, kubelet and Kubeadm utility on all the nodes. Execute following set of commands,

$ sudo apt update
$ sudo apt install -y kubelet kubeadm kubectl
$ sudo apt-mark hold kubelet kubeadm kubectl

6) Initialize Kubernetes Cluster with Kubeadm

Now, we are all set to initialize Kubernetes cluster. Run the following Kubeadm command on the master node only.

$ sudo kubeadm init

# Response ----
Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

Alternatively, if you are the root user, you can run:

  export KUBECONFIG=/etc/kubernetes/admin.conf

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 10.101.165.236:6443 --token ydq2ph.rwkw543ongql5ubu \
        --discovery-token-ca-cert-hash sha256:71cd1d99e7421976af20f43d981d7629a8db0f8096f8395f5a3380342187df18

Get cluster and node info

# Get cluster info on Master
$ kubectl cluster-info
# Response ------
Kubernetes control plane is running at https://10.21.172.44:6443
CoreDNS is running at https://10.21.172.44:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

# Get nodes info on Master
$ kubectl get nodes
# Response ------
NAME        STATUS   ROLES           AGE     VERSION
k8smaster   Ready    control-plane   10h     v1.28.2
node1       Ready    <none>          5h24m   v1.28.2

7) Join Worker Nodes to the Cluster

On each worker node, use the kubeadm join command you noted down earlier after initializing the master node on step 6. It should look something like this:

$ kubeadm join 10.21.172.44:6443 --token 0p4mgk.rxn2a6m4c7t1atdz \
        --discovery-token-ca-cert-hash sha256:57fc4625deadc0085f6160997419d7f95e8fd5265e857e5d45ac970c9be58f63 

8) Install Calico Network Plugin

A network plugin is required to enable communication between pods in the cluster. Run following kubectl command to install Calico network plugin from the master node.

$ kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.25.0/manifests/calico.yaml

Verify the status of pods in kube-system namespace

$ kubectl get pods -n kube-system

# Response ---
NAME                                       READY   STATUS    RESTARTS       AGE
calico-kube-controllers-658d97c59c-jmxr4   1/1     Running   0              5h29m
calico-node-2txqx                          1/1     Running   0              5h29m
calico-node-zkszp                          1/1     Running   0              5h29m
coredns-5dd5756b68-k5s68                   1/1     Running   0              10h
coredns-5dd5756b68-wd958                   1/1     Running   0              10h
etcd-k8smaster                             1/1     Running   1 (6h3m ago)   10h
kube-apiserver-k8smaster                   1/1     Running   1 (6h3m ago)   10h
kube-controller-manager-k8smaster          1/1     Running   4 (45m ago)    10h
kube-proxy-ksh8j                           1/1     Running   1 (6h3m ago)   10h
kube-proxy-p6kns                           1/1     Running   0              5h30m
kube-scheduler-k8smaster                   1/1     Running   4 (45m ago)    10h

9) Test Your Kubernetes Cluster Installation

To test Kubernetes installation, let’s try to deploy nginx based application and try to access it.

$ kubectl create deployment nginx-app --image=nginx --replicas=2

Check the status of nginx-app deployment

$ kubectl get deployment nginx-app
NAME        READY   UP-TO-DATE   AVAILABLE   AGE
nginx-app   2/2     2            2           68s

Expose the deployment as NodePort,

$ kubectl expose deployment nginx-app --type=NodePort --port=80
service/nginx-app exposed

Run following commands to view service status

$ kubectl get svc nginx-app

$ kubectl describe svc nginx-app

# Response ----
Name:                     nginx-app
Namespace:                default
Labels:                   app=nginx-app
Annotations:              <none>
Selector:                 app=nginx-app
Type:                     NodePort
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       10.110.182.144
IPs:                      10.110.182.144
Port:                     <unset>  80/TCP
TargetPort:               80/TCP
NodePort:                 <unset>  30309/TCP
Endpoints:                192.168.166.130:80,192.168.166.131:80
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

Delete a service or deployment or pod

$ kubectl delete services hello-world

$ kubectl delete deployment hello-world

$ kubectl delete pod hello-world

$ kubectl delete -f pod6.yml

Use following curl command to access nginx based application

$ curl http://10.21.172.143:30309/

# Response ----
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

Create a file named “pod5.yml”

# pod5.yml
kind: Pod
apiVersion: v1
metadata:
  name: delhipod
  labels:                                                   
    env: development
    class: pods
spec:
    containers:
       - name: c00
         image: ubuntu
         command: ["/bin/bash", "-c", "while true; do echo Hello-Bhupinder; sleep 5 ; done"]

Create the pod and apply

kubectl apply -f pod5.yml

Get labels of pods or nodes

$ kubectl get pods --show-labels
# Response
NAME       READY   STATUS        RESTARTS   AGE   LABELS
delhipod   1/1     Terminating   0          10h   class=pods,env=development

$ kubectl get nodes --show-labels

Get full details of pods

$ kubectl get pods -o wide
# Response
NAME       READY   STATUS    RESTARTS   AGE   IP                NODE    NOMINATED NODE   READINESS GATES
delhipod   1/1     Running   0          11m   192.168.166.136   node1   <none>           <none>

Add label at runtime

$ kubectl label pods delhipod myname=soundarya

$ kubectl get pods --show-labels
# Response
NAME       READY   STATUS        RESTARTS   AGE   LABELS
delhipod   1/1     Terminating   0          10h   class=pods,env=development,myname=soundarya

Search pod by label

$ kubectl get pods -l myname=soundarya
# Response
NAME       READY   STATUS        RESTARTS   AGE
delhipod   1/1     Terminating   0          22h

Search pod in set

kubectl get pods -l 'env in (development)'
# Response
NAME       READY   STATUS    RESTARTS   AGE
delhipod   1/1     Running   0          16m

ReplicaController

# myrc.yml
kind: ReplicationController
apiVersion: v1
metadata:
  name: myreplica
spec:
  replicas: 5
  selector:
    myname: Bhupinder
  template:
    metadata:
      name: testpod6
      labels:
        myname: Bhupinder
    spec:
     containers:
       - name: c00
         image: ubuntu
         command: ["/bin/bash", "-c", "while true; do echo Hello-Bhupinder; sleep 5 ; done"]

Get replicaController pods

$ kubectl get rc
# Response
NAME        DESIRED   CURRENT   READY   AGE
myreplica   4         4         2       6h49m

Get replicat describe

$ kubectl describe rc myreplica
# Response
Name:         myreplica
Namespace:    default
Selector:     myname=Bhupinder
Labels:       myname=Bhupinder
Annotations:  <none>
Replicas:     4 current / 4 desired
Pods Status:  2 Running / 2 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:  myname=Bhupinder
  Containers:
   c00:
    Image:      ubuntu
    Port:       <none>
    Host Port:  <none>
    Command:
      /bin/bash
      -c
      while true; do echo Hello-Bhupinder; sleep 5 ; done
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Events:
  Type    Reason            Age    From                    Message
  ----    ------            ----   ----                    -------
  Normal  SuccessfulCreate  2m58s  replication-controller  Created pod: myreplica-r42qd
  Normal  SuccessfulCreate  2m58s  replication-controller  Created pod: myreplica-5k4lb

Scale the pod

$ kubectl scale --replicas=3 rc -l myname=Bhupinder

$ kubectl get pods
# Response
NAME              READY   STATUS             RESTARTS   AGE
delhipod          1/1     Running            0          9h
myreplica-5k4lb   0/1     ImagePullBackOff   0          6m9s
myreplica-wbfpf   1/1     Running            0          6h53m
myreplica-wrs9n   1/1     Running            0          6h53m

ReplicaSet

# myrs.yml
kind: ReplicaSet                                    
apiVersion: apps/v1                            
metadata:
  name: myrs
spec:
  replicas: 2  
  selector:                  
    matchExpressions: # these must match the labels
      - {key: myname, operator: In, values: [Bhupinder, Bupinder, Bhopendra]}
      - {key: env, operator: NotIn, values: [production]}
  template:      
    metadata:
      name: testpod7
      labels:              
        myname: Bhupinder
    spec:
     containers:
       - name: c00
         image: ubuntu
         command: ["/bin/bash", "-c", "while true; do echo Technical-Guftgu; sleep 5 ; done"]

Delete replicaset

$ kubectl delete rs/myrs
# Response
replicaset.apps "myrs" deleted

$ kubectl get pods
# Response
NAME         READY   STATUS        RESTARTS      AGE
delhipod     1/1     Running       1 (13m ago)   27h
myrs-m5wzd   1/1     Terminating   1 (13m ago)   17h
myrs-mmt85   1/1     Terminating   1 (13m ago)   17h
myrs-mxks4   1/1     Terminating   1 (13m ago)   17h
myrs-qfcg2   1/1     Terminating   0             47s
myrs-sk4qk   1/1     Terminating   1 (13m ago)   17h

Jobs

Jobs are such pods which would run once and would be terminated. It doesn’t automatically run like normal pod.

# myjob.yml
apiVersion: batch/v1
kind: Job
metadata:
  name: testjob
spec:
  template:
    metadata:
      name: testjob
    spec:
      containers:
      - name: counter
        image: centos:7
        command: ["bin/bash", "-c", "echo Technical-Guftgu; sleep 5"]
      restartPolicy: Never
$ kubectl get pods
# Response
NAME            READY   STATUS      RESTARTS   AGE
delhipod        0/1     Error       1          30h
testjob-n7gjh   0/1     Completed   0          131m

Jobs in parallel

# myjobparallel.yml
apiVersion: batch/v1
kind: Job
metadata:
  name: testjob1
spec:
  parallelism: 5                           # Runs for pods in parallel
  activeDeadlineSeconds: 10  # Timesout after 30 sec
  template:
    metadata:
      name: testjob1
    spec:
      containers:
      - name: counter
        image: centos:7
        command: ["bin/bash", "-c", "echo Technical-Guftgu; sleep 20"]
      restartPolicy: Never
$ kubectl apply -f myjobparallel.yml 
# Response
job.batch/testjob1 created

$ kubectl get pods
# Response
NAME             READY   STATUS      RESTARTS   AGE
delhipod         0/1     Error       1          30h
testjob-n7gjh    0/1     Completed   0          144m
testjob1-6vdnw   1/1     Running     0          3s
testjob1-76gzl   1/1     Running     0          3s
testjob1-s5ttc   1/1     Running     0          3s
testjob1-vxn66   1/1     Running     0          3s
testjob1-w9ssf   1/1     Running     0          3s

Watch the changing statue of pods

$ watch kubectl get pods

Cron Jobs

Jobs that need to run on a schedule time. This will run every 1 minute

# mycron.yml
apiVersion: batch/v1
kind: CronJob
metadata:
 name: bhupi
spec:
 schedule: "* * * * *"
 jobTemplate:
   spec:
     template:
       spec:
         containers:
         - image: ubuntu
           name: bhupi
           command: ["/bin/bash", "-c", "echo Technical-Guftgu; sleep 5"]
         restartPolicy: Never

Init Containers

The main container will only be created once the init container is ready and working properly

# init.yml
apiVersion: v1
kind: Pod
metadata:
  name: initcontainer
spec:
  initContainers:
  - name: c1
    image: centos
    command: ["/bin/sh", "-c", "echo LIKE AND SUBSCRIBE TECHNICAL GUFTGU > /tmp/xchange/testfile; sleep 30"]
    volumeMounts:        
      - name: xchange
        mountPath: "/tmp/xchange"  
  containers:
  - name: c2
    image: centos
    command: ["/bin/bash", "-c", "while true; do echo `cat /tmp/data/testfile`; sleep 5; done"]
    volumeMounts:
      - name: xchange
        mountPath: "/tmp/data"
  volumes:                            
  - name: xchange
    emptyDir: {}

Check logs

$ kubectl logs -f pod/initcontainer
# Response
Defaulted container "c2" out of: c2, c1 (init)
LIKE AND SUBSCRIBE TECHNICAL GUFTGU
LIKE AND SUBSCRIBE TECHNICAL GUFTGU
LIKE AND SUBSCRIBE TECHNICAL GUFTGU

Check status of pod lifecycle phases

$ kubectl describe pod/initcontainer | grep -A 5 Conditions
# Response
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 

Pod Life Cycle

Lifecycle phases of a pod

  • pending – pod has been accepted by k8s, but not running
  • running – pod has been bound to a node, all containers are created and atleast one container is running
  • succeeded – containers in the pod have terminated and will not restart
  • failed – failed for any reason
  • completed – when the pod has run everything and nothing is left
  • unknown – when state of pod could not be obtained, typically due to network error, node is not known to master

Deployment

# deployment.yml

kind: Deployment
apiVersion: apps/v1
metadata:
   name: mydeployments
spec:
   replicas: 2
   selector:     
    matchLabels:
     name: deployment
   template:
     metadata:
       name: testpod
       labels:
         name: deployment
     spec:
      containers:
        - name: c00
          image: ubuntu
          command: ["/bin/bash", "-c", "while true; do echo Technical-Guftgu; sleep 5; done"]

Check status of deployments

$ kubectl get deploy
# Response
NAME            READY   UP-TO-DATE   AVAILABLE   AGE
mydeployments   2/2     2            2           72s

Describe deployments

$ kubectl describe deploy mydeployments
# Response
Name:                   mydeployments
Namespace:              default
CreationTimestamp:      Tue, 26 Sep 2023 18:43:28 +0530
Labels:                 <none>
Annotations:            deployment.kubernetes.io/revision: 1
Selector:               name=deployment
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:  name=deployment
  Containers:
   c00:
    Image:      ubuntu
    Port:       <none>
    Host Port:  <none>
    Command:
      /bin/bash
      -c
      while true; do echo Technical-Guftgu; sleep 5; done
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  <none>
NewReplicaSet:   mydeployments-64c9b975b7 (2/2 replicas created)
Events:
  Type    Reason             Age    From                   Message
  ----    ------             ----   ----                   -------
  Normal  ScalingReplicaSet  2m25s  deployment-controller  Scaled up replica set mydeployments-64c9b975b7 to 2

Get replicaset information

$ kubectl get rs
# Response
NAME                       DESIRED   CURRENT   READY   AGE
mydeployments-64c9b975b7   2         2         2       3m41s

Scale up or down the replica

$ kubectl scale --replicas=1 deploy mydeployments
# Response
deployment.apps/mydeployments scaled

# Check the updated replica

$ kubectl get rs
# Response
NAME                       DESIRED   CURRENT   READY   AGE
mydeployments-64c9b975b7   1         1         1       4m57s

Status of deployment

$ kubectl rollout status deploy mydeployments
deployment "mydeployments" successfully rolled out

History of versions

$ kubectl rollout history deploy mydeployments
deployment.apps/mydeployments 
REVISION  CHANGE-CAUSE
1         <none>

Update the manifest file and apply.
Changing the log and image details in yml file

# deployment.yml
kind: Deployment
apiVersion: apps/v1
metadata:
   name: mydeployments
spec:
   replicas: 2
   selector:     
    matchLabels:
     name: deployment
   template:
     metadata:
       name: testpod
       labels:
         name: deployment
     spec:
      containers:
        - name: c00
          image: centos
          command: ["/bin/bash", "-c", "while true; do echo love you; sleep 5; done"]
$ kubectl apply -f deployment.yml
# Response
deployment.apps/mydeployments configured

$ kubectl get deploy
# Response
NAME            READY   UP-TO-DATE   AVAILABLE   AGE
mydeployments   2/2     1            2           28m

$ kubectl get rs
# Response
NAME                       DESIRED   CURRENT   READY   AGE
mydeployments-64c9b975b7   0         0         0       29m
mydeployments-6bcf54f76f   2         2         2       24s

$ kubectl get pods
# Response
NAME                             READY   STATUS    RESTARTS   AGE
delhipod                         0/1     Error     1          2d5h
mydeployments-6bcf54f76f-j9hfs   1/1     Running   0          68s
mydeployments-6bcf54f76f-rkvj6   1/1     Running   0          50s

$ kubectl logs -f mydeployments-6bcf54f76f-j9hfs
# Response
love you
love you

$ kubectl exec mydeployments-6bcf54f76f-j9hfs -- cat /etc/os-release 
# Response
NAME="CentOS Linux"
VERSION="8"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="8"
PLATFORM_ID="platform:el8"
PRETTY_NAME="CentOS Linux 8"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:8"
HOME_URL="https://centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"
CENTOS_MANTISBT_PROJECT="CentOS-8"
CENTOS_MANTISBT_PROJECT_VERSION="8"

History after changes in the yml file

$  kubectl rollout history deploy mydeployments
# Response
deployment.apps/mydeployments 
REVISION  CHANGE-CAUSE
1         <none>
2         <none>

Undo to the last deployment

$ kubectl rollout undo deploy/mydeployments
# Response
deployment.apps/mydeployments rolled back

$ kubectl get pods | grep Running
# Response
mydeployments-64c9b975b7-bjn27   1/1     Running   0          3h21m
mydeployments-64c9b975b7-zlb5f   1/1     Running   0          3h20m

$ kubectl exec mydeployments-64c9b975b7-bjn27 -- cat /etc/os-release
# Response
PRETTY_NAME="Ubuntu 22.04.3 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.3 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy

$ kubectl logs -f mydeployments-64c9b975b7-bjn27
# Response
Technical-Guftgu
Technical-Guftgu

Network call between two containers on same Pod and same Node

# pod1.yml
kind: Pod
apiVersion: v1
metadata:
  name: testpod
spec:
  containers:
    - name: c00
      image: ubuntu
      command: ["/bin/bash", "-c", "while true; do echo Hello-Bhupinder; sleep 5 ; done"]
    - name: c01
      image: httpd
      ports:
       - containerPort: 80

Install the pod

$ kubectl apply -f pod1.yml

$ kubectl get pods
NAME       READY   STATUS    RESTARTS   AGE
testpod3   2/2     Running   0          4m6s

Call one container from other container using localhost and port

# -- Get into the container shell
$ kubectl exec testpod -it -c c00 -- /bin/bash
# Response
root@testpod:/

# -- update and install curl in container
root@testpod:/ apt update && apt install curl

# -- call localhost:80 which is running on other container
root@testpod3:/ curl localhost:80
<html><body><h1>It works!</h1></body></html>

Network call between two containers on different Pod and same Node

# pod2.yml
kind: Pod
apiVersion: v1
metadata:
  name: testpod1
spec:
  containers:
    - name: c01
      image: nginx
      ports: 
       - containerPort: 80

# pod3.yml
kind: Pod
apiVersion: v1
metadata:
  name: testpod4
spec:
  containers:
    - name: c03
      image: httpd
      ports:
       - containerPort: 80
$ kubectl apply -f pod2.yml 
# Response
pod/testpod1 created

$ kubectl apply -f pod3.yml 
# Response
pod/testpod4 created

$ kubectl get pods -o wide
# Response
NAME       READY   STATUS    RESTARTS   AGE   IP                NODE    NOMINATED NODE   READINESS GATES
testpod1   1/1     Running   0          5s    192.168.166.153   node1   <none>           <none>
testpod4   1/1     Running   0          14m   192.168.166.150   node1   <none>           <none>

$ curl 192.168.166.153:80
# Response
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
</html>

$ curl 192.168.166.150:80
# Response
<html><body><h1>It works!</h1></body></html>

ClusterIP

Network call between two containers on different Pod and different Node

These call are within the cluster only

# deployhttpd.yml
kind: Deployment
apiVersion: apps/v1
metadata:
   name: mydeployments
spec:
   replicas: 1
   selector:      # tells the controller which pods to watch/belong to
    matchLabels:
     name: deployment
   template:
     metadata:
       name: testpod1
       labels:
         name: deployment
     spec:
      containers:
        - name: c00
          image: httpd
          ports:
          - containerPort: 80
# service.yml
kind: Service                             # Defines to create Service type Object
apiVersion: v1
metadata:
  name: demoservice
spec:
  ports:
    - port: 80                               # Containers port exposed
      targetPort: 80                     # Pods port
  selector:
    name: deployment                    # Apply this service to any pods which has the specific label
  type: ClusterIP                       # Specifies the service type i.e ClusterIP or NodePort

Apply pod and service

$ kubectl apply -f deployhttpd.yml
$ kubectl apply -f service.yml

# Check the pod IPs
$ kubectl get pods -o wide
NAME                             READY   STATUS    RESTARTS   AGE   IP                NODE    NOMINATED NODE   READINESS GATES
mydeployments-685f595fb8-vgd52   1/1     Running   0          37s   192.168.166.138   node1   <none>           <none>

# Check the services
$ kubectl get svc
NAME          TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
demoservice   ClusterIP   10.111.72.42   <none>        80/TCP    8s
kubernetes    ClusterIP   10.96.0.1      <none>        443/TCP   5d2h

$ curl 10.111.72.42:80
<html><body><h1>It works!</h1></body></html>

NodePort

Expose Nginx outside cluster, make a servie accessible from outside the cluster

Exposes the service on the same port of each selected node in the Cluster using NAT.

# deploynginx.yml
kind: Deployment
apiVersion: apps/v1
metadata:
   name: mydeployments-nginx
spec:
   replicas: 1
   selector:      # tells the controller which pods to watch/belong to
    matchLabels:
     name: deployment-nginx
   template:
     metadata:
       name: testpod1
       labels:
         name: deployment-nginx
     spec:
      containers:
        - name: c00
          image: nginx
          ports:
          - containerPort: 80
# svcnginx.yml
kind: Service                             # Defines to create Service type Object
apiVersion: v1
metadata:
  name: nginxservice
spec:
  ports:
    - port: 80                               # Containers port exposed
      targetPort: 80                     # Pods port
  selector:
    name: deployment-nginx                  # Apply this service to any pods which has the specific label
  type: NodePort                       # Specifies the service type i.e ClusterIP or NodePort

$ kubectl apply -f deploynginx.yml 
# Response
deployment.apps/mydeployments-nginx created

$ kubectl apply -f svcnginx.yml 
# Response
service/nginxservice created
$ kubectl get services -o wide
# Response
NAME           TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE    SELECTOR
demoservice    NodePort    10.110.10.157   <none>        80:32245/TCP   104m   name=deployment
kubernetes     ClusterIP   10.96.0.1       <none>        443/TCP        7d2h   <none>
nginxservice   NodePort    10.100.147.56   <none>        80:30775/TCP   27s    name=deployment-nginx

$ kubectl get nodes -o wide
# Response
NAME        STATUS   ROLES           AGE     VERSION   INTERNAL-IP     EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION      CONTAINER-RUNTIME
k8smaster   Ready    control-plane   7d2h    v1.28.2   10.21.172.44    <none>        Ubuntu 22.04.3 LTS   5.15.0-84-generic   containerd://1.6.24
node1       Ready    <none>          6d21h   v1.28.2   10.21.172.143   <none>        Ubuntu 22.04.3 LTS   5.15.0-84-generic   containerd://1.6.24

Call the service using node/master IP and service port

NGINX service

curl http://10.21.172.143:30775
# Response
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>

Volumes

EmptyDir, volume is mounted on the Pod

Share volume between containers within the same Pod.

# emptydir.yml
apiVersion: v1
kind: Pod
metadata:
  name: myvolemptydir
spec:
  containers:
  - name: c1
    image: centos
    command: ["/bin/bash", "-c", "sleep 15000"]
    volumeMounts:                                    # Mount definition inside the container
      - name: xchange
        mountPath: "/tmp/xchange"          
  - name: c2
    image: centos
    command: ["/bin/bash", "-c", "sleep 10000"]
    volumeMounts:
      - name: xchange
        mountPath: "/tmp/data"
  volumes:                                                   
  - name: xchange
    emptyDir: {}
kubectl apply -f myjob.yml

$ kubectl get pods
# Response
NAME            READY   STATUS    RESTARTS   AGE
myvolemptydir   2/2     Running   0          6m37s

$ kubectl exec myvolemptydir -c c1 -it -- /bin/bash
# Response
[root@myvolemptydir /]# 
[root@myvolemptydir /]# cd /tmp/xchange/
[root@myvolemptydir xchange]# ls
a1  ab1.txt

$ kubectl exec myvolemptydir -c c2 -it -- /bin/bash
[root@myvolemptydir /]# 
[root@myvolemptydir /]# cd tmp/data/
[root@myvolemptydir data]# ls
a1  ab1.txt

EmptyDir, volume is mounted on the Host

# hostpath.yml
apiVersion: v1
kind: Pod
metadata:
  name: myvolhostpath
spec:
  containers:
  - image: centos
    name: testc
    command: ["/bin/bash", "-c", "sleep 15000"]
    volumeMounts:
    - mountPath: /tmp/hostpath
      name: testvolume
  volumes:
  - name: testvolume
    hostPath:
      path: /tmp/data 
kubectl apply -f hostpath.yml

$ kubectl get pods
# Response
NAME            READY   STATUS    RESTARTS   AGE
myvolhostpath   1/1     Running   0          4m26s

$ kubectl exec myvolhostpath -- ls /tmp/
# Response
hostpath
ks-script-4luisyla
ks-script-o23i7rc2
ks-script-x6ei4wuu

Check the data folder created in the host, in this case it is the node and not the master

ubuntu@node1:~$ cd /tmp/
ubuntu@node1:/tmp$ ls
data
snap-private-tmp
systemd-private-9b930295dc42473f9a6c7b7ec60205cc-systemd-logind.service-4UOSb2
systemd-private-9b930295dc42473f9a6c7b7ec60205cc-systemd-resolved.service-6Ucg4d
systemd-private-9b930295dc42473f9a6c7b7ec60205cc-systemd-timesyncd.service-rStvZL

Persistent Volume

Sharing the volume between different nodes which is not stored on node, but on separate data volume. https://openebs.io/docs/user-guides/localpv-hostpath

Install OpenEBS

kubectl apply -f https://openebs.github.io/charts/openebs-operator.yaml

Create a configuration file for PersistentVolumeClaim

# local-hostpath-pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: local-hostpath-pvc
spec:
  storageClassName: openebs-hostpath
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5G

Create the PersistentVolumeClaim

$ kubectl apply -f local-hostpath-pvc.yaml
# Response
persistentvolumeclaim/local-hostpath-pvc created

$ kubectl get pv
# Response
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                        STORAGECLASS       REASON   AGE
pvc-053537cb-ad82-4a23-a522-bab3c9fcccd4   5G         RWO            Delete           Bound    default/local-hostpath-pvc   openebs-hostpath            17m

$ kubectl get pvc local-hostpath-pvc
# Response
NAME                 STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS       AGE
local-hostpath-pvc   Pending                                      openebs-hostpath   4s

Create confiration file for pod using the PV(persistent volume)

# local-hostpath-pod.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-local-hostpath-deploy
spec:
  replicas: 1
  selector:
    matchLabels:
      name: local-pvc
  template:
    metadata:
      name: testpod2
      labels:
        name: local-pvc
    spec:
      containers:
      - name: hello-container
        image: busybox
        command:
           - sh
           - -c
           - 'while true; do echo "`date` [`hostname`] Hello from OpenEBS Local PV." >> /mnt/store/greet.txt; sleep $(($RANDOM % 5 + 300)); done'
        volumeMounts:
        - mountPath: /mnt/store
          name: local-storage        
      volumes:
      - name: local-storage
        persistentVolumeClaim:
          claimName: local-hostpath-pvc

Create the Pod

$ kubectl apply -f local-hostpath-pod1.yaml 
# Response
deployment.apps/hello-local-hostpath-deploy created

Verify that the container in the Pod is running

$ kubectl get pods
# Response
NAME                                           READY   STATUS    RESTARTS      AGE
hello-local-hostpath-deploy-57bc4fd889-kx227   1/1     Running   0             67s

# Verify that the data is being written to the volume

$ kubectl exec hello-local-hostpath-deploy-57bc4fd889-kx227 -- cat /mnt/store/greet.txt
# Response
Sun Oct  1 16:01:50 UTC 2023 [hello-local-hostpath-pod] Hello from OpenEBS Local PV.

$ kubectl describe pod hello-local-hostpath-deploy-57bc4fd889-sqhdv
# Response
ame:             hello-local-hostpath-deploy-57bc4fd889-sqhdv
Namespace:        default
Priority:         0
Service Account:  default
Node:             node1/10.21.172.143
Start Time:       Sun, 01 Oct 2023 22:37:56 +0530

Details about the dynamically provisioned Local PersistentVolume

$ kubectl get pvc local-hostpath-pvc
# Response
NAME                 STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS       AGE
local-hostpath-pvc   Bound    pvc-053537cb-ad82-4a23-a522-bab3c9fcccd4   5G         RWO            openebs-hostpath   2m15s

Look at the PersistentVolume details to see where the data is stored

$ kubectl get pv  pvc-053537cb-ad82-4a23-a522-bab3c9fcccd4  -o yaml
# Response
apiVersion: v1
kind: PersistentVolume
metadata:
  annotations:
    pv.kubernetes.io/provisioned-by: openebs.io/local
  creationTimestamp: "2023-10-01T16:01:42Z"
  finalizers:
  - kubernetes.io/pv-protection
  labels:
    openebs.io/cas-type: local-hostpath
  name: pvc-053537cb-ad82-4a23-a522-bab3c9fcccd4
  resourceVersion: "435983"
  uid: 60882a22-60f0-4e7d-a339-3c33a9fe6828
spec:
  accessModes:
  - ReadWriteOnce
  capacity:
    storage: 5G
  claimRef:
    apiVersion: v1
    kind: PersistentVolumeClaim
    name: local-hostpath-pvc
    namespace: default
    resourceVersion: "435916"
    uid: 053537cb-ad82-4a23-a522-bab3c9fcccd4
  local:
    fsType: ""
    path: /var/openebs/local/pvc-053537cb-ad82-4a23-a522-bab3c9fcccd4
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - node1
  persistentVolumeReclaimPolicy: Delete
  storageClassName: openebs-hostpath
  volumeMode: Filesystem
status:
  phase: Bound

Available pods

$ kubectl get pods
# Response
NAME                                           READY   STATUS    RESTARTS      AGE
hello-local-hostpath-deploy-57bc4fd889-sqhdv   1/1     Running   0             48s
myvolhostpath                                  1/1     Running   2 (94m ago)   46h

Check the content via the mount point

$ kubectl exec hello-local-hostpath-deploy-57bc4fd889-sqhdv -- cat /mnt/store/greet.txt
# Response
Sun Oct  1 16:39:00 UTC 2023 [hello-local-hostpath-pod] Hello from OpenEBS Local PV.
Sun Oct  1 16:44:00 UTC 2023 [hello-local-hostpath-pod] Hello from OpenEBS Local PV.
Sun Oct  1 16:49:02 UTC 2023 [hello-local-hostpath-pod] Hello from OpenEBS Local PV.
Sun Oct  1 17:06:40 UTC 2023 [hello-local-hostpath-deploy-57bc4fd889-kx227] Hello from OpenEBS Local PV.
Sun Oct  1 17:07:59 UTC 2023 [hello-local-hostpath-deploy-57bc4fd889-sqhdv] Hello from OpenEBS Local PV.

Check the content written in the Persistent volume, in this case, the path is on the node1

ubuntu@node1:/var/openebs$ cd local/
ubuntu@node1:/var/openebs/local$ ls
pvc-750a755b-9bd9-47bf-8caf-f8907f741354
ubuntu@node1:/var/openebs/local$ cd pvc-750a755b-9bd9-47bf-8caf-f8907f741354/
ubuntu@node1:/var/openebs/local/pvc-750a755b-9bd9-47bf-8caf-f8907f741354$ ls
greet.txt
ubuntu@node1:/var/openebs/local/pvc-750a755b-9bd9-47bf-8caf-f8907f741354$ cat greet.txt 
Sun Oct  1 16:39:00 UTC 2023 [hello-local-hostpath-pod] Hello from OpenEBS Local PV.

Liveness Probe

# liveness.yml
apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: mylivenessprobe
spec:
  containers:
  - name: liveness
    image: ubuntu
    args:
    - /bin/sh
    - -c
    - touch /tmp/healthy; sleep 1000
    livenessProbe:                                          
      exec:
        command:                                         
        - cat                
        - /tmp/healthy
      initialDelaySeconds: 5          
      periodSeconds: 5                                 
      timeoutSeconds: 30   

Namespaces

Create a new namespace

# devns.yml
apiVersion: v1
kind: Namespace
metadata:
   name: dev
   labels:
     name: dev
$ kubectl apply -f devns.yml 
# Response
namespace/dev created

$ kubectl get ns
# Response
NAME              STATUS   AGE
default           Active   10d
dev               Active   2s
kube-node-lease   Active   10d
kube-public       Active   10d
kube-system       Active   10d
openebs           Active   37h

Configuration file for new pod

# devpod.yml
kind: Pod                              
apiVersion: v1                     
metadata:                           
  name: testpod                  
spec:                                    
  containers:                      
    - name: c00                     
      image: ubuntu              
      command: ["/bin/bash", "-c", "while true; do echo Technical Guftgu; sleep 5 ; done"]
  restartPolicy: Never

Create Pod in the namespace dev

$ kubectl apply -f devpod.yml -n dev
# Response
pod/testpod created

$ kubectl get pods
# Response
No resources found in default namespace.

$ kubectl get pods -n dev
# Response
NAME      READY   STATUS    RESTARTS   AGE
testpod   1/1     Running   0          7s

Delete pod of the namespace dev

$ kubectl delete -f devpod.yml -n dev
# Response
pod "testpod" delete

Set dev namespace as default namespace

$ kubectl config set-context $(kubectl config current-context) --namespace=dev
# Response
Context "kubernetes-admin@kubernetes" modified.

$ kubectl get pods
# Response
NAME      READY   STATUS    RESTARTS   AGE
testpod   1/1     Running   0          24s

Find current namespace

$ kubectl config view | grep namespace
# Response
namespace: dev

Manage Resource Quota

# podresources.yml
apiVersion: v1
kind: Pod
metadata:
  name: resources
spec:
  containers:
  - name: resource
    image: centos
    command: ["/bin/bash", "-c", "while true; do echo Technical-Guftgu; sleep 5 ; done"]
    resources:                                          
      requests:
        memory: "64Mi"
        cpu: "100m"
      limits:
        memory: "128Mi"
        cpu: "200m"
# resourcequota.yml
apiVersion: v1
kind: ResourceQuota
metadata:
   name: myquota
spec:
  hard:
    limits.cpu: "400m"
    limits.memory: "400Mi"
    requests.cpu: "200m"
    requests.memory: "200Mi"
# resource-quota-deployments.yml
kind: Deployment
apiVersion: apps/v1
metadata:
  name: resource-quota-deployments
spec:
  replicas: 3
  selector:      
    matchLabels:
     objtype: deployment
  template:
    metadata:
      name: testpod8
      labels:
        objtype: deployment
    spec:
     containers:
       - name: c00
         image: ubuntu
         command: ["/bin/bash", "-c", "while true; do echo Technical-Guftgu; sleep 5 ; done"]
         resources:
            requests:
              cpu: "200m"

Set the default value for CPU Limit and CPU Request for a pod

# cpu-limit-range.yml
apiVersion: v1
kind: LimitRange
metadata:
  name: cpu-limit-range
spec:
  limits:
  - default:
      cpu: 1
    defaultRequest:
      cpu: 0.5
    type: Container

Request – undefined Limit – defined

# cpu2.yml
apiVersion: v1
kind: Pod
metadata:
  name: default-cpu-demo-2
spec:
  containers:
  - name: default-cpu-demo-2-ctr
    image: nginx
    resources:
      limits:
        cpu: "1"

# Response
Limits:
  cpu:  1
Requests:
  cpu:        1

Request – defined Limit – undefined

# cpu3.yml
apiVersion: v1
kind: Pod
metadata:
  name: default-cpu-demo-3
spec:
  containers:
  - name: default-cpu-demo-3-ctr
    image: nginx
    resources:
      requests:
        cpu: "0.75"

# Response
Limits:
  cpu:  1
Requests:
  cpu:        750m

Horizontal Pod Autoscaler(HPA)

# Install metric server
wget -O metricserver.yml https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

# Add this line in the args section of kind: Deployment
- --kubelet-insecure-tls

# Apply the metric server
$ kubectl apply -f metricserver.yml 
# Response
serviceaccount/metrics-server created
# deployhpa.yml
kind: Deployment
apiVersion: apps/v1
metadata:
   name: mydeploy
spec:
   replicas: 1
   selector:
    matchLabels:
     name: deployment
   template:
     metadata:
       name: testpod8
       labels:
         name: deployment
     spec:
      containers:
        - name: c00
          image: httpd
          ports:
          - containerPort: 80
          resources:
            limits:
              cpu: 500m
            requests:
              cpu: 200m
$ kubectl autoscale deployment mydeploy --cpu-percent=20 --min=1 --max=10

Go to a pod and call the apt update so that cpu usage increase

ubuntu@k8smaster:~$ kubectl get pods
# Response
NAME                        READY   STATUS    RESTARTS   AGE
mydeploy-5c49c88d9f-68zls   1/1     Running   0          2m18s
mydeploy-5c49c88d9f-6g6m6   1/1     Running   0          3m39s

ubuntu@k8smaster:~$ kubectl exec mydeploy-5c49c88d9f-6g6m6 -it -- /bin/bash
# Response
root@mydeploy-5c49c88d9f-6g6m6:/usr/local/apache2# apt update
$ kubectl get all
# Response
NAME                            READY   STATUS    RESTARTS   AGE
pod/mydeploy-5c49c88d9f-4l8nl   1/1     Running   0          8m23s
pod/mydeploy-5c49c88d9f-cbqp2   1/1     Running   0          3m19s

NAME                       READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/mydeploy   5/5     5            5           8m23s

NAME                                  DESIRED   CURRENT   READY   AGE
replicaset.apps/mydeploy-5c49c88d9f   5         5         5       8m23s

NAME                                           REFERENCE             TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
horizontalpodautoscaler.autoscaling/mydeploy   Deployment/mydeploy   0%/20%    1         10        5          7m20s

Helm and Helm Chart

https://www.youtube.com/watch?v=FpJpHWe3Va4

To download helm

curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3
chmod 700 get_helm.sh
./get_helm.sh

$ helm version
# Response
version.BuildInfo{Version:"v3.13.0", GitCommit:"825e86f6a7a38cef1112bfa606e4127a706749b1", GitTreeState:"clean", GoVersion:"go1.20.8"}

Helm repo list

$ helm list
# Response
NAME    NAMESPACE       REVISION        UPDATED STATUS  CHART   APP VERSION


# Create first helm chart
$ helm repo add stable https://charts.helm.sh/stable
# Response
"stable" has been added to your repositories


$ helm repo list
# Response
NAME    URL                          
stable  https://charts.helm.sh/stable


# Search repo
$ helm search repo jenkins
# Response
NAME            CHART VERSION   APP VERSION     DESCRIPTION                                       
stable/jenkins  2.5.4           lts             DEPRECATED - Open source continuous integration...


# Remove helm repo
$ helm repo remove stable
# Response
"stable" has been removed from your repositories

Create helm chart

ubuntu@k8smaster:~/helm_files$ helm create helloworld
# Response
Creating helloworld

ubuntu@k8smaster:~/helm_files$ ls
# Response
helloworld

ubuntu@k8smaster:~/helm_files$ cd helloworld/
ubuntu@k8smaster:~/helm_files/helloworld$ ls
# Response
Chart.yaml  charts  templates  values.yaml

ubuntu@k8smaster:~/helm_files/helloworld$ tree
# Response
├── Chart.yaml
├── charts
├── templates
│   ├── NOTES.txt
│   ├── _helpers.tpl
│   ├── deployment.yaml
│   ├── hpa.yaml
│   ├── ingress.yaml
│   ├── service.yaml
│   ├── serviceaccount.yaml
│   └── tests
│       └── test-connection.yaml
└── values.yaml

3 directories, 10 files
# Install helm chart
ubuntu@k8smaster:~/helm_files$ helm install testjenkins stable/jenkins
# Response
WARNING: This chart is deprecated
....


# Get all details
ubuntu@k8smaster:~/helm_files$ kubectl get all
# Response
NAME                               READY   STATUS    RESTARTS      AGE
pod/mydeploy-5c49c88d9f-lq5zb      1/1     Running   1 (36m ago)   31h
pod/testjenkins-86f7fc84df-mpsts   0/2     Pending   0             62s

NAME                        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)     AGE
service/kubernetes          ClusterIP   10.96.0.1       <none>        443/TCP     42h
service/testjenkins         ClusterIP   10.101.64.238   <none>        8080/TCP    62s
service/testjenkins-agent   ClusterIP   10.100.0.104    <none>        50000/TCP   62s

NAME                          READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/mydeploy      1/1     1            1           31h
deployment.apps/testjenkins   0/1     1            0           62s

NAME                                     DESIRED   CURRENT   READY   AGE
replicaset.apps/mydeploy-5c49c88d9f      1         1         1       31h
replicaset.apps/testjenkins-86f7fc84df   1         1         0       62s

NAME                                           REFERENCE             TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
horizontalpodautoscaler.autoscaling/mydeploy   Deployment/mydeploy   0%/5%     1         10        1          42h


# Delete helm chart
$ helm delete testjenkins
# Response
release "testjenkins" uninstalled


# Get all details
ubuntu@k8smaster:~/helm_files$ kubectl get all
# Response
NAME                            READY   STATUS    RESTARTS      AGE
pod/mydeploy-5c49c88d9f-lq5zb   1/1     Running   1 (41m ago)   31h

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

NAME                       READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/mydeploy   1/1     1            1           31h

NAME                                  DESIRED   CURRENT   READY   AGE
replicaset.apps/mydeploy-5c49c88d9f   1         1         1       31h

NAME                                           REFERENCE             TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
horizontalpodautoscaler.autoscaling/mydeploy   Deployment/mydeploy   0%/5%     1         10        1          42h

List all the named releases

$ helm list
# Response
NAME            NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION
testtomcat      default         1               2023-10-05 20:20:37.533286776 +0530 IST deployed        tomcat-0.4.3    7.0        

Helm upgrade and rollback

# Install helm chart
$ helm install testchart stable/tomcat --version 0.4.0
# Response
NAME: testchart
LAST DEPLOYED: Fri Oct  6 00:02:20 2023
...


# List helm revisions
$ helm history testchart
# Response
REVISION        UPDATED                         STATUS          CHART           APP VERSION     DESCRIPTION     
1               Fri Oct  6 00:02:20 2023        deployed        tomcat-0.4.0    7.0             Install complete


# Upgrade the htlm chart
$ helm upgrade testchart stable/tomcat
# Response
WARNING: This chart is deprecated
false
Release "testchart" has been upgraded. Happy Helming!
...


# List helm revisions
$ helm history testchart
# Response
REVISION        UPDATED                         STATUS          CHART           APP VERSION     DESCRIPTION     
1               Fri Oct  6 00:02:20 2023        superseded      tomcat-0.4.0    7.0             Install complete
2               Fri Oct  6 00:03:26 2023        deployed        tomcat-0.4.3    7.0             Upgrade complete


# Rollback to revision 1
$ helm rollback testchart
# Response

Rollback was a success! Happy Helming!
$ helm history testchart
# Response
REVISION        UPDATED                         STATUS          CHART           APP VERSION     DESCRIPTION     
1               Fri Oct  6 00:02:20 2023        superseded      tomcat-0.4.0    7.0             Install complete
2               Fri Oct  6 00:03:26 2023        superseded      tomcat-0.4.3    7.0             Upgrade complete
3               Fri Oct  6 00:12:08 2023        deployed        tomcat-0.4.0    7.0             Rollback to 1 

Download helm package

# Down helm package in tar format
$ helm pull stable/tomcat
$ ls
# Response
helloworld  tomcat-0.4.3.tgz


# Down helm package and untar it
$ helm pull stable/tomcat --untar
$ ls
helloworld  tomcat

# Directory structure of tomcat package
$ tree tomcat/
tomcat/
├── Chart.yaml
├── README.md
├── templates
│   ├── NOTES.txt
│   ├── _helpers.tpl
│   ├── appsrv-svc.yaml
│   └── appsrv.yaml
└── values.yaml

1 directory, 7 files

Leave a Reply

Your email address will not be published. Required fields are marked *