Skip to main content

Command Palette

Search for a command to run...

Kubernetes end-to-end project with deployment of Django notes application

Updated
6 min read
Kubernetes end-to-end project with deployment of Django notes application
O

Hi there! I'm Ojas Jawale, a passionate Cloud, DevOps and Cyber Security enthusiast. I love to dive into the latest new technologies and sharing my journey through blog. I'm always eager to learn and grow in this ever-evolving field of DevOps and Cyber Security. You'll find me writing about CI/CD pipelines, automation, containerization with Docker, and other exciting tech topics related to software quality and deployment. My goal is to demystify complex DevOps and Cyber Security concepts, provide practical tips on automation and testing, and inspire others in the developer and operations community. Let's connect, learn, and build amazing, high-quality software together!

  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.

  1. 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!

LinkedIn | GitHub

More from this blog

Untitled Publication

52 posts