Step 1: Cluster Configuration Log in to your UpCloud Control Panel. Navigate to Kubernetes and click Create Cluster.
- Location: Choose a location (e.g.,
FI-HEL1as shown below).
Step 2: Network
- Network: Check the Private Network option.
Important
Crucial Step: You MUST create/select a private network (e.g., k8s-private-net). This connects your worker nodes securely. Note that the private network cannot be changed once the cluster has been created
Step 3: Node Group & SSH Configuration
- Plan: Select a plan (e.g.,
DevelopmentorGeneral Purpose). For this course, the2 core, 4 GB memory(Development) plan with 2 nodes is sufficient. - Name: Give your node group a name (e.g.,
worker-group).
- SSH Key: It is highly recommended to add an SSH key to access your worker nodes if debugging is needed.
- If you don't have one, follow this guide: How to use SSH keys authentication
- Select your public key in the "Authentication" section.
Step 4: Create
- Public Access: Ensure "Allow access from all IP addresses" is selected for the API unless you have a static IP. Review your summary and click Create cluster.
Note
Creating a Kubernetes cluster takes time (approximately 10 minutes). Please be patient while the status changes to Running.
Once the cluster status is Running, you need to configure your local environment to control it.
Step 1: Install kubectl If you haven't already, install the Kubernetes command-line tool: https://kubernetes.io/docs/tasks/tools/install-kubectl-linux
Step 2: Configure kubeconfig
- Go to the Kubernetes tab in UpCloud.
- Scroll down to the Kubeconfig section.
- Recommended to configure the kubeconfig file manually. Click Download kubeconfig to save the YAML file to your local machine (e.g.,
~/Downloads/coursetestcluster_kubeconfig.yaml). - Export KUBECONFIG that you downloaded above (use full path).
export KUBECONFIG=~/Downloads/coursetestcluster_kubeconfig.yamlTip
To make this permanent for the current session, you can add it to your shell profile (~/.bashrc or ~/.zshrc), or simply run this command every time you open a new terminal window to work on this project.
Step 3: Verify Connection Run the following command to check if you are connected:
kubectl cluster-infoExpected Output:
Kubernetes control plane is running at https://xxxxxx
CoreDNS is running at https://xxxxxx
Clone the repo
git clone https://github.com/EvoTestOps/DeathStarBench.git- Docker
- Docker-compose
- luarocks (apt-get install luarocks)
- luasocket (luarocks install luasocket)
- Navigate to the scripts directory:
git clone https://github.com/EvoTestOps/DeathStarBench.git
cd DeathStarBench/hotelReservation/kubernetes/scripts- Build the Docker images using the provided script:
./build-docker-images.shImportant
If you want to use your own Docker registry, you need to:
- Open
build-docker-images.shand modify theREGISTRYvariable to your Docker username - Update all deployment YAML files in the
kubernetes/directory to use your modified image names - Example: Change
igorrudyk1/user-service:latesttoyour-username/user-service:latest
kubectl apply -Rf DeathStarBench/hotelReservation/kubernetes/Wait until the deployment is complete to view the result
kubectl get pods- Option.1: Using Conda We strongly recommend using Conda virtual environment to avoid technical problems:
conda create --name hotel python=3.11
conda activate hotel
conda install -c conda-forge locust- Option.2: Using pip
sudo apt-get update
sudo apt install python3-pip
pip3 install locust
export PATH=$PATH:$HOME/.local/binWait for the external-IP of frontend (might take up to 10 minutes):
kubectl get svc frontend -wThen run the Locust test:
locust -f uh_locust_tests/locust.py --host=http://<your-external-IP-of-frontend>:5000 --headless -u 10 -r 2 -t 10sparameter description:--host means the address of host; --headless means not start the graphical interface and output the result in terminal;- u means the number of concurrent users; - r means the number of new users per second; -t means the duration of the test
Expected Output: You should see statistics about request success/failure rates.
For Task 1 and Task 2 reports, you need to observe the system status using these tools.
Jaeger is used for distributed tracing to monitor and troubleshoot transactions in complex distributed systems.
Get the URL: Watch for the external-IP of jaeger:
kubectl get svc jaeger -wAccess UI: Visit http://<your-external-IP-of-jaeger>:16686 in your browser.
How to use:
-
Search: Select a Service (e.g.,
frontend) and click "Find Traces". -
Analyze: Click on a specific trace to see the Spans (individual operations).
-
Identify Issues: Look for:
-
Errors: Spans marked in red.
-
Latency: unusually long bars in the timeline.
-
Waterfall view: Helps you understand which microservice is slowing down the request.
-
Prometheus is used for event monitoring and alerting.
Setup
Go to the corresponding directory
cd <path-of-repo>/hotelReservation/UH_prometheusCreate a configmap
kubectl create configmap prometheus-config --from-file=prometheus.ymlApply related resources
kubectl apply -f node-exporter-service.yaml
kubectl apply -f node-exporter.yaml
kubectl apply -f prometheus-config.yaml
kubectl apply -f prometheus-deployment.yaml
kubectl apply -f prometheus-rbac.yaml
kubectl apply -f prometheus-service.yamlGet the URL: Gets the external IP of the prometheus service
kubectl get svc prometheus -wVisit http://<your-external-IP-of-prometheus>:9090 in your browser.

How to use:
-
Graph Tab: Enter queries to visualize data over time.
-
Table Tab: View the current value of metrics.
Some sample query metrics
- CPU utilization
rate(node_cpu_seconds_total{mode="system"}[1m])- Memory usage
node_memory_MemTotal_bytes - node_memory_MemFree_bytes
- Disk usage
node_filesystem_size_bytes - node_filesystem_free_bytesTo debug specific pods (e.g., if a Locust test fails):
- Get pods name
kubectl get pods- View the specific pod logs
kubectl logs <pod-name># List all pods
kubectl get pods [-n namespace]
# Get pod details
kubectl describe pod <pod-name>
# Get pod logs
kubectl logs <pod-name>
kubectl logs -f <pod-name> # Follow log output
# Execute command in pod
kubectl exec -it <pod-name> -- /bin/bash
# Delete pod
kubectl delete pod <pod-name># List all services
kubectl get services
kubectl get svc # Short form
# Get service details
kubectl describe service <service-name>
# Port forwarding
kubectl port-forward svc/<service-name> <local-port>:<service-port>
# List deployments
kubectl get deployments
# Scale deployment
kubectl scale deployment <deployment-name> --replicas=<number>
# Rollout status
kubectl rollout status deployment/<deployment-name>
# Rollback deployment
kubectl rollout undo deployment/<deployment-name>
# List namespaces
kubectl get namespaces
kubectl get ns # Short form
# Create namespace
kubectl create namespace <namespace-name>
# Switch namespace
kubectl config set-context --current --namespace=<namespace-name>
# Delete namespace (and everything in it)
kubectl delete namespace <namespace-name>
Note
Replace text in <> with your actual values.
Add -n <namespace> to any command to specify a namespace.