Building micro services through Event Driven Architecture part24 : deploy and manage applications on a Kubernetes cluster using helm charts

Building micro services through Event Driven Architecture part24 : deploy and manage applications on a Kubernetes cluster using helm charts

This tutorial is the 24th episode of a series : Building microservices through Event Driven Architecture.

Helm is a package manager for Kubernetes that allows users to easily deploy and manage applications on a Kubernetes cluster. Helm uses charts, which are packages of pre-configured Kubernetes resources, to simplify the deployment process.

In this tutorial I will use  helm chart to deploy an azure azure kubernetes services cluster , an azure sql database with private endpoint and an azure container registry.

A chart is a definition of the application and a release is an instance of a chart
we can install a new release of a revision of an existing release

Deploy infrastructure

To enable kubernetes, I just need to download and install docker for desktop and activate it

Workflow

  1. The web application gateway receives an HTTP request from the internet and should requires an API call to the Azure SQL Database.

  2. The web api connects to the virtual network through a virtual interface mounted in the aksSubnet of the virtual network LogCorner.EduSync.Speech.Vnet
  3. Azure Private Link sets up a private endpoint for the Azure SQL Database in the databaseSubnet of the virtual network.

  4. The web api sends a query for the IP address of the Azure SQL Database. The query traverses the virtual interface in the aksSubnet. The CNAME of the Azure SQL Database directs the query to the private DNS zone. The private DNS zone returns the private IP address of the private endpoint set up for the Azure SQL Database.

  5. The web api connects to the Azure SQL Database through the private endpoint in the databaseSubnet.

  6. The Azure SQL Database firewall allows only traffic coming from the databaseSubnet to connect. The database is inaccessible from the public internet.

Components

This scenario uses the following Azure services:

  • Azure Web Application Gateway distribute incoming traffic across the kubernetes cluster ensuring high availability and scalability

  • Azure kubernetes services : hosts web api, allowing autoscale and high availability without having to manage infrastructure.  for now the ask cluster have a public ip address and I will disable it on upcoming tutorials
  • Azure container registry : hosts docker images deployed in the kubernetes cluster. for now the azure container registry have  public access and I will disable it on upcoming tutorials
  • Azure SQL Database is a general-purpose relational database managed service that supports relational data, spatial data, JSON, and XML.

  • Azure Virtual Network is the fundamental building block for private networks in Azure. Azure resources like virtual machines (VMs) can securely communicate with each other, the internet, and on-premises networks through Virtual Networks.

  • Azure Private Link provides a private endpoint in a Virtual Network for connectivity to Azure PaaS services like Azure Storage and SQL Database, or to customer or partner services.

  • Azure DNS hosts private DNS zones that provide a reliable, secure DNS service to manage and resolve domain names in a virtual network without the need to add a custom DNS solution.

  • Azure virtual machine : used to connect and manage sql server database through the private endpoint  
  • Azure bastion Host : used to connect securely to the azure virtual machine 

The terraform files to deploy the infrastrcuture can be found here : .\LogCorner.EduSync.Speech.Command\iac

#terraform init is a command used to initialize a new or existing Terraform working directory. This command is typically run at the beginning of a new project, or when you want to update the provider plugins used by an existing project.

terraform init

#terraform plan is a command used to create an execution plan for a Terraform configuration. This command will show you what changes Terraform will make to your infrastructure based on the current configuration. The -var-file flag is used to specify a file containing input variables for the configuration.

terraform plan -var-file="dev.tfvars"

# terraform apply is a command used to apply the changes defined in a Terraform configuration to your infrastructure. This command will create or update any resources necessary to bring your infrastructure in line with the desired state defined in your configuration.

terraform apply -var-file="dev.tfvars" --auto-approve

Build docker images

To deploy application in kubernetes, we need to dockerize the application and build docker image.

So, you can run the following command to build the images, locate the docker-compose.yml file under (\LogCorner.EduSync.Speech.Command\src)

# Build the images using my docker-compose.yml file
docker-compose build

The build will produce 2 images : logcornerhub/logcorner-edusync-speech-command  and logcornerhub/logcorner-edusync-speech-mssql-tools

for deployment to azure kubernetes services, i will not use logcornerhub/logcorner-edusync-speech-mssql-tools image because i will deploy to azure sql database

Tag and push image to azure container registry

# define variables
$resourceGroupName ="LOGCORNER.EDUSYNC.SPEECH.RG"
$azureContainerRegistryName ="logcorneredusyncregistry"
$subscriptionId="{{your_azure_subscriptionId}}"

# login to azure using az login or service principal
az login
az account set --subscription $subscriptionId

# login to the azurecontainer registry
az acr login --name $azureContainerRegistryName

# tag
docker tag logcornerhub/logcorner-edusync-speech-command  "$azureContainerRegistryName.azurecr.io/logcorner-edusync-speech-command:1.0.0"

# push 
docker push "$azureContainerRegistryName.azurecr.io/logcorner-edusync-speech-command:1.0.0"

Build kubernetes configuration files

login to your azure account and set your Azure default Subscription

az login 
az account set --name [your subscriptionId ou subscriptionName ]

in ths tutorial, I will use docker-desktop and enable kubernetes.

If you have many kubernetes clusters in your kubeconfig file, please run the following commands to use docker-desktop as your default kubernetes cluster.

# Define variables
$resourceGroupName ="LOGCORNER.EDUSYNC.SPEECH.RG"
$aksName="LogCornerEduSyncSpeechCluster"
# Get the kubeconfig to log into the cluster
az aks get-credentials  --resource-group $resourceGroupName   --name $aksName
# set context
kubectl config get-contexts 
kubectl config use-context  $aksName
kubectl cluster-info

