This KEDA K3s autoscaling tutorial shows you how to scale two real workloads. One worker that reacts to RabbitMQ queue depth, and one worker that reacts to a Prometheus metric. You will learn to create both ScaledObjects, generate real load, and check the scaling decisions step by step.
Event-Driven Autoscaling on K3s with KEDA, RabbitMQ, and Prometheus
Table of Contents
- What Is KEDA and Why Use It on K3s
- Prerequisites for KEDA K3s Autoscaling
- Step 1: Install K3s
- Step 2: Install Helm
- Step 3: Install KEDA on K3s
- Step 4: Deploy RabbitMQ on K3s
- Step 5: Deploy the RabbitMQ Worker and Create the Queue
- Step 6: Create the RabbitMQ ScaledObject
- Step 7: Install Prometheus with kube-prometheus-stack Chart
- Step 8: Deploy HTTP Worker That Exposes Prometheus Metrics
- Step 9: Create the Prometheus-Driven ScaledObject
- Step 10: Test the Autoscaler with Real Load
- Step 11: Verify the Scaling Decisions
- Conclusion

What Is KEDA and Why Use It on K3s
KEDA (Kubernetes Event-Driven Autoscaling) adds extra triggers to the normal Kubernetes Horizontal Pod Autoscaler (HPA). Instead of scaling only on CPU or memory, KEDA can scale on a queue length, a message rate, or any Prometheus query. Also, it can scale a deployment down to zero pods when there is no work, which the normal HPA cannot do.
K3s is a lightweight Kubernetes distribution. It runs easily on a single VPS or a small home lab. Since K3s is still full Kubernetes, every standard Helm chart and every KEDA object works on it with no changes.
For real workloads, it is recommended to use a reliable dedicated server. KEDA needs to check signals and start pods fast, so steady CPU and network performance matter for smooth autoscaling.
Prerequisites for KEDA K3s Autoscaling
Before you start this KEDA K3s autoscaling tutorial, make sure you have:
- A Linux server running Ubuntu 22.04 or newer with at least 4 GB RAM and 2 CPU cores, root or sudo access.
- An open outbound internet connection to download K3s, Helm charts, and container images.
- Basic comfort with the terminal and
kubectl.
Step 1: Install K3s
First, install the latest stable K3s release with the official install script:
Wait about 30 to 60 seconds, then check that the node is ready:
You should see one node with status Ready. Now set up kubectl so you don't need sudo k3s kubectl every time:
Confirm it works correctly by checking its version:
Step 2: Install Helm
Helm is the package manager we will use for KEDA and Prometheus. Install the latest stable Helm 3 with the official script:
Step 3: Install KEDA on K3s
This is the core step of the KEDA K3s autoscaling tutorial. You must add the official KEDA Helm repository and install the latest stable chart, which deploys KEDA 2.20.2:
Check that KEDA is running:
You should see three pods, including keda-operator, keda-operator-metrics-apiserver, and keda-admission-webhooks all in Running state. And CRDs such as scaledobjects.keda.sh and triggerauthentications.keda.sh.
This confirms KEDA is installed correctly before we connect any real signal.
Step 4: Deploy RabbitMQ on K3s
We will run RabbitMQ with the management plugin enabled, using a plain Deployment so you can see every setting. First, create a namespace and a secret:
Then, create the RabbitMQ manifest file:
Apply the file and check the status:
Note: If a queue ever gets stuck or messages will not deliver, our RabbitMQ error-fixing guide covers the most common problems.
Step 5: Deploy the RabbitMQ Worker and Create the Queue
The worker is the deployment that KEDA will scale. Here we use a small busybox loop as a stand-in worker so you can focus on the scaling behavior:
Apply it with the command below:
Then, you should create the queue named orders. Exec into the RabbitMQ pod and use rabbitmqadmin, the command-line tool that ships with the management plugin:
Step 6: Create the RabbitMQ ScaledObject
At this point, you should create a TriggerAuthentication so KEDA can log in to RabbitMQ using the secret you already made:
Apply the file with:
Now you can create the ScaledObject. It watches the orders queue and scales the worker between 0 and 15 replicas, targeting 5 messages per pod:
pollingInterval: 10 means KEDA checks the queue every 10 seconds.
cooldownPeriod: 60 means the worker only scales down to zero after the queue stays empty for 60 straight seconds. This stops short quiet moments from shutting the worker down too soon.
Apply and check the RabbitMQ autoscaler:
Step 7: Install Prometheus with kube-prometheus-stack Chart
For the second worker, we need a real Prometheus server to query. Install the community kube-prometheus-stack, which bundles Prometheus, the Prometheus Operator, and Grafana:
Wait for the pods to become ready, then confirm the Prometheus service name:
You should see a service called kube-prometheus-stack-prometheus listening on port 9090. KEDA's Prometheus scaler will query this service directly.
Step 8: Deploy HTTP Worker That Exposes Prometheus Metrics
Now you can create a small HTTP app that counts incoming requests and exposes that count on a /metrics endpoint, which Prometheus will scrape. We store the app code in a ConfigMap.
Apply and check the HTTP worker status:
Next, create a ServiceMonitor so Prometheus scrapes this service.
The label release: kube-prometheus-stack must match your Helm release name. That's how the chart's Prometheus knows to pick up this ServiceMonitor by default.
Step 9: Create the Prometheus-Driven ScaledObject
This part of the KEDA K3s autoscaling tutorial connects KEDA directly to the Prometheus query language instead of a queue. The ScaledObject below scales the HTTP worker between 1 and 10 replicas based on the request rate:
threshold: "5" means KEDA aims for about 5 requests per second per pod.
If the rate goes above that, KEDA adds more pods. If it drops, KEDA removes pods, down to the minimum of minReplicaCount: 1.
Apply and check with:
Step 10: Test the Autoscaler with Real Load
Now it's time to see KEDA in action. We'll send real traffic to both workers: messages to the RabbitMQ queue, and requests to the HTTP worker. This gives KEDA a signal to react to, so we can watch it scale the pods up.
Load the RabbitMQ queue: Exec back into the RabbitMQ pod and publish 300 test messages to the orders queue:
Load the HTTP worker: Run a temporary pod that hits the HTTP worker in a loop to raise the request rate:
Let it run for a minute or two, then press Ctrl+C to stop.
Step 11: Verify the Scaling Decisions
This final step of the KEDA K3s autoscaling tutorial confirms both workers actually reacted. Check the KEDA-managed HPA objects, which KEDA creates automatically for every ScaledObject:
Look at the current replica counts directly:
Check KEDA's own view of each trigger, including whether it currently sees the trigger as active:
In the describe output, look for the Conditions section. Active: True means KEDA detected load and told the HPA to scale up. Active: False after the cooldown period means it will scale the RabbitMQ worker back toward zero. Also, you can watch it live:
- When the queue is empty for 60 seconds, the RabbitMQ worker scales back down to 0 pods.
- When the request rate drops for 90 seconds, the HTTP worker scales back down to 1 pod, its set minimum.
Conclusion
At this point, you have a working KEDA K3s autoscaling tutorial with two real signals, not just a CPU demo. One trigger scales on RabbitMQ queue depth, the other on a Prometheus query. Both scale real deployments up and down automatically.
This setup works the same way on any K3s cluster, lab or production. You don't need a public cloud provider's autoscaling service to make it work.
We hope you enjoy this guide. For more detailed information, you can check the KEDA official documentation.