This project demonstrates an auto-scaling architecture for WebSocket servers running within a Kubernetes cluster, leveraging Prometheus metrics for dynamic scaling based on real-time usage.
The architecture is composed of several components designed to work in tandem for providing a scalable, real-time WebSocket communication service:
websocket-client
: A Node.js application that simulates WebSocket connections to test the scalability and performance of the WebSocket server.websocket-server
: A Node.js WebSocket server that handles incoming connections and emits standard WebSocket events.websocket-scaler
: A Python application running within the Kubernetes cluster, tasked with collecting metrics from thewebsocket-server
pods and performing scaling actions based on those metrics.
The project is organized into the following directory structure:
/apps
/websocket-client
: Contains the WebSocket client simulation application./websocket-server
: Contains the WebSocket server application./websocket-scaler
: Contains the Kubernetes scaling application.
/kubernetes
/redis
: Contains Kubernetes manifests for Redis deployment, used for storing session data with persistence./websocket-server
: Contains Kubernetes manifests for deploying the WebSocket server.service.yaml
: Service configuration withsessionAffinity: ClientIP
to maintain session persistence.ingress.ws
: Ingress configuration withnginx.ingress.kubernetes.io/load-balance: "ewma"
for efficient load balancing andnginx.ingress.kubernetes.io/upgrade: "websocket"
to properly handle WebSocket upgrades.
Before deploying the WebSocket infrastructure, ensure that you have the following prerequisites installed:
-
Install Minikube: Follow the official Minikube installation guide to install Minikube on your machine.
-
Start Minikube: Once installed, start a Minikube cluster using the following command:
minikube start
-
Verify the cluster: Check the status of the cluster to ensure it's running:
minikube status
- Fetch the script:
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
- Add permisions to script:
chmod 700 get_helm.sh
- Execute the script:
./get_helm.sh
- Add prometheus helm repository:
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
- Update helm repository:
helm repo update
- Install prometheus on minkube:
helm install prometheus prometheus-community/kube-prometheus-stack
- Verify prometheus installation:
Ensure that all the components are up and running:
kubectl get all -n prometheus
With Minikube and Prometheus running, you can now deploy the WebSocket components to the cluster:
- Deploy Redis::
Navigate to the kubernetes/redis directory and apply the manifests:
kubectl apply -f .
- Deploy WebSocket Server::
Navigate to the kubernetes/websocket-server directory and apply the manifests for the StatefulSet and associated resources:
kubectl apply -f .
- Deploy WebSocket Scaler::
Navigate to the kubernetes/websocket-scaler directory and apply the manifests for the Deployment and associated resources:
kubectl apply -f .
OBS: You can navigate to any app dir inside app/ and build your own docker image then change the image reference on StatefulSet or Deployment if you want to make any changes in the code, feel free :)
The connections.js
script in the apps/websocket-client
directory is a Node.js application that simulates multiple WebSocket connections to test the scalability and performance of the WebSocket server. It attempts to establish a specified number of WebSocket connections, each with a delay between connections to avoid overwhelming the server.
To run the simulation, follow these steps:
- Navigate to the Client Application Directory:
Change into the
apps/websocket-client
directory where theconnections.js
script is located.cd apps/websocket-client
- Install Dependencies::
Before running the script for the first time, make sure to install the necessary Node.js dependencies.
npm install
- Run the script::
Execute the connections.js script using Node.js.
node src/connections.js