Deploying Microservice App on K8s

Deploying Microservice App on K8s

Part 4: Persistent Storage, ConfigMaps and Secrets Manifests

ยท

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.

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

Persistent Storage

To deploy the application we need to understand how to implement persistent storage in the AWS EKS Cluster. As I have said in the previous blogs, we will use AWS EFS (Elastic File System) as a persistent storage and mount volume from this storage on the backend microservice's container.

I highly recommend reading the article below on persistent storage in the AWS EKS Cluster before moving further in this blog.

You do not need to edit the discussed files, I will tell you when to edit and what to edit as I discuss these files.

So let's discuss the manifest files for persistent storage

storage_class.yaml

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: cluster-persistent-storage
provisioner: efs.csi.aws.com
reclaimPolicy: Retain
parameters:
  provisioningMode: efs-ap
  fileSystemId: "Your EFS file sytem Id"
  directoryPerms: "700"

Here is the first Kubernetes manifest, it defines a name for this storage class and next it defines a provisioner which is the AWS EFS CSI DRIVER in our case.

Reclaim Policy is set to Retain which means PV (persistent volume) is not automatically deleted when the PVC is deleted or when the application is terminated. Instead, the PV and its data are retained, and it's up to the cluster administrator to manually reclaim or delete the resources.

Next, there is a parameter section that defines the provisioning mode. The provisioningMode parameter is used to define the mode in which the storage should be provisioned. In our case, the value is set to efs-ap, indicating Elastic File System (EFS) automatic provisioning mode with access points.

Next in the parameter section, you have to paste the file system ID of your EFS file system. You can get it in the EFS Service.

At last, directory read and write permission is defined, allowing only the owner (user) to read, write, and execute files within that directory.

Here is the K8s documentation on storage classes-

pvc.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: backend-pvc-claim
  namespace: backend
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: cluster-persistent-storage
  resources:
    requests:
      storage: 1Gi

This is the file where PVC (Persistent Volume Claim) is defined. The claim is named as backend-pvc-claim and this claim resides in the "backend" namespace.

In the spec section accessModes is defined which is set to ReadWriteMany which means multiple pods can read and write to this PVC at a time.

Next storageClassName is defined as cluster-persistent-storage which is the name of our storage class that I described above.

Next in the resources, this PVC will request 1 GB of data capacity from the storage class.

This is it, storage_class.yaml and pvc.yaml are the only two files required to provision persistent volume in the EKS cluster. Now we just need to mount the PVC to the backend microservice's pod.


ConfigMaps and Secret Manifests

These are important manifest files as you have we have to define the passwords and endpoints in these files and the communication between microservices and database will happen only if we do this part right.

In the previous blog, I discussed the ConfigMaps and secrets and mentioned that we do not have to change the configuration in the source code of microservices and you can make those configs as it is because ConfigMaps and Secret will inject configuration files in the container for us.

ConfigMap and secret for Authentication Microservice

auth-configs.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: auth-config
data:
  config.env: |
    DB_HOST= "Your RDS Database Endpoint"
    APP_HOST=0.0.0.0

This is the ConfigMap manifest and this ConfigMap is named "auth-config" that is defined in "metadata" section.

Next in the data section, I have a script that creates a file as config.env which as you should know is the name of the config file in the source code. This file has a DB_HOST variable and a APP_HOST variable. You just need to paste the database endpoint of your RDS MySQL database here.

Make the cloud architecture with the terraform command and go to the AWS RDS service and in there you will see the database, in the database you will the endpoint in the Connectivity and Security section.

Whenever you build the architecture from the same rds.tf file after destroying the architecture, the RDS database will have this same endpoint so you do not have to update this endpoint in ConfigMap every time you build the architecture after destroying it.

You can find K8s ConfigMap doc here.

auth-secrets.yaml

apiVersion: v1
kind: Secret
metadata:
  name: auth-secret
