Deploying Microservice App on K8s

Deploying Microservice App on K8s

Part 3: Exploring Microservice Application Directory and Some K8s Concepts

ยท

7 min read

This blog is Part 3 of the blog series it is recommended that you read the previous blogs before this one. Here is the Part 1 of the series.

Clone the project repository-

In this blog, I will discuss the directories in microservice applications and you can find the directories discussed in this blog in /Tasklist App directory in the project repository.


There are two directories in the "Tasklist App" Directory in the project. Auth is for authentication microservice and backend is for backend microservice.

One does not need to understand the complete end-to-end source code of microservices for deployment and DevOps perspective. Just the understanding of how the authentication service works is sufficient for the project, which I have explained in the first blog of the series so refer to that if you have not read it. You do not need to edit anything in these files as I am only discussing these files.

What I have not explained in the first blog is files and configurations in the microservices directory so I will be discussing them in this blog.

auth Directory

In the auth directory we have "app.py" which contains the main logic of the authentication microservice.

App.py imports configuration or environmental variables from two files that are stored in two different directories in the auth directory. The first one is the "config" directory with a "config.env" file that stores non-confidential configurations. The other directory is the "secret" directory with a "secret.env" file in it that stores confidential information.

๐Ÿค”
Wonder why confidential and non-confidential files are stored in different directories and different files? I have explained this in the later part of this blog.

config.env

As we discussed earlier this file stores non-confidential configurations, but what are the non-confidential configurations that it stores is discussed below-

  1. It stores the database endpoint in the "DB_HOST" variable and its value "localhost" which means the endpoint is running locally in the machine on which this app is running. We will change this value when we deploy the application on AWS EKS Cluster, this is set to localhost because I ran this app locally for testing and the database was running on my machine locally.

  2. It stores the bind address which is the IP address on which the machine on which this app is running is listening to. This address is stored in the "APP_HOST" variable and its value is "0.0.0.0" which means that the application will listen for incoming connections on all available network interfaces, making it accessible over the network.

secret.env

We know that this file stores secret configurations let's discuss what these configurations are-

DATABASE: It stores the database that we are using which is MySQL, this config tells the app which database it is connecting to.

DB_USERNAME: The app imports the username of the database from this config.

DB_PASSWORD: The app imports the password of the database from this config.

JWT_SECRET_KEY: The app imports the JWT (JSON Web Token) key from this config. This JWT key is the key from which the authentication microservice verifies the JWT token provided by the user side to the backend microservice and the backend forwards this JWT token to authentication for verification.

SECRET_KEY: This "SECRET_KEY" is the session key that is used for managing server-side state and storing user-specific information. The app imports this config from here.

requirements.txt

The authentication microservice has Python module requirements and these requirements are mentioned in the requirements.txt file.

Dockerfile

To create the image of this application we need a Dockerfile. In the Dockerfile I am using "python:3.12.1-slim-bullseye" as the base image. In this image, I have set the "app" directory as the working directory.

Next, I have copied all the contents of the "auth" directory to the "/app" directory of the image. The authentication microservice has some Python module requirements and these requirements are being installed in the image using the "RUN" command with pip install -r requirements.txt command.

At last in the Dockerfile, I have run a CMD command that will run the authentication microservice whenever the container gets created from this Image.

.dockerignore

This is the file that contains the name of the other file in the "auth" directory. Docker will not copy the file to the Docker Image of the authentication microservice that is mentioned in this file.

This file contains the Dockerfile name as this is the file that is not required in the Image of the microservice.


backend Directory

The backend directory follows a similar structure as auth directory, it has a config directory and a secret directory to store confidential and non-confidential information in the config.env and secret.env file. It also has requirements.txt, Dockerfile and .dockerignore files as the auth directory. Apart from these files, it has some other files too. Let's discuss all the files in this directory-

config

This repository contains config.env file to store non-confidential configurations. The configs stored in this file are-

auth: This is the variable in the config.env file that stores the endpoint of the backend microservice and its port. Its value is set to http://localhost:8000. This value is to localhost because I ran it on my local machine to test the app. We will change this configuration when deploying the app in the AWS EKS Cluster. The backend service is running on port 8000 so I have provided port 800 in this endpoint.

The authentication microservice does not take its port's value from its configuration file and its port value is fixed in the authentication's app.py file. You can see the port at last of app.py file in auth directory.

APP_HOST: It is the bind address for the backend microservice same as the bind address of the auth microservice.

CSVs

This is the directory that has CSV (Comma Separated Value) files that store user tasks.

secret

This is the directory that contains "secret.env" file for confidential configurations. Just a single config is defined in this file which is the session key for the backend with the variable name "SECRET_KEY".

templates

This directory contains HTML files for the web pages. There is no need to understand and look at these files.

.dockerignore

It contains the names of the files that should not be copied to the backend microservice's container Image as these have no use there.

app.py

This file has the main source code of the backend microservice. You do not have to understand its source code but feel free if you want to.

Dockerfile

The backend's Image gets created from this file, it is similar to the Docker file of authentication microservice it uses the same Python image as authentication, set /app as the working directory, runs commands to install the backend's requirement modules and runs the backend application when a container gets created from it.

requirements.txt

This file contains the required modules used by the backend microservice.

todo.py

This is a file that has Python functions that get used by the app.py file to perform operations on CSV files.


Configuration in K8s

You have now seen the configuration files in both the microservices directory. The confidential and non-confidential configurations are stored in different files because we are going to use K8s secrets for the secret config that will inject the secret configuration file in the container and the K8s config map that will inject the non-secret config in the container. So since there are two separate methods to store confidential and non-confidential config there needed to be two files in the application as well for the respective configs as well.

Let me tell you when we deploy the application, the K8s secret and ConfigMap will inject config files in the "/app/config" and "/app/secret" directories and replace the "secret.env" file and "config.env" file with the files with the same name of these files but with different configurations in the container (/app is the working directory as we have defined in the Dockerfile it is where the application code is).

So you can leave all the configurations defined by me for my local machine as it is and do to need to edit it.

The advantage of this approach is that we can change the configurations in K8s Secret and ConfigMaps without the need to update the configs in microservices and rebuild the image out of it.

The "secret.env" and "config.env" are in different directories because K8s Secret and ConfigMaps use volumes of type "Secret" and of type "ConfigMap" to inject files in the specified directory and we have to mount these volumes in these directories. So the catch is that we cannot mount more than one volume in a directory hence, "secret.env" and "config.env" are in two different directories so that we can mount secret volume type and ConfigMap volume type in different directories.

We will implement these configurations in upcoming blogs


Share the blog on socials and tag me onXandLinkedInfor the #buildinpublic initiative.

Follow me on X and LinkedIn

******Thank you for reading๐Ÿ˜๐Ÿ˜‡******

ย