Deploy a Web Application to Azure Kubernetes Service (AKS)
This tutorial guides you through deploying a simple web application to an Azure Kubernetes Service (AKS) cluster. We'll cover creating a container image, pushing it to Azure Container Registry (ACR), and then deploying it to AKS.
Prerequisites
- An Azure account with an active subscription. If you don't have one, you can create a free account.
- The Azure CLI installed and configured.
- Docker installed and running locally.
- Kubectl installed.
Step 1: Create a Sample Web Application
First, let's create a basic web application. For this example, we'll use a simple Node.js application.
Create a new directory for your application, e.g., my-aks-app, and navigate into it.
Create a file named app.js with the following content:
const express = require('express');
const app = express();
const port = process.env.PORT || 8080;
app.get('/', (req, res) => {
res.send('Hello from AKS!');
});
app.listen(port, () => {
console.log(`App listening on port ${port}`);
});
Create a package.json file:
{
"name": "my-aks-app",
"version": "1.0.0",
"description": "Simple web app for AKS deployment",
"main": "app.js",
"scripts": {
"start": "node app.js"
},
"dependencies": {
"express": "^4.17.1"
}
}
Install the Node.js dependencies:
npm install
Step 2: Create a Dockerfile
In the same directory, create a file named Dockerfile:
# Use an official Node runtime as a parent image
FROM node:18-alpine
# Set the working directory in the container
WORKDIR /usr/src/app
# Copy package.json and package-lock.json to the working directory
COPY package*.json ./
# Install any needed packages specified in package.json
RUN npm install
# Bundle app source
COPY . .
# Make port 8080 available to the world outside this container
EXPOSE 8080
# Define environment variable
ENV PORT=8080
# Run app.js when the container launches
CMD [ "npm", "start" ]
Step 3: Build and Push the Docker Image to ACR
First, you need an Azure Container Registry (ACR). If you don't have one, create it:
az acr create --resource-group myResourceGroup --name myaksacr <unique-acr-name> --sku Basic
Login to your ACR:
az acr login --name <unique-acr-name>
Build the Docker image and tag it for ACR:
docker build -t <unique-acr-name>.azurecr.io/my-aks-app:v1 .
Push the image to ACR:
docker push <unique-acr-name>.azurecr.io/my-aks-app:v1
Step 4: Create an AKS Cluster
If you don't have an AKS cluster, create one:
az aks create --resource-group myResourceGroup --name myAKSCluster --node-count 1 --enable-addons monitoring --generate-ssh-keys
Get credentials for your AKS cluster:
az aks get-credentials --resource-group myResourceGroup --name myAKSCluster
Step 5: Deploy the Application to AKS
Create a Kubernetes deployment manifest file, e.g., deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-aks-app-deployment
spec:
replicas: 3
selector:
matchLabels:
app: my-aks-app
template:
metadata:
labels:
app: my-aks-app
spec:
containers:
- name: my-aks-app
image: <unique-acr-name>.azurecr.io/my-aks-app:v1
ports:
- containerPort: 8080
env:
- name: PORT
value: "8080"
Create a Kubernetes service manifest file, e.g., service.yaml:
apiVersion: v1
kind: Service
metadata:
name: my-aks-app-service
spec:
selector:
app: my-aks-app
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: LoadBalancer
Apply the deployment and service configurations:
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
Step 6: Access Your Application
Get the external IP address of the LoadBalancer service:
kubectl get service my-aks-app-service
It might take a few minutes for the LoadBalancer to provision and assign an external IP. Once available, open a web browser and navigate to the external IP address. You should see "Hello from AKS!".
Note: If you are using a free Azure account or a limited subscription, creating a LoadBalancer service might incur costs. Consider using a ClusterIP service for internal access or NodePort for simpler exposure during development.
Clean Up
To avoid ongoing charges, you can delete the AKS cluster and ACR:
az group delete --name myResourceGroup --yes --no-wait