The worker kladde-worker has little to do: after the nightly fetch, and when someone uploads a contact list. The rest of the time it waits on an empty queue and occupies
a pod with a memory and CPU request. In lesson 3.5.7 you solved the same problem on Container Apps: the worker grows with the length of the queue and shrinks to zero.
This lesson shows what that looks like on Kubernetes. The question: How does a deployment scale by the length of a Service Bus queue, down to zero, without a key standing anywhere?
What KEDA is on Container Apps, what pollingInterval, cooldownPeriod and messageCount mean, and how a worker shuts down cleanly is covered in lesson 3.5.7 and is not repeated here. This lesson is about
what Kubernetes does differently: objects instead of Bicep fields, a way of its own to sign in, and a neighbor that KEDA does not get along with.
The Horizontal Pod Autoscaler
Kubernetes comes with a scaling mechanism of its own: the Horizontal Pod Autoscaler (HPA). It is a control loop and works out, at the pace of the control plane (every 15 seconds by default), how many replicas a deployment needs. The core of the calculation:
desired replicas = ceil( current replicas × current metric value / target value )
Where the metric value comes from is the decisive question:
| Kind of metric | Source | Example |
|---|---|---|
| Resource value per pod | the interface metrics.k8s.io, usually from the Metrics Server |
CPU utilization as a percentage of the container's request (requests) |
| Custom value per pod | custom.metrics.k8s.io |
Requests per second per pod |
| Value of an object or from outside | custom.metrics.k8s.io, external.metrics.k8s.io |
the length of a queue |
For the web part of the Kladde, CPU utilization is a good metric: more requests means more CPU. For the worker it is a poor one. A worker that waits for messages needs no CPU, and one that has 5,000 messages in the queue can at the same time use next to none while it waits for a database. What really describes it is the queue: a value from outside, which the HPA can read only through an interface for external metrics. That takes something that asks the queue and delivers the answer to that interface.
From Kubernetes 1.37 on, an HPA can go down to zero replicas for object and external metrics (minReplicas: 0; beta, on by default). It never can for resource values, because they can only be
measured on running pods. The HPA alone still does not get you anywhere, because it does not read the queue itself.