Author: Ojas Jawale

Table of Contents


  1. Project Overview

In this Kubernetes project, the goal is to deploy and manage an application using the ojasjawale/notes-app:latest image within a dedicated namespace, notes-app on minikube cluster. This deployment will incorporate a wide range of Kubernetes concepts, each contributing to a robust and secure application environment.

This project is an extension of previous project deployed -> Django Notes App

Where, deployed an Django Notes application using Docker and pushed image on DockerHub. Now as an add-on of kubernetes, using same image deployed on DockerHub.


  1. Installation of Minikube Cluster

For detailed steps of installation of minikube cluster visit -> Minikube Installation

In Next steps we will directly going to setup k8s cluster for project.


  1. Step 1 : Namespace Creation
  • Create a namespace to organize all Kubernetes resources for this project.
  • Create namespace.yml file,
  • This YAML file creates a namespace named notes-app to isolate resources and manage them more easily.
apiVersion: v1
kind: Namespace
metadata:
  name: notes-app
  • Apply file
kubectl apply -f namespace.yml

  1. Step 2 : Create Deployment
  • Deploy the notes-app using a Deployment resource to manage replicas and updates.
  • Create deployment.yml file,
  • This Deployment ensures three replicas of the notes-app container are running and manages updates seamlessly.
apiVersion: apps/v1
kind: Deployment
metadata:
  name: notes-app-deployment
  namespace: notes-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: notes-app
  template:
    metadata:
      labels:
        app: notes-app
    spec:
      containers:
      - name: notes-app
        image: ojasjawale/notes-app:latest
        ports:
        - containerPort: 8000
  • Apply file
kubectl apply -f deployment.yml

  1. Step 3 : Create Service
  • Expose the notes-app deployment using a Service.
  • Create service.yml file,
apiVersion: v1
kind: Service
metadata:
  name: notes-app-service
  namespace: notes-app
spec:
  selector:
    app: notes-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8000
  • Apply file
kubectl apply -f service.yml
  • For testing, port forwarding of traffic.
kubectl port-forward service/notes-app-service 8000:80 --address=0.0.0.0 -n notes-app
  • Copy Public IP of instance with port 8000 and access application on browser.

  1. Step 4 : Persistent Volumes and Claims
  • Set up Persistent Volumes (PV) and Persistent Volume Claims (PVC) for stateful applications.
  • Create pv.yml file,
apiVersion: v1
kind: PersistentVolume
metadata:
  name: notes-app-pv
  namespace: notes-app
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: /mnt/data
  • Apply file
kubectl apply -f pv.yml
  • Till now persistentVolume is not claimed.
  • PV defines the storage resource, while PVC requests storage for a pod.
  • Create pvc.yml file

Claiming PV storage for POD’s.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: notes-app-pvc
  namespace: notes-app
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
  • Apply file
kubectl apply -f pvc.yml



  • Attach storage to deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: notes-app-deployment
  namespace: notes-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: notes-app
  template:
    metadata:
      labels:
        app: notes-app
    spec:
      containers:
      - name: notes-app
        image: ojasjawale/notes-app:latest
        ports:
        - containerPort: 8000
        volumeMounts:
        - name: notes-app-storage
          mountPath: /data  # Mount path inside the container
      volumes:
      - name: notes-app-storage
        persistentVolumeClaim:
          claimName: notes-app-pvc  # Reference to the PVC


  1. Step 5 : Ingress Controller

To setup Ingress in minikube, need to enable addon called ingress

minikube addon enable ingress
  • Set up an Ingress for path-based routing to the application.
  • Create ingress.yml file,
  • The Ingress routes traffic based on the URL path to the notes-app-service, which listens on port 80 and forwards it to port 8000 in the pods.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: notes-app-ingress
  namespace: notes-app
spec:
  rules:
  - host: notes-app
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: notes-app-service
            port:
              number: 80
      - path: /app
        pathType: Prefix
        backend:
          service:
            name: notes-app-service
            port:
              number: 80
  • Apply file