deploy and manage applications on a Kubernetes cluster using helm charts

The helm charts can be located under : .\LogCorner.EduSync.Speech.Command\kubernetes\aks\helm-chart

A chart is a definition of the application and a release is an instance of a chart
we can install a new release or a revision of an existing release


# install helm 
To  install helm we can navigate to the website and follow the steps to install helm in our operating system
https://helm.sh/docs/intro/install/
for example for windows I can use choco : choco install kubernetes-helm

# Verify installation
helm version --short :  is used to display the version of the Helm client installed on your system in a short format

# Add the official stable Helm chart repository. This repository contains a large collection of pre-built charts that can be used to deploy a variety of common applications and services to Kubernetes clusters.

helm repo add "stable" "https://charts.helm.sh/stable"

# Install a Release  :  helm install [release] [chart]
# installing a chart named webapi with the release name logcorner-command

helm install  logcorner-command  webapi

# list all the releases deployed to a Kubernetes cluster
helm list

# get all pods
kubectl get pods

# get all services
kubectl get services

# helm history [release]
helm history logcorner-command

# helm upgrade [release] [chart]
helm upgrade   logcorner-command  webapi

# helm rollback [release] [revision]
helm rollback logcorner-command 1

# helm status [release]
helm status logcorner-command

# helm get all [release]
helm get all logcorner-command

# helm get manifest  [release]
helm get manifest logcorner-command

# helm uninstall [release]
helm uninstall logcorner-command  webapi

Note the service load balancer public ip (20.23.189.10) I will need it to test the web api : http://52.137.56.112/swagger/index.html

Setup sql server database

To setup the sql server database, I should connect to the bastion visrtual machine deployed on management. Note that I can connect to the database using a virtual machine that can reach the SQL Server using its private endpoint.

Dowload and install a tool to help me for managing and administering SQL Server databases like SQL Server Management Studio (SSMS) that i can found here : https://learn.microsoft.com/en-us/sql/ssms/download-sql-server-management-studio-ssms?view=sql-server-ver16

you can aslo use your another tool : azure data studio, etc…

Connect to the database and run the scripts to create the database schema.

you can find the scripts inside the github repository folder : .\LogCorner.EduSync.Speech.Command\src\LogCorner.EduSync.Speech.Database\dbo\Tables

USE LogCorner.EduSync.Speech.Database
GO
CREATE TABLE [dbo].[EventStore] (
    [Id]          INT              IDENTITY (1, 1) NOT NULL,
    [Version]     BIGINT           NOT NULL,
    [AggregateId] UNIQUEIDENTIFIER NOT NULL,
    [Name]        NVARCHAR (250)   NOT NULL,
    [TypeName]    NVARCHAR (250)   NOT NULL,
    [OccurredOn]  DATETIME         NOT NULL,
    [PayLoad]     TEXT             NOT NULL,
    CONSTRAINT [PK__EventStore] PRIMARY KEY CLUSTERED ([Id] ASC)
);


GO
PRINT N'Creating Table [dbo].[MediaFile]...';


GO
CREATE TABLE [dbo].[MediaFile] (
    [ID]       UNIQUEIDENTIFIER NOT NULL,
    [Url]      NVARCHAR (250)   NULL,
    [SpeechID] UNIQUEIDENTIFIER NOT NULL,
    PRIMARY KEY CLUSTERED ([ID] ASC)
);


GO
PRINT N'Creating Table [dbo].[Speech]...';


GO
CREATE TABLE [dbo].[Speech] (
    [ID]          UNIQUEIDENTIFIER NOT NULL,
    [Title]       NVARCHAR (250)   NOT NULL,
    [Description] NVARCHAR (MAX)   NOT NULL,
    [Url]         NVARCHAR (250)   NOT NULL,
    [Type]        INT              NOT NULL,
    [IsDeleted]   BIT              NULL,
    CONSTRAINT [PK_Presentation] PRIMARY KEY CLUSTERED ([ID] ASC)
);


GO
PRINT N'Creating Default Constraint unnamed constraint on [dbo].[Speech]...';


GO
ALTER TABLE [dbo].[Speech]
    ADD DEFAULT (newid()) FOR [ID];


GO
PRINT N'Creating Default Constraint unnamed constraint on [dbo].[Speech]...';


GO
ALTER TABLE [dbo].[Speech]
    ADD DEFAULT ((1)) FOR [Type];


GO
PRINT N'Creating Default Constraint unnamed constraint on [dbo].[Speech]...';


GO
ALTER TABLE [dbo].[Speech]
    ADD DEFAULT ((0)) FOR [IsDeleted];


GO
PRINT N'Creating Foreign Key [dbo].[FK_MediaFile_Speech]...';


GO
ALTER TABLE [dbo].[MediaFile]
    ADD CONSTRAINT [FK_MediaFile_Speech] FOREIGN KEY ([SpeechID]) REFERENCES [dbo].[Speech] ([ID]);

GO

Test api deployment

Open a browser, http://20.23.189.10/swagger/index.html where 20.23.189.10 is the public ip address of the service . you can get it by running kubectl get services :

speech-command-http-api-service LoadBalancer 10.4.4.36 20.23.189.10 80:30155/TCP,443:30171/TCP

Create a post request (/api/speech), the body of the post request should look like this :

http://localhost:30124/swagger/index.html
{
  "title": "this is a title",
  "description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.",
  "url": "http://test.com",
  "typeId": 1
}

We should have a new record in the database

Code source is available here : 

  • https://github.com/logcorner/LogCorner.EduSync.Speech.Command/tree/episode-24-helm

Thanks for reading, if you have any feedback, feel free to post it

Support us

BMC logoBuy me a coffee