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)
Worker Nodes
Main Kubernetes Components
Pods:
Note: Communication between pods should be done via services, not direct IP references.
Services:
Types:
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.
Setting Up Minikube on Your Local Machine
Minikube
Minikube is local Kubernetes, focusing on making it easy to learn and develop for Kubernetes.
minikube start
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
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.
· 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.
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.
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.
PostgreSQL Deployment: The Deployment section defines the PostgreSQL pod that runs the database container.
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.
Web Application Deployment:
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:
2. Django Web App:
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:
Django Containerization
Create public repository on AWS ECR and Push image to it.
Create public repository
After you retrieve an authentication token and authenticate your Docker client to your registry, then build and push image to the repo
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.
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:
Once connected, execute the following SQL commands to create the database and grant the necessary privileges:
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:
his will open the Django application in your default web browser. The application is simply listing items stored in the DB.
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:
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:
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