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.
Deploy infrastructure
To enable kubernetes, I just need to download and install docker for desktop and activate it
Workflow
-
The web application gateway receives an HTTP request from the internet and should requires an API call to the Azure SQL Database.
- The web api connects to the virtual network through a virtual interface mounted in the aksSubnet of the virtual network LogCorner.EduSync.Speech.Vnet
-
Azure Private Link sets up a private endpoint for the Azure SQL Database in the databaseSubnet of the virtual network.
-
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.
-
The web api connects to the Azure SQL Database through the private endpoint in the databaseSubnet.
-
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