Learning Kubernetes through Example (1/3): Deploying Django Web App with PostgreSQL on K8s Cluster

Learning Kubernetes through Example (1/3): Deploying Django Web App with PostgreSQL on K8s Cluster

Introduction

Hello everyone, this is a quick tutorial on Kubernetes through code examples. If you want to learn Kubernetes and get your hands dirty while gradually advancing in concepts, this is the place to start! This is going to be a three-episode series explaining Kubernetes via code examples. In the first episode, we will understand Kubernetes concepts through an example by deploying a web app with a PostgreSQL database using K8s on Minikube (Code Included). In the next episode, we'll automate the deployment process using Terraform.

Let us dive in!

Understanding Kubernetes Basics

Kubernetes is a container orchestration platform that manages and automates containerized applications. It has a master node (Control Plane) and worker nodes.

Master Node (Control Plane)

  • Kube API Server: The entry point for all interactions (UI, CLI, API).
  • Controller Manager: Keeps track of the cluster’s health (e.g., restarts failing containers).
  • Scheduler: Decides which node should run a new pod based on workload.
  • Etcd: Highly available key-value store, used to store the cluster's data
  • Virtual Network: Ensures communication between all components.


Article content
Kubernetes cluster components

Worker Nodes

  • A node may be a virtual or physical machine, depending on the cluster. Each node is managed by the control plane and contains the services necessary to run Pods.
  • Run Kubelet, which communicates with the master.
  • Host the Pods “containers” where applications are deployed.

 

Main Kubernetes Components

Pods:

  • Ephemeral units that run application containers.
  • Each pod has a unique IP, but it's not persistent across restarts.

Note: Communication between pods should be done via services, not direct IP references.


Article content

Services:

  • Service is a method for exposing the network application that is running as one or more Pods in a cluster.

Types:

  • ClusterIP: Exposes the Service internally within the cluster; the default type for Services.
  • NodePort: Exposes the Service on a static port across all Nodes in the cluster, making it accessible externally.
  • LoadBalancer: Exposes the Service externally through a load balancer, requiring an external load balancing solution.
  • ExternalName: Maps the Service to an external DNS name without proxying, enabling external hostname resolution.

ConfigMap:

Stores non-sensitive configuration (e.g., database URLs) in a key-value pairs.

Kubernetes Secrets:

Used to store sensitive data like passwords, which pods can access securely.

Volumes:

Attach persistent storage to pods (local or remote).

Deployment:

Blueprint for app pods, specifying the number of replicas.

StatefulSets:

Used for databases and stateful applications. Ensures persistent data and scaling.

 

Kubernetes Configuration

