CloudTalents Application on K8s
In the previous post, we used docker-compose to build and manage our multi-container application. Today, I talk about orchestrating those containers using Kubernetes.
fter building the docker image in the previous article, it’s time to orchestrate containers using K8s.
Follow along by cloning the below repo.
Source code repo
Docker Hub
The docker image is tagged and pushed to the docker hub.
Figure1: Docker Hub
Config Maps and Secrets
When we ran the Django(app
) container locally, we passed the env file into the docker run to inject configuration variables into the runtime environment. On Kubernetes, configuration variables can be injected using ConfigMaps and Secrets.
ConfigMaps should be used to store non-confidential configuration information, such as app settings, and Secrets should be used for sensitive information, such as API keys and database credentials.
|
|
Creating Postgres Secret
We’ll use the env file from the docker section, removing variables inserted into the ConfigMap.
Create a file db-secrets
and load the values as follows.
|
|
|
|
Rolling out the Postgres DB using a StatefulSet
The first step is to deploy Postgres as a stateful set with a headless service. A stateful set is a Kubernetes resource that manages deploying and scaling a set of Pods with persistent identities and storage. A headless service is a Kubernetes service that does not have a cluster IP address. Instead, it provides DNS records for the pods in the stateful set.
Figure2: local-path provisioner
The following YAML file defines a headless service named db that exposes port 5432
and selects Pods with the label app: postgres. It also defines a stateful set named “postgres” that uses the headless service, has one replica, and creates Pods with the label app: postgres. Each Pod has a container named Postgres that runs the image postgres:16
|
|
Then, you can apply the YAML file by running
|
|
The command above will create the headless service and the stateful set in your cluster. You can verify them by running the following commands:
|
|
Output - DB
Figure3: statefulset-postgress
The local-path provisioner mounts a directory /opt/local-path-provisioner on the node to which the db pod gets assigned.
Figure4: directory mount
Creating App Secret
Create a file django-secrets
and load the values as follows.
|
|
|
|
Rolling out the Django app using a Deployment
In this step, we will create a Deployment for your Django app. A Kubernetes Deployment is a controller that can manage stateless applications in your cluster. A controller is a control loop that regulates workloads by scaling them up or down. Controllers also restart and clear out failed containers.
Here, we define a Kubernetes Deployment called app and label it with the key-value pair name: app. We specify that we’d like to run only one replica of the Pod defined below the template field.
|
|
Using envFrom
with secretRef
and configMapRef
, we specify that all the data from the app-secret Secret and app-config ConfigMap should be injected into the containers as environment variables. The ConfigMap and Secret keys become the environment variable names.
Finally, we expose containerPort 8000 and name it gunicorn.
Create the Deployment using k apply -f app-deploy.yaml
Verify the resources using the following commands.
|
|
Output - APP
Figure5: deployment-app
Now execute the Django migration
using the command below
|
|
Migrations are Django’s way of propagating changes you make to your models (adding a field, deleting a model, etc.) into your database schema. Successful execution of the command returns the below output.
Figure6: deployment-app
Rolling out the NGINX using a Deployment
In this step, we will create a Deployment for your nginx. It first creates a ConfigMap and uses a custom nginx.conf file. It is mounted as a volume inside /etc/nginx/conf.d
directory of Pod.
A nodePort
service exposes the Pod to the outside world.
|
|
Create the deployment using the following command
|
|
Verify the resources using the following command
|
|
Output - NGINX
Figure7: deployment-nginx
Access the application through a browser and upload an image.
You can use either the k8s master or worker IP address and port 31680
to access the app.
Figure8: application
I have deployed the NGINX ingress controller by following the steps from the official documentation.
Create an ingress resource using the YAML file below
|
|
An Ingress resource will be created and will look like the one below
Figure9: Ingress resource
One final modification is needed: change the node port for the nginx-ingress service to 31780
Figure10: ingress nodeport-svc
Rollout
Now access the app using the FQDN http://cloudtalentstartup.com:31780
Figure11: website-final-version
Now the application can be scaled up seamlessly to meet the high volume of traffic