Deploying a Microservices E-Commerce Project on Azure Kubernetes Service (AKS)
1. Overview & Architectural Premise
This chapter serves as a hands-on deployment guide for taking a polyglot, microservices-based e-commerce application (the IBM/Instana Robot Shop) and running it on Azure Kubernetes Service (AKS).
- The Application: An e-commerce platform that sells robotic parts, featuring 8 microservices, 2 databases (
MongoDBandMySQL), and an in-memory data store (Redis). - DevOps Objectives: Containerize services across multiple programming languages, manage stateful vs. stateless components, provision persistent storage classes, and expose applications using Kubernetes
Ingresscontrollers on Azure.
2. Real-Life Analogy: The Modular E-Commerce Mall
Real-Life Analogy: Think of a monolithic application as a traditional mom-and-pop general store where a single cashier handles billing, inventory, customer lookup, and shipping all in one room. If the cash register breaks, the entire store stops.
In contrast, our Microservices E-Commerce architecture is like a massive modern shopping mall. Each store (microservice) operates independently—the shoe store doesn't crash when the clothing boutique restocks its inventory. Specialized backend teams manage distinct data warehouses (MongoDB for customer records, MySQL for product images, and Redis for rapid-fire real-time product ratings), communicating seamlessly through structured APIs.
3. High-Level System Architecture & Microservices Breakdown
The application is intentionally polyglot (built across multiple languages) to simulate real-world enterprise environments where different teams choose the optimal technology stack for their specific domain.
Microservice Technology Matrix
4. Containerization Deep Dive: Dockerfiles Across Languages
Each microservice has a customized Dockerfile tailored to its specific runtime.
A. Node.js Service (e.g., Cart / Catalog)
FROM node:18-alpine
ENV INSTANA_ENABLED=false
EXPOSE 8080
WORKDIR /app
COPY package.json ./
RUN npm install
COPY server.js ./
CMD ["node", "server.js"]
B. Python Service (e.g., Payments)
FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY app.py ./
CMD ["python", "app.py"]
C. Java Multi-Stage Build (e.g., Shipping)
To prevent heavy build tools (like Maven and full JDKs) from bloating production runtime images, the shipping service uses a Multi-Stage Build:
# Stage 1: Build the Java Binary (Maven + Heavy Debian Base)
FROM maven:3.8-jdk-11 AS build
WORKDIR /build
COPY pom.xml ./
COPY src ./src
RUN mvn clean package -DskipTests
# Stage 2: Runtime Execution (Lightweight OpenJDK)
FROM openjdk:11-jre-slim
WORKDIR /app
COPY --from=build /build/target/shipping.jar ./shipping.jar
EXPOSE 8080
CMD ["java", "-jar", "shipping.jar"]
5. Kubernetes Deployment Strategy: Plain Manifests vs. Helm Charts
Deploying 8 microservices, databases, and associated objects manually requires managing roughly 24 distinct YAML manifests.
The Maintenance Dilemma
- Maintaining raw YAML files across multiple environments (
Dev,Staging,Production) leads to configuration drift and redundant code. - Helm Solution: Helm packages these 24 manifests inside a
templates/folder while externalizing dynamic variables (such as image repositories, replica counts, and resource limits) into a singlevalues.yamlfile.
6. Storage Architecture: Persistent Volumes & StatefulSets for Redis
The Ratings service relies on Redis for real-time rating computations. Because Redis stores data in memory, standard Pod restarts would wipe out all user ratings unless backed by persistent storage.
StatefulSet Configuration
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: redis
namespace: roboshop
spec:
serviceName: redis
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: redis:alpine
ports:
- containerPort: 6379
volumeMounts:
- name: data-redis
mountPath: /data
volumeClaimTemplates:
- metadata:
name: data-redis
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "default"
resources:
requests:
storage: 1Gi
Storage Class Decision Matrix
When requesting persistent storage in AKS, selecting the correct storage class determines underlying performance and attachment behavior:
7. Step-by-Step Execution Walkthrough on Azure AKS
Step 1: Provision the AKS Cluster
Create an AKS resource group and cluster using the Azure CLI or Azure Portal:
# Create Resource Group
az group create --name e-commerce-demo --location westus2
# Create AKS Cluster
az aks create \
--resource-group e-commerce-demo \
--name three-tier \
--node-count 1 \
--enable-managed-identity \
--generate-ssh-keys
Step 2: Configure Local Kubectl Context
Fetch cluster credentials to connect your local terminal to the newly provisioned AKS cluster:
az aks get-credentials --resource-group e-commerce-demo --name three-tier
# Verify connection
kubectl config current-context
kubectl get nodes
Step 3: Clone Repository & Deploy via Helm
Clone the project repository, switch to the Helm directory, create the namespace, and deploy the application:
git clone https://github.com/iam-veeramalla/three-tier-architecture-demo.git
cd three-tier-architecture-demo/AKs/helm
# Create Namespace
kubectl create namespace roboshop
# Install Helm Chart
helm install roboshop-release . --namespace roboshop
Step 4: Verify Pod Health
Monitor deployment rollouts to ensure all 8 microservices, databases, and Redis pods are running:
kubectl get pods -n roboshop
Expected outcome: All pods transition into the Running state.
8. Ingress Configuration & External Exposure
While services can be exposed individually via cloud LoadBalancers, utilizing a Kubernetes Ingress Controller provides advanced routing capabilities (path-based routing, TLS termination, and Web Application Firewall integration).
Enabling Native Ingress on AKS
- Navigate to your AKS cluster in the Azure Portal.
- Select Networking -> Check Enable Ingress Controller (or provision via Azure App Gateway Ingress Controller add-on).
- Apply the Ingress Manifest:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: roboshop-ingress
namespace: roboshop
annotations:
kubernetes.io/ingress.class: azure/application-gateway
spec:
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web
port:
number: 8080
Apply the Ingress resource:
kubectl apply -f ingress.yaml -n roboshop
Retrieve the external IP address assigned by the Azure Ingress controller:
kubectl get ingress -n roboshop
Paste the external address into your browser to access the fully functioning Robot Shop e-commerce platform.
9. Summary and Key Takeaways
- Polyglot Microservices: Enterprise architectures often combine multiple programming languages (Node.js, Python, Java, Go) where each service operates independently and communicates via APIs.
- Data Persistence Strategy: Ephemeral application workloads require robust storage abstraction. Stateful components like Redis utilize StatefulSets bound to Persistent Volume Claims (PVCs).
- Storage Class Selection: Use Azure Managed Disks (
ReadWriteOnce) for single-pod stateful databases and Azure Files (ReadWriteMany) when multiple pods across nodes require shared file access. - Helm Package Management: Deploying complex multi-service applications (24+ manifests) is simplified using Helm charts by externalizing environment-specific configurations into
values.yaml. - AKS Ingress Integration: Native Ingress controllers on Azure (such as Application Gateway Ingress) route external web traffic efficiently while supporting enterprise security policies.