Kubernetes configurations are declarative and sent to the API Server in YAML or JSON format. This includes components like Deployments and Services.

  • Configuration File Structure:apiVersion: Specifies the version.kind: Defines the type (e.g., Deployment, Service).metadata: Contains name, labels, etc.spec: Defines the desired state.
  • Kubernetes continually checks the current state and adjusts to match the desired state (similar to Terraform's "desired state" concept).

Article content

Setting Up Minikube on Your Local Machine

 

Minikube

Minikube is local Kubernetes, focusing on making it easy to learn and develop for Kubernetes.

  • PrerequisitesInstall Minikube and kubectl on your Machine.Follow instructions in the link below to install and configure Minikube on your machine with the selected driver (I selected docker)https://minikube.sigs.k8s.io/docs/start/
  • Starting MinikubeCommands to initialize Minikube:

minikube start        

  • Accessing the Minikube DashboardBrief guide on accessing the Kubernetes dashboard via:

minikube dashboard        

Interact with Your Cluster

Kubectl

The Kubernetes command-line tool, kubectl, allows you to run commands against Kubernetes clusters. You can use kubectl to deploy applications, inspect and manage cluster resources, and view logs.

Note:

Kubectl is installed as a dependency when installing minikube

 

Example commands

-       Get cluster information

   kubectl cluster-info        

-       List all pods

   kubectl get pods        

-       Apply configuration from a YAML file

  kubectl apply -f deployment.yaml        

-       Get logs for a specific Pod

  kubectl logs <pod-name>        

-       Force Pod restart

   kubectl delete <pod-name>        

 

Project: Django Application Components in K8s

 

Project Overview

Article content

This project focuses on deploying a Django web application and PostgreSQL database on Kubernetes (K8s). The app and database will communicate securely using Kubernetes Secrets and ConfigMaps. To ensure data persistence, we will use a Persistent Volume for the PostgreSQL database, which protects against data loss in case the database pod dies or restarts.

Environment variables and sensitive data (such as database credentials) will be stored in Secrets. These will be injected into the K8s deployments via environment variables in the configuration files. Note that Secrets will be base64 encoded to ensure secure handling.

For the Django application, we will build a container image, push it to a public AWS Elastic Container Registry (ECR) repository, and reference this image in the web app deployment configuration.

We will also make the application accessible from the browser, allowing users to interact with the deployed system.

 

Kubernetes Configuration Files

 

Let's break down each of the Kubernetes configuration files and explain how they are linked together, starting with one file at a time. This will help make the connections between the configurations clear.

 

postgres-secret.yaml

This file defines the secrets for the PostgreSQL database. Kubernetes Secrets allow you to securely store sensitive data, such as passwords.

Article content

 

·       POSTGRES_USERNAME and POSTGRES_PASSWORD are stored as base64 encoded values. This ensures that sensitive data like the database username and password are not stored in plain text.

·       These secrets will be accessed by both the PostgreSQL and Django applications, ensuring they can securely connect to each other.

 

postgres-config-map.yaml

This file defines the configuration for the PostgreSQL service.

Article content

postgres-url: This configuration entry contains the URL or service name for the PostgreSQL database. It will be referenced by the Django application (via an environment variable) to know how to connect to the PostgreSQL database.

 

postgres-pvc.yaml

This file defines the Persistent Volume Claim (PVC) for the PostgreSQL database, ensuring that data is stored persistently even if the pod is restarted or dies.

Article content

 

postgres-pvc: This claim ensures that the PostgreSQL database data will persist. It requests 1Gi of storage (which you can adjust). This PVC is later referenced in the PostgreSQL deployment to mount the storage.

 

postgres.yaml

This file defines the Deployment and Service for the PostgreSQL database.

Article content
Article content

 

PostgreSQL Deployment: The Deployment section defines the PostgreSQL pod that runs the database container.

  • It references the postgres-secrets-file for the database password, ensuring the pod has secure access to the database credentials.
  • The postgres-storage volume uses the postgres-pvc to store data persistently on disk.

PostgreSQL Service: This service exposes the PostgreSQL pod to other components within the Kubernetes cluster, so the Django web app can access it via the postgres-service DNS name.

 

webapp.yaml

This file defines the Deployment and Service for the Django web application.

Article content
Article content

 

Web Application Deployment:

  • The webapp-deployment specifies the Django container.
  • It references the postgres-secrets-file for the PostgreSQL username and password to securely connect to the database.
  • It also references the postgres-config-map for the DB_URL, which points to the postgres-service (defined earlier).
  • The Django application will use these environment variables to connect to the PostgreSQL database.

Web Application Service: The webapp-service exposes the Django application on port 8000 within the Kubernetes cluster and allows external access via NodePort on port 30100.

 

How They Work Together

1.    PostgreSQL Database:

  • The PostgreSQL database is deployed using a Deployment and is exposed via a Service (postgres-service), allowing other components like the Django web app to communicate with it.
  • The database credentials are securely stored in the Secret (postgres-secrets-file) and accessed by the PostgreSQL container.
  • The database uses Persistent Volumes to store data persistently, ensuring that data is not lost if the pod dies or restarts.

2.    Django Web App:

  • The Django application is deployed using a Deployment and connects to the PostgreSQL database using environment variables.
  • The Secret provides the PostgreSQL username and password, while the ConfigMap provides the URL of the PostgreSQL service (postgres-service).
  • The web app is accessible externally through the webapp-service, which exposes it on port 30100.

 

Django Application Code Customization

Update settings.py to configure PostgreSQL

Modify your DATABASES setting in settings.py to connect to your PostgreSQL instance in Kubernetes:

Article content

 

Django Containerization

 

Article content

 

Create public repository on AWS ECR and Push image to it.

Create public repository

Article content

 

After you retrieve an authentication token and authenticate your Docker client to your registry, then build and push image to the repo

Article content

Deploying the Application on Minikube

To deploy the application on Minikube, you first need to deploy the PostgreSQL files. Begin by applying the PostgreSQL-related YAML files (postgres-secret.yaml, postgres-config-map.yaml, postgres-pvc.yaml, and postgres.yaml) using kubectl apply -f <file-name>. This will set up the PostgreSQL database, including the deployment and service.

Article content

Next, you'll need to connect to the running PostgreSQL pod and create the necessary database. Run the following command to access the PostgreSQL pod:

Article content

Once connected, execute the following SQL commands to create the database and grant the necessary privileges:

Article content

 

After setting up the PostgreSQL database, deploy the web application by applying the webapp.yaml file using the kubectl apply -f webapp.yaml command.

Finally, you can make the web application accessible in your browser by running:

Article content

his will open the Django application in your default web browser. The application is simply listing items stored in the DB.

 

Article content
WebApp Working in the Browswer

 

If you encounter any issues during deployment, you can check the logs of the web app or PostgreSQL pods for more details. Use the following command to view the logs of a specific pod:

 

Conclusion

In today's episode, we learned how to deploy a Django web application with a PostgreSQL database on Minikube, covering the creation of Kubernetes resources like deployments, services, secrets, and config maps. We also discussed how to set up persistent storage to avoid data loss.

Caveats on Minikube:

  • Data is local to your machine: The data won’t persist if you delete the Minikube cluster entirely.
  • Not production-ready: For production workloads, use cloud storage solutions like AWS EBS, or a fully managed database outside the cluster, like Aurora. While Minikube is a great learning tool, Aurora is a better choice for production environments.

This example serves educational purposes, helping us understand the basic concepts of Kubernetes in a controlled, local environment.

What's Next?

In the next episode, we will automate the deployment process using Terraform, simplifying the management and scaling of our Kubernetes resources. Stay tuned!

 

For the complete code and configuration files, you can access the GitHub repository here: 

https://github.com/Tiger4Code/K8s-Tutorial-Django-Postgres-Webapp

 

Author: Noor Sabahi

Principal AI Engineer

 

 

#Kubernetes #Django #PostgreSQL #KubernetesTutorial #DevOps #CloudComputing #Minikube #Docker #Containers #CloudInfrastructure #KubernetesDeployment #WebApplicationDeployment #PersistentStorage #KubernetesServices #KubernetesSecrets #ConfigurationManagement #InfrastructureAsCode #CloudDatabases #DevOpsAutomation #KubernetesForBeginners #KubernetesNetworking

 

 

To view or add a comment, sign in

Others also viewed

Explore topics