In this blog post, I will guide you through the process of creating a Django app and deploying it in a Kubernetes cluster. Additionally, we will explore how to use an Ingress resource to route traffic to multiple paths on the Kubernetes pods.
Firstly, we will create a basic Django app and containerize it. Once we have our container image, we will create a deployment and service for our app. The deployment will manage the replicas of our app running in the cluster, and the service will expose our app to the cluster.
Next, we will create an Ingress resource to route traffic to our app. The Ingress resource will define the routing rules for incoming traffic based on the paths specified in the rules. We will create rules for two paths in our app, '/home' and '/page'.
Finally, we will deploy the Ingress controller in our cluster. The Ingress controller is a crucial component that will manage the Ingress resources in our cluster and route the incoming traffic to our app.
With these steps, we will have a fully functional Django app running in a Kubernetes cluster, and incoming traffic will be routed to our app based on the rules defined in the Ingress resource.
What is Kubernetes?
Kubernetes is an open-source container orchestration platform that automates the deployment, scaling, and management of containerized applications. It provides features such as automatic scaling, rolling updates, self-healing, and service discovery, making it a popular choice for deploying containerized applications in production environments. It can be deployed on-premises, in the cloud, or in a hybrid environment, and integrates with a wide range of other tools and platforms.
What is Ingress?
Ingress is an API object that provides a way to manage external access to services in a cluster. It allows you to route traffic to different services based on rules defined in the Ingress resource. Ingress can be used to configure load balancing, SSL termination, and virtual host routing. In short, Ingress is a powerful tool for managing external access to applications running in a Kubernetes cluster.
An Ingress Controller is a component that is responsible for managing and configuring Ingress resources. It reads the rules defined in the Ingress resources and routes the incoming traffic to the appropriate services in the cluster. There are different types of Ingress controllers available, such as NGINX, Traefik, and Istio. Ingress controllers are an essential component in managing external access to services in a Kubernetes cluster.
Creating Django app
Open a terminal or command prompt and navigate to the directory where you want to create your project.
Run the following command to create a new Django project.
django-admin startproject <project_name>
Here I replace my <project_name>
with djangokubernetesproject
.Navigate to the project directory.Run the following command to create a new app.
python manage.py startapp <app_name>
Here I replace my <app_name>
with app
.Open the urls.py
file in the project directory and add the following lines.
from django.contrib import admin
from django.urls import path , include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('app.urls')),
]
Now create an urls.py
file inside your app
directory. Define the URLs for your app.
from django.contrib import admin
from django.urls import path
from app.views import home , page
urlpatterns = [
path('home/', home , name='home' ),
path('page/', page , name='page' ),
]
Open your views.py
file located in your app
directory and add the following lines.
import os
from django.http import HttpResponse
# Create your views here.
def home(request):
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
if x_forwarded_for:
ip = x_forwarded_for.split(',')[0]
else:
ip = request.META.get('REMOTE_ADDR')
print('ip address of the client = ' , ip)
pod_name = os.environ.get('HOSTNAME')
return HttpResponse(
'<h1>Hello World . ip address of the client = ' + str(ip) + '</h1>'
'<h1>Hello World . pod name = ' + str(pod_name) + '</h1>'
)
def page(request):
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
if x_forwarded_for:
ip = x_forwarded_for.split(',')[0]
else:
ip = request.META.get('REMOTE_ADDR')
print('ip address of the client = ' , ip)
pod_name = os.environ.get('HOSTNAME')
return HttpResponse(
'<h1>Hello World . ip address of the client = ' + str(ip) + '</h1>'
'<h1>Hello World . pod name = ' + str(pod_name) + '</h1>'
)
Now open your settings.py
file and add you app name in the INSTALLED_APPS
.
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app'
]
[Optional] : Open a terminal or command prompt and navigate to the project directory and run the following command to start the development server.
python manage.py runserver 0.0.0.0:8000
This will start the development server, and we can access our app by visiting localhost:8000 in a web browser.
Creating Docker file
Create a dockerfile
in your django project directory. Here I am creating my dockerfile inside djangokubernetesproject
directory.
# Base image
FROM python:3.9-slim-buster
# Set working directory
WORKDIR /app
# Copy and install requirements
COPY requirements.txt .
RUN pip install -r requirements.txt
# Copy project files
COPY . .
# Set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# Expose port
EXPOSE 8000
# Run the command to start the server
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
Build a docker image
Once we have created the Dockerfile to configure our Django app, the next step is to build the Docker image and push it to a container registry. To do this, navigate to the project directory in the terminal and run the following commands
docker build -t <docker_hub_name>/django-ingress .
Here, replace <docker_hub_name>
with your Docker Hub username. For example, if your username is ndrohith09
, the command would be
docker build -t ndrohith09/django-ingress .
This command will build the Docker image with the specified name and tag. Make sure to include the period at the end of the command, as it indicates the build context.
Once the image is built, it's time to push it to the Docker Hub registry. To do this, run the following command:
docker push ndrohith09/django-ingress .
Now that your Docker image is pushed to the Docker Hub registry, you can use it to deploy your Django app on Kubernetes using Ingress.
Create kubernetes deployment file
To deploy our Django app on Kubernetes, we need to create a Kubernetes deployment file called django-ingress.yaml
that defines the specifications for our application. In this case, we want to create a deployment that has two paths - /home
and /page
Now we will create a kubernetes deployment file for the django app which has two paths '/home' and '/page'.
We will use the Docker image that we built and pushed to the Docker Hub container registry in the previous step. Here is an example deployment file that you can use:
apiVersion: apps/v1
kind: Deployment
metadata:
name: home
spec:
replicas: 2
selector:
matchLabels:
app: home
template:
metadata:
labels:
app: home
spec:
containers:
- name: home
image: ndrohith09/django-ingress
ports:
- containerPort: 8000
---
apiVersion: v1
kind: Service
metadata:
name: home-svc
spec:
type: LoadBalancer
ports:
- port: 8000
targetPort: 8000
protocol: TCP
name: http
selector:
app: home
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: page
spec:
replicas: 2
selector:
matchLabels:
app: page
template:
metadata:
labels:
app: page
spec:
containers:
- name: page
image: ndrohith09/django-ingress
ports:
- containerPort: 8000
---
apiVersion: v1
kind: Service
metadata:
name: page-svc
spec:
type: LoadBalancer
ports:
- port: 8000
targetPort: 8000
protocol: TCP
name: http
selector:
app: page
Thus to configure the Django app with two paths /home
and /page
, we created two Kubernetes deployments, named home
and page
, and two services, named home-svc
and page-svc
.
After configuring the deployments and services, the next step is to update the django-ingress.yaml
file to configure the ingress. We need to add specific rules and paths for routing the incoming traffic to the appropriate Kubernetes services.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: django-ing
annotations:
kubernetes.io/ingress.class: nginx
spec:
tls:
- secretName: tls-secret
rules:
- http:
paths:
- path: /home
pathType: Prefix
backend:
service:
name: home-svc
port:
number: 8000
- http:
paths:
- path: /page
pathType: Prefix
backend:
service:
name: page-svc
port:
number: 8000
To create the Kubernetes services for the Django app, navigate to the project directory in the terminal and execute the relevant commands. These commands will create the services based on the deployment configurations and make them accessible to external traffic through the ingress controller.
kubectl create -f django-ingress.yaml
Note : It is important to understand that the ingress controller does not generate a public IP in local systems. As a result, we need to use cloud providers such as Oracle Cloud Infrastructure (OCI), Amazon Web Services (AWS), Google Cloud Platform (GCP), or Microsoft Azure, among others, that provide Kubernetes services to provision our services and generate a public IP. This will enable us to access our Django app from anywhere on the internet.
Deployment in Cloud platforms
Here, we will be deploying our Django app on a cloud platform, specifically on the Oracle Kubernetes Cluster (OKE)
. First, you need to create an Oracle Cloud account and navigate to the Kubernetes Clusters (OKE) page to create your own Kubernetes cluster. You can refer to the official documentation for creating a Kubernetes cluster in Oracle Cloud.
Docs: Creating a Kubernetes Cluster
After creating the Kubernetes cluster, you can access it using either the cloud shell access
or local access
.
Docs: Setting Up Cluster Access
Once you have access to your Kubernetes cluster, the next step is to set up the Ingress controller on the cluster. Ingress controllers are not a part of the Kubernetes core components, and there are different Ingress controllers available to choose from.
For Oracle Kubernetes Engine (OKE), the recommended Ingress controller is the Oracle Cloud Infrastructure (OCI) Load Balancing Ingress Controller. This controller is specifically designed for OKE and integrates with the Oracle Cloud Infrastructure Load Balancing service to provide a fully-managed, scalable and secure ingress solution for your cluster.
You can follow the official documentation to set up the OCI Load Balancing Ingress Controller on your OKE cluster.
Docs: Setting Up an Ingress Controller on a Cluster
Once the Ingress controller is installed and configured, you can proceed with creating and applying your Ingress resource YAML file (django-ingress.yaml)
to configure routing to your Django app's services.
Note that the process for setting up an Ingress controller may differ depending on the cloud provider or infrastructure you are using. Make sure to refer to the relevant documentation for your platform to ensure proper setup and configuration of your Ingress controller.
To apply the services in the cluster, navigate to the project directory and use the following command to apply the django-ingress.yaml
file
kubectl apply -f django-ingress.yaml
This will create the necessary resources in the cluster, including the ingress controller and the defined routes for our Django app. To get more details about the resources in your Kubernetes cluster, you can use the following command:
kubectl get all
This command will list all the resources in your cluster, including deployments, pods, services, and ingress. You can use this command to verify that your Django app is up and running, and that your ingress rules have been properly configured.
Once the resources are created, we can check the status of the ingress controller by running the following command
kubectl get ingress
This will display the details of the ingress resources created in the cluster, including the host, path, and backend service details. If the external IP address is not automatically generated by the cloud provider, we can check the status of the ingress resources by running the following command:
kubectl describe ingress
This will provide more detailed information about the ingress controller, including the IP address and any errors or warnings encountered during configuration.
With our ingress controller and services configured, we can now access our Django app using the external IP address provided by the ingress controller. You can retrieve the external IP address by running the command kubectl get ingress
in your terminal. Once you have the external IP address, you can access your Django app by navigating to the defined paths in the browser, such as http://<external_ip_address>/home
and http://<external_ip_address>/page
.
To access the Django app, we can navigate to the defined paths '/home' and '/page' in the browser using the external IP provided by the ingress controller 144.24.133.172
. This will route the requests to the respective Kubernetes pods and display the output on the browser.
To access the /home
path of the Django app, you can use the following URL: http://144.24.133.172/home
. This should display the HTML response that corresponds to the /home
path that we defined earlier in our ingress configuration.
Similarly To access the /page
path of the Django app, you can use the following URL: http://144.24.133.172/page
. This should display the HTML response that corresponds to the /page
path that we defined earlier in our ingress configuration.
Hope you have gained a good understanding of how to create a Django app and use Ingress to route traffic to multiple paths on Kubernetes pods.
Thank You!