Launch web app in local kubernetes using helm with monitoring. The awesome local playground tutorial for those who study DevOps!
- write a basic Django application
- pack up the application into a docker image
- prepare a helm package (chart)
To complete the tutorial, you will need:
- knowledge of the Helm and k8s basics
- pre-installed docker-for-desktop with Kubernetes, Docker Enterprise, Helm.
Let's make a simple Django web application without getting into too much detail.
- Create a project folder:
$ mkdir django-tutorial
- Create a standard
requirements.txtfile with dependencies:
$ cat <<EOF >>requirements.txt django==2.1.2 EOF
- Initialize the virtual environment and install Django in it:
python3 -m venv venv source venv/bin/activate pip install -r requirements.txt
- Now, we can generate a simple
helloworldproject using the
django-admin startproject helloworld
- This way, you're able to create a project with the following structure:
tree helloworld helloworld ├── helloworld │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py └── manage.py
- Create a
views.pyfile in the
cat <<EOF >>helloworld/helloworld/views.py from django.views.generic import View from django.http import HttpResponse class HelloWordView(View): def get(self, request): return HttpResponse( "Helloword!" ) EOF
cat <<EOF >>helloworld/helloworld/urls.py from django.contrib import admin from django.urls import path from .views import HelloWordView urlpatterns = [ path('admin/', admin.site.urls), path('', HelloWordView.as_view()) ] EOF
- Since the application is to be installed in the local cluster, change the
settings.py(NOTE: it is unacceptable to do this in production):
ALLOWED_HOSTS = ['*']
- Now we have a simple application that we can run locally via
python manage.py runserverand open in a browser via
To install the application in k8s, you first need to create a Docker image. Select a simple base image and install Python dependencies into it. Copy the code to the image and launch the application server. The
python manage.py runserver is not suitable for production, so use any WSGI-friendly server instead, e.g. Gunicorn or Uwsgi.
- Go to the project root folder and create a Docker file that looks the following way:
cat <<EOF >>Dockerfile FROM python:3.7-alpine RUN apk add python3-dev build-base linux-headers pcre-dev mariadb-connector-c-dev RUN pip install uwsgi WORKDIR /etc/app COPY ./requirements.txt ./ RUN pip install -r requirements.txt COPY ./ ./ CMD ["uwsgi", "--chdir=/etc/app", "--module=helloworld.wsgi:application", "--master", "--pidfile=/tmp/project-master.pid", "--http=0.0.0.0:8080", "--processes=5", "--uid=1000", "--gid=2000", "--harakiri=20", "--max-requests=5000", "--vacuum"] EOF
- Make sure that you're using the same docker daemon as k8s does, and run an image**:**
docker build -t django-tutorial .
Helm is one of the most popular package managers for k8s.
It is recommended that we use Helm in this tutorial, as it enables us to quickly launch Grafana charts and Prometheus for the monitoring purpose; the parameters are described in the comments quite neatly, and the chart structure gives a good insight into which specific Kubernetes resources will be installed. We won't get too deep into Helm here, as there's a large number of articles that can tell about its basics, pros and cons.
So, back to creating a chart for our
- Create a base for the Helm chart.
helm create django-tutorial
- You should get the following structure:
django-tutorial ├── Chart.yaml ├── charts ├── templates │ ├── NOTES.txt │ ├── _helpers.tpl │ ├── deployment.yaml │ ├── ingress.yaml │ └── service.yaml └── values.yaml
Chart.yamlcontains the package metadata
values.yamlcontains chart configuration parameters
templatesfolder contains templates for the Kubernetes resources
- You may also find a file named
requirements.yamlwhich contains dependencies
chartsfolder contains packages with dependencies. You can use either of the two options: 1) keeping the list of dependencies in requirements.yaml and updating them with the
helm packagecommand; or, simply storing child charts in this folder.
- Change the
values.yamlfile, refer/link to the previously created image containing our application. Make sure that in Kubernetes you're using the same docker daemon; otherwise you'll have no access to this image.
image: repository: django-tutorial # Docker image name tag: latest pullPolicy: Never # Use local image
- In this tutorial, we aren't going to use Ingress or LoadBalancer to access the services outside our cluster; we'll just use NodePort. NodePort is a special type of service which opens a host port within the range/interval of 30000–32767 and re-directs all the traffic from it to the defined/selected/specified service.
service: type: NodePort port: 8080
containerPortfrom 80 to 8080.
ports: - name: http containerPort: 8080 protocol: TCP
- Install a chart with release name
django-tutorial; if you don't specify the name, Kubernetes will pick a random one.
helm install . --name django-tutorial
- The list of releases can be viewed through a command. We now have our release set up successfully with status "Deployed":
helm ls NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE django-tutorial 1 Thu Jan 10 21:51:14 2019 DEPLOYED django-tutorial-0.1.0 1.0 default
- Check the pod status:
kubectl get pods NAME READY STATUS RESTARTS AGE django-tutorial-9b485585-t2hxd 1/1 Running 0 3d
- Now, view the list of services installed. Our application should be available at
kubectl get services NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE django-tutorial NodePort 10.104.171.0 <none> 8080:32319/TCP 2s
In the Part 2:
- set up the export of Django's standard metrics
- add one custom metric
- set up the monitoring of the application's separate segments and the monitoring of the whole cluster, with Prometheus
- visualize these data with Grafana
- set up alerts with Amixr