I need to scale a set of pods that run queue-based workers. Jobs for workers can run for a long time (hours) and should not get interrupted. The number of pods is based on the length of the worker queue. Scaling would be either using the horizontal autoscaler using custom metrics, or a simple controller that changes the number of replicas.
Problem with either solution is that, when scaling down, there is no control over which pod(s) get terminated. At any given time, most workers are likely working on short running jobs, idle, or (more rare) processing a long running job. I'd like to avoid killing the long running job workers, idle or short running job workers can be terminated without issue.
What would be a way to do this with low complexity? One thing I can think of is to do this based on CPU usage of the pods. Not ideal, but it could be good enough. Another method could be that workers somehow expose a priority indicating whether they are the preferred pod to be deleted. This priority could change every time a worker picks up a new job though.
Eventually all jobs will be short running and this problem will go away, but that is a longer term goal for now.
When you scale down the number of replicas, the system will choose one to remove; there isn't a way to "hint" at which one you'd like it to remove. One thing you can do is you can change the labels on running pods which can affect their membership in the replication controller.
When you autoscale, it creates a HorizontalPodScaler. You can delete it by: kubectl delete hpa NAME-OF-HPA .
I think running this type of workload using a Deployment
or similar, and using a HorizontalPodAutoscaler
for scaling, is the wrong way to go. One way you could go about this is to:
Deployment
) whose task is to periodically create a Kubernetes Job
object.Job
should contain a value for .spec.parallelism
equal to the maximum number of concurrent executions you will accept.Pods
spawned by the Job
then run your processing logic. They should each pull a message from the queue, process it, and then delete it from the queue (in the case of success).Job
must exit with the correct status (success or failure). This ensures that the Job
recognises when the processing has completed, and so will not spin up additional Pods
.Using this method, .spec.parallelism
controls the autoscaling based on how much work there is to be done, and scale-down is an automatic benefit of using a Job
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With