ungleich-staticcms/content/u/blog/2022-06-03-django-hosting-in-kubernetes/contents.lr
2022-06-03 18:25:37 +02:00

100 lines
2.9 KiB
Markdown

title: Hosting Django Apps in Kubernetes [WIP]
---
pub_date: 2022-06-03
---
author: ungleich django team
---
twitter_handle: ungleich
---
_hidden: no
---
_discoverable: yes
---
abstract:
Django running on top of k8s
---
body:
## Situation
At ungleich we are hosting quite a lot of Django applications. As of
2022-06-03, most of them are still deployed on a traditional VM based
setup.
We are using this blog entry to document a possible blueprint and the
progress of migration at ungleich.
## General design
Our Kubernetes clusters usually use
[ArgoCD](https://argo-cd.readthedocs.io/en/stable/) for deployments,
so Django applications should potentially be defined the same way.
Most of our kubernetes applications are defined in helm charts and
thus the "general django application" should probably also be defined
in a helm chart.
## Freedom of choice
While as a hoster it might be tempting to define a specific image that
Django applications should be using (like
[python](https://hub.docker.com/_/python)), but we want to give us and
our customers the freedom to choose the image they use themselves. It
might potentially even come from a private registry.
## Interface definition
All of our Django applications are using Postgresql for storing
data. Postgresql is used by quite some other applications that we
deployed in k8s, so this is a no-brainer - Django hosting at ungleich
even in k8s will be based on Postgresql.
Static data of Django applications can easily be stored on a PVC. This
has the drawback that filesystem PVCs based on ceph block devices are
RWO and thus in case of restart, there will be a short downtime.
This is, generally speaking probably accepted, like a deploy would
have caused a short downtime on a VM as well.
However alternatives would be a shared filesystem (such as
NFS/CephFS), but they are usually slower than dedicated block
devices.
## Django startup
On startup, Django will need to ensure the database schema
has been upgraded to the latest version. so something like `python
manage.py migrate` should probably be called in an InitContainer for
most apps.
## Secrets
Django applications usually have some kind of secrets and most Django
applications have DIFFERENT types of secrets. Thus defining a specific
environment variable does not seem to be a smart idea.
Instead, we should probably offer to store secrets in something like
[SealedSecrets](https://github.com/bitnami-labs/sealed-secrets).
Database connection information is provided by default and is
cluster/app specific.
## Deployment
We are likely going with a git-ops style deployment in which
everything is defined for the Django app. This repository is read
write for each client/customer.
This probably includes:
- Possible encrypted secrets
- Image definition
- Maybe even (part of) a pod definition?
Some parameters are likely to be stored in a different, ungleich only
writable repository, such as:
- Size of RAM
- Number of CPUs
- Storage size (Postgresql, Static files, ...)