kubectl apply -f ingress.yml
  • Add an domain entry in /etc/hosts file
sudo nano /etc/hosts
  • Now, try to send query on URL
curl notes-app
  • This is an we called it as path based routing using Ingress controller.

Step 6 : Network Policies and CNI

  • Define Network Policies to control traffic and configure CNI for network management.
  • Create networkPolicy.yml file,
  • Network Policies control the communication between pods based on labels. CNI (Container Network Interface) is typically configured at the cluster level.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: notes-app-network-policy
  namespace: notes-app
spec:
  podSelector:
    matchLabels:
      app: notes-app
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: notes-app
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: notes-app
  • Apply file
kubectl apply -f networkPolicy.yml

  1. Step 7 : Job and CronJob
  • Define a Job for one-time tasks and a CronJob for scheduled tasks.
  • Create job.yml file
apiVersion: batch/v1
kind: Job
metadata:
  name: notes-app-job
  namespace: notes-app
spec:
  template:
    spec:
      containers:
      - name: notes-app-job
        image: ojasjawale/notes-app:latest
        ports:
        - containerPort: 8000
      restartPolicy: OnFailure
  • Create cron.yml file
apiVersion: batch/v1
kind: CronJob
metadata:
  name: notes-app-cronjob
  namespace: notes-app
spec:
  schedule: "0 1 * * *"  # Daily at 1 AM
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: notes-app-cronjob
            image: ojasjawale/notes-app:latest
            ports:
            - containerPort: 8000
          restartPolicy: OnFailure

  1. Step 8 : Horizontal Pod Auto-scaling

For HPA setup in minikube, Need to enable addon called metrics-server

minikube addons enable metrics-server
  • Modify deployment for resource limiting
apiVersion: apps/v1
kind: Deployment
metadata:
  name: notes-app-deployment
  namespace: notes-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: notes-app
  template:
    metadata:
      labels:
        app: notes-app
    spec:
      containers:
      - name: notes-app
        image: ojasjawale/notes-app:latest
        ports:
        - containerPort: 8000
        resources:
          requests:
            cpu: "100m"       # Minimum CPU required
          limits:
            cpu: "200m"       # Maximum CPU allowed
  • Implement HPA to scale pods based on CPU utilization.
  • Create hpa.yml file
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: notes-app-hpa
  namespace: notes-app
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: notes-app-deployment
  minReplicas: 1
  maxReplicas: 5
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 15
  • Apply file
kubectl apply -f hpa.yml
  • Currently, there is only one POD is running,
  • Create two screens and in one screen try port-forwarding
kubectl port-forward service/notes-app-service 8000:80 --address=0.0.0.0 -n notes-app
  • Second screen watch for real-time CPU utilization and auto-scaling of POD’s
watch kubectl get hpa -n notes-app
  • POD’s are scaling up automatically,

  1. Step 9 : Role Base Access Control (RBAC)
  • Create service account
kubectl create serviceaccount k8s-user
  • Implement RBAC for fine-grained access control.
  • Create role.yml file
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: notes-app-role
  namespace: notes-app
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]
  • Create roleBinding.yml file
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: notes-app-rolebinding
  namespace: notes-app
subjects:
- kind: User
  name: k8s-user # Replace with your Kubernetes user
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: notes-app-role
  apiGroup: rbac.authorization.k8s.io
  • Role defines permissions, and RoleBinding assigns those permissions to a user or set of users.
  • Testing of RBAC configurations,
  • Run commands using –as=user flag (Where user is the name of the user you wish to impersonate.)
  • As k8s-user has get permissions,
  • As k8s-user don’t have create resource permission, hence action is forbidden.

  1. Step 10 : Testing application on browser
  • Forward port on containerPort from local port and try to access application
kubectl port-forward service/notes-app-service 8000:80 --address=0.0.0.0 -n notes-app

Connect With Me

Thank you for reading. I hope you were able to understand and learn something new from my blog.

Happy Learning!

Categorized in:

Blog,