Community post originally published on Dev.to by Syed Asad Raza
Helm, often described as the package manager for Kubernetes, simplifies the deployment and management of applications within Kubernetes clusters. This guide will walk you through deploying a microservices application using Helm, illustrating key concepts such as creating Helm charts, managing dependencies, and deploying a multi-service application.
Prerequisites
Before we begin, ensure you have the following tools installed:
- kubectl: Kubernetes command-line tool.
- minikube: Local Kubernetes cluster for development and testing.
- Docker: For building container images.
- Helm: Kubernetes package manager.
Overview
We will deploy a sample application consisting of two microservices:
- Frontend Service: A simple web application that communicates with the backend service.
- Backend Service: An API that returns a message.
We’ll use Helm to package these services into charts, manage their dependencies, and deploy them to a Kubernetes cluster.
Keep reading
- Use a bash utility to install multiple Helm charts
- The evolution of deployments in werf
- Your operator should be a Helm chart
- Register for KubeCon + CloudNativeCon North America 2024 today
Step 1: Build Docker Images
First, we need to create Docker images for our frontend and backend services.
Backend Service
Create a simple Node.js
backend service:
// backend/server.js
const express = require('express');
const app = express();
app.get('/api/message', (req, res) => {
res.json({ message: 'Hello from the backend!' });
});
const port = 3000;
app.listen(port, () => {
console.log(`Backend service running on port ${port}`);
});
Create a Dockerfile
for the backend:
# backend/Dockerfile
FROM node:14
WORKDIR /app
COPY server.js .
RUN npm install express
EXPOSE 3000
CMD ["node", "server.js"]
Frontend Service
Create a simple HTML file for the frontend service:
<!-- frontend/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Frontend Service</title>
</head>
<body>
<h1>Frontend Service</h1>
<div id="message"></div>
<script>
fetch('/api/message')
.then(response => response.json())
.then(data => {
document.getElementById('message').innerText = data.message;
});
</script>
</body>
</html>
Create a Dockerfile for the frontend:
# frontend/Dockerfile
FROM nginx:alpine
COPY index.html /usr/share/nginx/html
Build Docker Images
Navigate to each service directory and build the Docker images
:
In backend directorydocker build -t backend-service
In frontend directorydocker build -t frontend-service
Step 2: Create Helm Charts
Create a Helm Chart for the Backend Service
Navigate to a working directory and create a new Helm chart:
helm create backend
This command generates a basic Helm chart structure. Modify the backend/templates/deployment.yaml
file to suit our backend service:
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-backend
spec:
replicas: 2
selector:
matchLabels:
app: {{ .Release.Name }}-backend
template:
metadata:
labels:
app: {{ .Release.Name }}-backend
spec:
containers:
- name: backend
image: backend-service
ports:
- containerPort: 3000
Modify the backend/templates/service.yaml
file:
apiVersion: v1
kind: Service
metadata:
name: {{ .Release.Name }}-backend
spec:
selector:
app: {{ .Release.Name }}-backend
ports:
- protocol: TCP
port: 80
targetPort: 3000
Create a Helm Chart for the Frontend Service
Similarly, create a Helm chart for the frontend service:
helm create frontend
Modify the frontend/templates/deployment.yaml
file:
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-frontend
spec:
replicas: 2
selector:
matchLabels:
app: {{ .Release.Name }}-frontend
template:
metadata:
labels:
app: {{ .Release.Name }}-frontend
spec:
containers:
- name: frontend
image: frontend-service
ports:
- containerPort: 80
Modify the frontend/templates/service.yaml
file:
apiVersion: v1
kind: Service
metadata:
name: {{ .Release.Name }}-frontend
spec:
selector:
app: {{ .Release.Name }}-frontend
ports:
- protocol: TCP
port: 80
targetPort: 80
Step 3: Deploy Using Helm
Start your Minikube cluster:minikube start
Deploy the Backend Service
Navigate to the backend directory and install the chart:
helm install backend ./backend
Deploy the Frontend Service
Navigate to the frontend directory and install the chart:
helm install frontend ./frontend
Step 4: Set Up Ingress
To expose the frontend service externally, we will set up an ingress.
Enable Ingress in Minikube
Enable the ingress addon:
minikube addons enable ingress
Create Ingress Resource
Create an ingress
resource to route traffic to the frontend service:
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: frontend-ingress
spec:
rules:
- host: frontend.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend
port:
number: 80
Apply the ingress configuration:
kubectl apply -f ingress.yaml
Add an entry to your /etc/hosts
file to map frontend.local
to the Minikube IP:
echo "$(minikube ip) frontend.local" | sudo tee -a /etc/hosts
Step 5: Verify the Deployment
Access the frontend service in your browser by navigating to http://frontend.local
. You should see the frontend page displaying the message fetched from the backend service.
Conclusion
In this guide, we’ve deployed a microservices application using Helm on Kubernetes, demonstrating intermediate concepts like creating Helm charts, managing dependencies, and setting up ingress. Helm simplifies the deployment and management of Kubernetes applications, making it a powerful tool for cloud-native development.
By sharing this tutorial, you’re providing valuable technical content to the CNCF community, helping others understand and leverage Helm for their Kubernetes deployments.