type: Opaque
data:
  secret.env: |
    REFUQUJBU0U9dGFza2xpc3RfZGIKREJfVVNFUk5BTUU9c2VucGFpCkRCX1BBU1NXT1JEPW9ubHlz
    ZW5wYWlrbm93cwpKV1RfU0VDUkVUX0tFWT1kNzRmYWUxMDQzYzdlN2ExMWM3NDE2YWRjMjlmMmE4
    MDYyMzdiOWU1N2I4MTViYzgwMGM1ODA3ZWNjMjc3OTI2ClNFQ1JFVF9LRVk9MjhhYWM1N2U2YTg3
    MTZlY2JmNGRiNjNlN2E5NDJjMGE3OTM5MjE3NTI1ODAyMjFkMjA0MjY4YjhjNzQ2MzZhOQ==

This is the K8s secret file that contains the secret file in base64 encoded value. This secret works similarly to ConfigMap as I have a similar script here which makes a file named "secret.env" and in that file, it pastes the secret database config in base64 encoded format.

The secret file in the repository source code will work just fine if you haven't changed any value in the rds.tf file and you do not have to edit this file. However, it is important to know how to get the base64 encoded value for secret configs.

Here is how you can make yourself this base64 encoded config.

In a file write down the secret configurations and the value of variables like DATABASE, DB_USERNAME and DB_PASSWORD you can see the value of these variables in Terraform rds.tf file.

The DATABASE variable stores the name of the database that we want to connect to, we have defined it in a terraform file along with the database password and database username so you can copy these values from there. You can change the JWT_SECRET_KEY and SECRET_KEY values or keep them the same it's up to you.

You can also copy the whole config below at once with ctrl+a.

DATABASE=tasklist_db
DB_USERNAME=senpai
DB_PASSWORD=onlysenpaiknows
JWT_SECRET_KEY=d74fae1043c7e7a11c7416adc29f2a806237b9e57b815bc800c5807ecc277926
SECRET_KEY=28aac57e6a8716ecbf4db63e7a942c0a793921752580221d204268b8c74636a9

After you have copied the whole config you need to encode this config. You can do this by entering this command in the terminal-

echo "Your copied config" | base64

In the above command, you have to keep the double quotes and in the quotes past the configs.

Below is the actual command I used to encode the above config-

echo "DATABASE=tasklist_db
DB_USERNAME=senpai
DB_PASSWORD=onlysenpaiknows
JWT_SECRET_KEY=d74fae1043c7e7a11c7416adc29f2a806237b9e57b815bc800c5807ecc277926
SECRET_KEY=28aac57e6a8716ecbf4db63e7a942c0a793921752580221d204268b8c74636a9" | base64

Once you execute this command you will see a base64 encoded value of this file, you need to copy this base64 encoded value and paste it into the K8s secret manifest file for the backend microservice (auth-secrets.yaml).

You can find K8s secret doc here.

ConfigMap and secret for Backend Microservice

backend-configs.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: backend-config
  namespace: backend
data:
  config.env: |
    auth=http://auth-service.auth:8000
    APP_HOST=0.0.0.0

This ConfigMap manifest is similar to that of authentication, the manifest is named "backend-config" and in the backend namespace. In the script it creates a file named "config.env" and has the authentication microservice's endpoint in the auth variable.

The authentication's endpoint is the name of the service that the authentication deployment will use which is auth-service and after the service .auth is there which means that the service resides in the auth namespace and at the end, the port :8000 is there in which the auth is listening to.

The APP_HOST is listening to all network interfaces and it need not be changed.

backend-secrets.yaml

apiVersion: v1
kind: Secret
metadata:
  name: backend-secret
  namespace: backend
type: Opaque
data:
  secret.env: |
    U0VDUkVUX0tFWT0vZHM6NjgzNHR2I2RhCg==

Backend's secret manifest is also similar to that of the authentication. The name of this secret is backend-secret and it is in backend namespace. In the script, it creates a file named secret.env and stores the base64 encoded value of the session key for the backend.

You do not need to change anything in this file and here is how I created it-

SECRET_KEY=/ds:6834tv$b#da

I encoded this config by this command-

echo "SECRET_KEY=/ds:6834tv$b#da" | base64

After this command, the terminal will output the base 64 encoded value, I just pasted that value in this secret manifest file.


Share the blog on socials and tag me on X and LinkedIn for the #buildinpublic initiative.

Follow me on X and LinkedIn

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

ย