This template is dedicated to up and running django with kubernetes.
this is a simple diagram to show you how the services are integrating with each other.
in order to work with your django application with k8s you need to prepare your environment for development, such as installing docker and minikube for start. so follow along the instructions and make everything.
You'll need to have Docker installed. It's available on Windows, macOS and most distros of Linux.
System requirements To install Docker Desktop successfully, your Linux host must meet the following general requirements:
- 64-bit kernel and CPU support for virtualization.
- KVM virtualization support. Follow the KVM virtualization support instructions to check if the KVM kernel modules are enabled and how to provide access to the kvm device.
- QEMU must be version 5.2 or newer. We recommend upgrading to the latest version.
- systemd init system.
- Gnome, KDE, or MATE Desktop environment.
- For many Linux distros, the Gnome environment does not support tray icons. To add support for tray icons, you need to install a Gnome extension. For example, AppIndicator.
- At least 4 GB of RAM.
- Enable configuring ID mapping in user namespaces, see File sharing.
Docker Desktop for Linux runs a Virtual Machine (VM). For more information on why, see Why Docker Desktop for Linux runs a VM.
If you're using Windows, it will be expected that you have to install wsl too. WSL or WSL 2.
That's because we're going to be running shell commands. You can always modify these commands for PowerShell if you want.
in order to run the kubernetes cluster you need to install one of the following providers for dev environment
docker desktop already has support for windows,linux and mac so its already there all you have to do is to go to docker desktop settings and enable kubernetes, and wait till installation is completed. after that you will see another icon appears beside docker and shows the status of the kubernetes too.
Minikube is Kubernetes tool. It allows you to run Kubernetes locally on your computer. It runs as a single-node Kubernetes cluster within your local computer, making it easy to develop the Kubernetes app. you can follow the instructions provided here to install it based on your os.
https://minikube.sigs.k8s.io/docs/start/
What you’ll need
- 2 CPUs or more
- 2GB of free memory
- 20GB of free disk space
- Internet connection
- Container or virtual machine manager, such as: Docker, QEMU, Hyperkit, Hyper-V, KVM, Parallels, Podman, VirtualBox, or VMware Fusion/Workstation
after installation you have to run the minikube and set it up for usage, so in order to do that just run the following command:
minikube start
when its done you will see the details of the steps and informations.
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. For more information including a complete list of kubectl operations, see the kubectl reference documentation provided here:
https://kubernetes.io/docs/reference/kubectl/
for installing kubectl, you can head to the link down below and choose the right os and start the installation steps:
https://kubernetes.io/docs/tasks/tools/
Note: for windows users after downloading the file you have to put it in a folder inside C directory and then just add the path to environment variables of the system. then you can access and test it with the following command: shell kubectl version --client
Once you have the PATH ready, run the following command to check if your set Kubectl is ready to execute Kubernetes commands:
kubectl cluster-info
and you should see something similar to this:
if you have already setup more than one cluster you can switch between them by docker icon in system tray and changed the kubernetes cluster from one to another.
kubernetes cheat sheets.
for deployment purposes you need to build the docker image, so it can be used inside the k8s deployment as a refrence. there are two options here:
- build locally and push to docker hub
- build locally and use it
the correct way is to build and push to docker hub but as we may be some restrictions just build and use it. remember that we are using a special naming so follow the commands below to create the images. after that you can either decide to push it to hub or not.
for building django app:
docker build -t django_app -f ./dockerfiles/prod/django/Dockerfile .
and for nginx app:
docker build -t nginx_app -f ./dockerfiles/prod/nginx/Dockerfile .
if you want to push it to the hub firstly, login to docker with the following command:
docker login -u username -p password
after that just push your apps with the following command:
docker push [USERNAME]/[IMAGE-NAME]:[TAG]
in order to deploy the sample project i have provided 3 services inside the k8s
directory:
- postgres
- redis
- django
- nginx
- celery-worker
- celery-beater
- flower
in order to deploy the application using the local cluster you need to apply or create them by kubectl, which will communicate with the cluster and create the needed pods,services,deployments and etc. so just follow the instructions:
for setting up postgres first of all you need to setup the config-map first so:
kubectl apply -f ./k8s/postgres/config-map.yml
after that you need to deploy the pod by the deployment:
kubectl apply -f ./k8s/postgres/deployment.yml
and lastly i norder for your services to access the database you need to assign a service to it by:
kubectl apply -f ./k8s/postgres/service.yml
at the end you will end up having the postgres up and running. if you list all the details you can see that the database is running at this point.
first you need to deploy the pod by the deployment:
kubectl apply -f ./k8s/redis/deployment.yml
and lastly i norder for your services to access the database you need to assign a service to it by:
kubectl apply -f ./k8s/redis/service.yml
our main service is our django application which will be communicating with the database. os first of all lets setup config-map
kubectl apply -f ./k8s/django/config-map.yml
after that you need to deploy the pod by the deployment:
kubectl apply -f ./k8s/django/deployment.yml
and lastly to make the service accessible by nginx we need to have a service to be able to connect to:
kubectl apply -f ./k8s/django/service.yml
at the end you will end up having the django app up and running. if you list all the details you can see that the django app and database is running at this point. you can change the default configs and update each one.
migrate database configs.
kubectl exec POD_NAME -- python manage.py migrate
Note: you need to have migrations included in your project and just do the migrate.
first you need to deploy the pod by the deployment, nginx will be running with 2 replicas:
kubectl apply -f ./k8s/nginx/deployment.yml
and also apply the service so we can access the django app though nginx,which will be in load balance mode:
kubectl apply -f ./k8s/nginx/service.yml
at the end you will end up having the all the needed services to run the whole application.
C:\Users\AliBigdeli\Documents\GitHub\Django-Kubernetes-Template>kubectl get all
NAME READY STATUS RESTARTS AGE
pod/django-5b74bd444-mskdm 1/1 Running 0 2m43s
pod/my-nginx-c7bb68546-64q56 1/1 Running 0 25s
pod/my-nginx-c7bb68546-qrkl2 1/1 Running 0 25s
pod/postgres-6bdb7d69c-2wn9v 1/1 Running 0 7m3s
pod/redis-67b95b7577-2jwv8 1/1 Running 0 4m1s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/django ClusterIP 10.110.233.36 <none> 8000/TCP 2m21s
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 4d21h
service/nginx-loadbalancer LoadBalancer 10.109.224.172 localhost 80:30362/TCP 20s
service/postgres ClusterIP 10.97.134.246 <none> 5432/TCP 6m58s
service/redis ClusterIP 10.98.178.118 <none> 6379/TCP 3m46s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/django 1/1 1 1 2m43s
deployment.apps/my-nginx 2/2 2 2 25s
deployment.apps/postgres 1/1 1 1 7m3s
deployment.apps/redis 1/1 1 1 4m1s
NAME DESIRED CURRENT READY AGE
replicaset.apps/django-5b74bd444 1 1 1 2m43s
replicaset.apps/my-nginx-c7bb68546 2 2 2 25s
replicaset.apps/postgres-6bdb7d69c 1 1 1 7m3s
replicaset.apps/redis-67b95b7577 1 1 1 4m1s
at the end you need to be able to see the website by opening your localhost on port 80
in order to control celery worker we need to deploy the worker also based on the django config, so with the following command you can deploy the worker.
kubectl apply -f ./k8s/celery-worker/deployment.yml
Note: there is no need for other configurations except changing the resources based on your need.
for your schedule tasks you need to have a beater running to follow the time and do tasks based on schedules, in order to run it you can use the following command:
kubectl apply -f ./k8s/celery-beater/deployment.yml
Note: there is no need for other configurations except changing the resources based on your need.
and at the end you need should have all the pods running like the list below:
C:\Users\AliBigdeli\Documents\GitHub\Django-Kubernetes-Template>kubectl get all
NAME READY STATUS RESTARTS AGE
pod/celery-beater-c85b98476-7mr8r 1/1 Running 0 74m
pod/celery-worker-76455b99fb-knhtn 1/1 Running 0 81m
pod/django-5b74bd444-r6nhl 1/1 Running 0 82m
pod/my-nginx-c7bb68546-m7c8t 1/1 Running 0 81m
pod/my-nginx-c7bb68546-vtcdl 1/1 Running 0 81m
pod/postgres-6bdb7d69c-2wn9v 1/1 Running 0 107m
pod/redis-67b95b7577-2jwv8 1/1 Running 0 104m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/django ClusterIP 10.110.233.36 <none> 8000/TCP 103m
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 4d22h
service/nginx-loadbalancer LoadBalancer 10.109.224.172 localhost 80:30362/TCP 101m
service/postgres ClusterIP 10.97.134.246 <none> 5432/TCP 107m
service/redis ClusterIP 10.98.178.118 <none> 6379/TCP 104m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/celery-beater 1/1 1 1 80m
deployment.apps/celery-worker 1/1 1 1 81m
deployment.apps/django 1/1 1 1 82m
deployment.apps/my-nginx 2/2 2 2 81m
deployment.apps/postgres 1/1 1 1 107m
deployment.apps/redis 1/1 1 1 104m
NAME DESIRED CURRENT READY AGE
replicaset.apps/celery-beater-c85b98476 1 1 1 74m
replicaset.apps/celery-worker-76455b99fb 1 1 1 81m
replicaset.apps/django-5b74bd444 1 1 1 82m
replicaset.apps/my-nginx-c7bb68546 2 2 2 81m
replicaset.apps/postgres-6bdb7d69c 1 1 1 107m
replicaset.apps/redis-67b95b7577 1 1 1 104m
MIT.
Feel free to let me know if something needs to be fixed. or even any features seems to be needed in this repo.