Scaligator is an intelligent Kubernetes Horizontal Pod Autoscaler (HPA) alternative, built in Rust for speed, resilience, and extensibility. It dynamically scales workloads based on custom Prometheus metrics, time-based rules, and business-aware logic going beyond vanilla Kubernetes autoscaling.
-
π More than CPU/Memory: Scale based on Prometheus metrics or any custom metric.
-
π Time-based scaling: Automatically scale down non-critical environments at night.
-
β‘ Rust Performance: Lightweight, blazing fast, and built with safety in mind.
-
π Production-ready: Config-driven, highly observable, and Kubernetes-native.
-
π HTTP Alerts: React to external triggers for proactive scaling.
-
β Kubernetes controller for scaling Deployments
-
β Configurable via Config file or Environment variables
-
β Prometheus integration for metric-driven scaling
-
β REST endpoint for handling alert-based triggers
-
β Graceful shutdown & robust logging
- Clone the repo and build the image:
git clone https://github.com/p-r-a-v-i-n/scaligator.git
cd scaligator
docker build -t scaligator:latest .
- Load the image into your local cluster (kind/minikube):
kind load docker-image scaligator:latest
# or
minikube image load scaligator:latest
- Deploy to Kubernetes:
kubectl apply -f prometheus-rbac.yaml
kubectl apply -f scaligator-serviceaccount.yaml
kubectl apply -f scaligator-clusterrole.yaml
kubectl apply -f scaligator-clusterrolebinding.yaml
kubectl apply -f scaligator-deployment.yaml
kubectl apply -f scaligator-service.yaml
(Optionally integrate with Prometheus & Alertmanager using scaligator-rules.yaml and scaligator-alertmanager.yaml)
- Scaligator supports:
- Environment variables (override config file)
- Config file (config.toml)
- Kubernetes ConfigMap
- Example config:
prometheus_url = "http://prometheus-operated.monitoring:9090"
watch_namespaces = ["default", "scaling", "dev"]
scale_up_cpu_threshold = 0.7
scale_down_cpu_threshold = 0.2
disable_dev_after = "20:00"
enable_dev_after = "08:00"
- Load via ConfigMap:
kubectl create configmap scaligator-config \
--from-file=config.toml=./config/config.toml
Here are a few examples of how to run Scaligator with different configurations.
- Using a Configuration File You can run Scaligator with a custom configuration file by using the --config (or -c) flag.
- Create a Config.toml file:
prometheus_url = "[http://prometheus-operated.monitoring:9090](http://prometheus-operated.monitoring:9090)"
watch_namespaces = "default,scaling,dev"
scale_up_cpu_threshold = 0.75
scale_down_cpu_threshold = 0.25
reconcile_interval = 60
- Run Scaligator with the config file:
cargo run -- -c /path/to/your/Config.toml
- Using Environment Variables Scaligator can also be configured using environment variables with the SCALIGATOR_ prefix. This is especially useful in CI/CD pipelines or Kubernetes deployments.
- Set the environment variables:
export SCALIGATOR_PROMETHEUS_URL="[http://prometheus.monitoring.svc.cluster.local:9090](http://prometheus.monitoring.svc.cluster.local:9090)"
export SCALIGATOR_WATCH_NAMESPACES="production,staging"
export SCALIGATOR_SCALE_UP_CPU_THRESHOLD="0.8"
export SCALIGATOR_SCALE_DOWN_CPU_THRESHOLD="0.3"
- Run Scaligator:
cargo run
- Running with Docker You can run Scaligator using the pre-built Docker image. This is the recommended way to run Scaligator in a production environment.
- Build the Docker image:
docker build -t scaligator:latest .
- Run the Docker container with environment variables:
docker run \
-e SCALIGATOR_PROMETHEUS_URL="[http://prometheus.monitoring.svc.cluster.local:9090](http://prometheus.monitoring.svc.cluster.local:9090)" \
-e SCALIGATOR_WATCH_NAMESPACES="default" \
scaligator:latest
- Update your prometheus.yml:
scrape_configs:
- job_name: scaligator
static_configs:
- targets: ["scaligator.default.svc.cluster.local:8080"]
- Apply scaling rules:
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: scaligator-cpu-rules
namespace: monitoring
spec:
groups:
- name: scaligator.rules
rules:
- alert: HighCPUUsage
expr: |
rate(container_cpu_usage_seconds_total{namespace=~"default|scaling|dev"}[2m]) > 0.7
for: 2m
labels:
severity: warning
annotations:
summary: "High CPU usage detected"
description: "Pod {{ $labels.pod }} in {{ $labels.namespace }} using > 70% CPU"
kubectl apply -f scaligator-rules.yaml
- Forward alerts to Scaligator:
apiVersion: monitoring.coreos.com/v1alpha1
kind: AlertmanagerConfig
metadata:
name: scaligator-alerts
namespace: monitoring
spec:
route:
receiver: scaligator
receivers:
- name: scaligator
webhookConfigs:
- url: "http://scaligator.default.svc.cluster.local:8080/alerts"
kubectl apply -f scaligator-alertmanager.yaml
- Scaligator supports two complementary modes:
- Runs a reconciliation loop that queries Prometheus for CPU/memory usage.
- Adjusts Deployment replicas automatically based on thresholds.
- Example logs:
INFO scaligator::controller: π Reconciling namespace: "default" INFO scaligator::scaler: πΌ Scaling up myapp to 3 replicas (CPU: 0.82) INFO scaligator::scaler: π½ Scaling down myapp to 1 replicas (CPU: 0.15) INFO scaligator::scaler: π’ No scaling needed for myapp (CPU: 0.45)
- Exposes a webhook for Alertmanager.
- External alerts can trigger immediate scale actions.
- Example:
INFO scaligator::alerts: π’ Global alert status: firing INFO scaligator::alerts: π’ Individual alert status: firing INFO scaligator::alerts: π¨ Alert: pod=myapp-7d9c8c9c4f-abcde, ns=dev, cpu=0.92
- Check logs:
kubectl logs -l app=scaligator
- Expected output:
π Starting scaligator...
INFO scaligator:π§ Loading application config...
INFO scaligator:β
Config loaded: AppConfig { prometheus_url: "http://prometheus-operated.monitoring:9090", watch_namespaces: "default,scaling,dev", scale_up_cpu_threshold: 0.7, scale_down_cpu_threshold: 0.2, reconcile_interval: 30 }
INFO scaligator:π§ Inferring Kubernetes config...
INFO scaligator:β
Kubernetes client initialized
INFO scaligator:π Starting HTTP server on 0.0.0.0:8080
INFO scaligator::controller:π Controller starting reconciliation loop. Checking every 30s.
INFO scaligator::controller:π Reconciling namespace: "default"
INFO scaligator::controller:π Reconciling namespace: "scaling"
INFO scaligator::controller:π Reconciling namespace: "dev"
INFO scaligator::controller:β
Reconciliation complete. Sleeping for 30s.
- 403 Forbidden on deployments β RBAC not applied β re-apply scaligator-clusterrole.yaml + scaligator-clusterrolebinding.yaml
- Connection refused to Prometheus β update prometheus_url in config to point to your running Prometheus service
- No scaling happening β check kubectl get events for denied patch operations
- π Rust-based: tiny binary, low overhead, very fast
- β‘ Prometheus-native: simple queries + alert webhook, no complex CRDs
- β° Time-based scaling: scale down dev at night, scale up in morning (KEDA doesnβt support this out-of-the-box)
- π¨ Alert-based webhook scaling: direct integration with Alertmanager
- πͺΆ Config-driven & minimal: easier to reason about vs KEDAβs multiple CRDs
- π Potential future: vertical scaling (planned for Kubernetes β₯1.33, KEDA doesnβt cover this yet)
-
π¦ Written in Rust β great for learning systems programming in cloud-native environments
-
βΈοΈ Deep dive into Kubernetes controllers and autoscaling logic
-
π Work on real-world scaling challenges in production scenarios
-
π Active community β shaping the future of autoscaling beyond HPA
PRs welcome! Please open an issue first to discuss your ideas.