Build a Kubernetes Pod Autoscaler with Python
Imagine your Python app is suddenly hit with a traffic spike that doubles in seconds. Your server slows, users complain, and you’re manually scaling pods in a panic. That’s the nightmare every DevOps engineer fears. But what if you could build your own Kubernetes Pod Autoscaler in Python—custom, lightweight, and tailored to your app’s unique metrics? No more waiting for generic HPA rules. You get full control, real-time responsiveness, and the ability to scale based on your business logic, not just CPU.
Let’s build one today.
Why Build a Custom Autoscaler in Python?
Kubernetes comes with the built-in Horizontal Pod Autoscaler (HPA), which scales based on CPU or memory usage [3][4]. But HPA has limitations: it can’t scale based on custom metrics like queue length, request latency, or external API response times. For those cases, you need a Custom Pod Autoscaler.
Python is a perfect fit because:
- It’s native to many cloud-native tooling stacks.
- It has excellent Kubernetes client libraries (
kubernetes). - You can write logic that’s easy to read, test, and extend.
In this guide, you’ll build a working Python autoscaler that monitors a custom metric (e.g., number of pending jobs in a queue) and scales your deployment accordingly.
Prerequisites
Before diving in, ensure you have:
- A running Kubernetes cluster (Minikube, EKS, GKE, etc.)
-
kubectlinstalled and configured - Python 3.8+ with
pip - The
kubernetesPython client:pip install kubernetes
You also need the Metrics Server deployed so your autoscaler can read pod metrics if needed [4][5][7]. If you’re using Minikube:
minikube addons enable metrics-server
Step 1: Define Your Scaling Logic
Let’s say your app processes jobs from a queue. You want to scale up when the queue has more than 50 pending jobs, and scale down when it’s under 10.
Here’s the core logic in Python:
import os
import time
from kubernetes import client, config
from kubernetes.client.rest import ApiException
# Load Kubernetes config (in-cluster or local)
config.load_incluster_config() # or load_kube_config() for local
def get_queue_length():
"""
Replace this with your actual logic to fetch queue length.
Example: call an API, read from Redis, etc.
"""
return 75 # Simulated value
def scale_deployment(deployment_name, namespace, replicas):
apps_v1 = client.AppsV1Api()
body = client.V1Deployment(
metadata=client.V1ObjectMeta(name=deployment_name),
spec=client.V1DeploymentSpec(replicas=replicas)
)
try:
apps_v1.patch_namespaced_deployment(
name=deployment_name,
namespace=namespace,
body=body
)
print(f"Scaled {deployment_name} to {replicas} replicas")
except ApiException as e:
print(f"Failed to scale deployment: {e}")
def main():
deployment_name = "my-python-app"
namespace = "default"
min_replicas = 2
max_replicas = 10
while True:
queue_length = get_queue_length()
current_replicas = apps_v1.list_namespaced_deployment(namespace).items[0].spec.replicas
if queue_length > 50 and current_replicas < max_replicas:
scale_deployment(deployment_name, namespace, current_replicas + 1)
elif queue_length < 10 and current_replicas > min_replicas:
scale_deployment(deployment_name, namespace, current_replicas - 1)
time.sleep(10) # Check every 10 seconds
if __name__ == "__main__":
main()
This script:
- Fetches the current queue length
- Checks current replica count
- Scales up or down based on thresholds
- Runs continuously in a loop
You can replace get_queue_length() with real logic—e.g., calling your job queue API or reading from Redis.
Step 2: Package and Deploy as a Kubernetes Pod
Now, turn this script into a container and deploy it as a pod in your cluster.
Create a requirements.txt
kubernetes
Create a Dockerfile
FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY autoscaler.py .
CMD ["python", "autoscaler.py"]
Build and Push the Image
If you’re using Minikube:
eval $(minikube docker-env)
docker build -t my-autoscaler .
For cloud clusters, push to Docker Hub or your registry:
docker build -t my-registry/my-autoscaler .
docker push my-registry/my-autoscaler
Create a Deployment Manifest
apiVersion: apps/v1
kind: Deployment
metadata:
name: python-autoscaler
spec:
replicas: 1
selector:
matchLabels:
app: python-autoscaler
template:
metadata:
labels:
app: python-autoscaler
spec:
containers:
- name: autoscaler
image: my-autoscaler # or your registry path
env:
- name: DEPLOYMENT_NAME
value: "my-python-app"
- name: NAMESPACE
value: "default"
serviceAccountName: autoscaler-sa
Create a Service Account with Permissions
Your autoscaler needs permission to patch deployments:
apiVersion: v1
kind: ServiceAccount
metadata:
name: autoscaler-sa
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: autoscaler-role
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: autoscaler-binding
subjects:
- kind: ServiceAccount
name: autoscaler-sa
namespace: default
roleRef:
kind: Role
name: autoscaler-role
apiGroup: rbac.authorization.k8s.io
Apply everything:
kubectl apply -f serviceaccount.yaml
kubectl apply -f autoscaler-deployment.yaml
Step 3: Test Your Autoscaler
Deploy your main Python app (my-python-app) with resource limits:
resources:
requests:
cpu: "100m"
limits:
cpu: "500m"
Then simulate load. If you’re using a job queue, push 60 jobs. Your autoscaler should detect the spike and scale up. Monitor with:
kubectl get deployments
kubectl get pods -l app=my-python-app
You’ll see replica counts change automatically.
What You Can Do Next
This is a minimal but fully functional autoscaler. Here’s how to level it up:
- Add ** Prometheus metrics** instead of simulated queue length
- Support multi-deployment scaling
- Add alerting when scaling events occur
- Use async/await for better performance
- Integrate with external APIs (e.g., Slack, Datadog)
Ready to Ship This Today?
You just built a custom Kubernetes Pod Autoscaler in Python that scales based on your business logic—not just CPU. No YAML-only HPA, no black-box controllers. You control the thresholds, the metrics, and the logic.
Try it now:
- Copy the code above into
autoscaler.py - Build and deploy the pod
- Simulate load and watch your app scale
If this worked for you, drop a comment with your custom metric logic. Want a version that scales based on Redis queue length or HTTP latency? Let me know—I’ll write the next post.
Your app deserves an autoscaler that thinks like you. Build it. Deploy it. Scale it.
If you found this helpful, consider buying me a coffee ☕ — it keeps these articles coming!
Also check out my AI tools collection: AI 次元世界 — free AI tools for developers.
🛠️ Useful resource: **Content Creator Ultimate Bundle (Save 33%)* — $29.99. Check it out on Gumroad!*
Top comments (0)