There are two ways of setting up a new HorizontalPodAutoscaler
object:
- Declarative approach described here:
Creating the autoscaler declaratively
Instead of using kubectl autoscale
command to create a HorizontalPodAutoscaler imperatively we can use the following file to create it declaratively:
application/hpa/php-apache.yaml

apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: php-apache
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: php-apache
minReplicas: 1
maxReplicas: 10
targetCPUUtilizationPercentage: 50
We will create the autoscaler by executing the following command:
kubectl create -f https://k8s.io/examples/application/hpa/php-apache.yaml
Imperative approach i.e. by invoking kubectl autoscale
command:
kubectl autoscale deployment nginx-deployment --cpu-percent=50 --min=1 --max=5
The first approach doesn't leave much room for further interpretation. The syntax is strictly specified and you cannot do much about it. As you can see both kind
and name
of our scaling target should be specified and although your pseudo code may seem like an interesting proposal, it have no chances to work. According to the specification name
field is a map/dictionary and a list simply cannot be used in this context.
When it comes to the imperative approach, actually you can automate it by using a fairly simple bash one-liner and make your life a bit easier. If you have... let's say 50 different deployments and you want to autoscale
all of them, it can save you a lot of time.
For the sake of simplicity I've created only 3 different deployments:
$ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment-1 3/3 3 3 4m3s
nginx-deployment-2 3/3 3 3 3m58s
nginx-deployment-3 3/3 3 3 3m54s
In order not to create hpa one by one manually, I used the following one-liner bash script:
$ for i in $(kubectl get deployments -o jsonpath='{.items[*].metadata.name}');do kubectl autoscale deployment $i --cpu-percent=50 --min=1 --max=3; done
the result of which is:
horizontalpodautoscaler.autoscaling/nginx-deployment-1 autoscaled
horizontalpodautoscaler.autoscaling/nginx-deployment-2 autoscaled
horizontalpodautoscaler.autoscaling/nginx-deployment-3 autoscaled
Command:
kubectl get deployments -o jsonpath='{.items[*].metadata.name}'
returns only the names of your deployments, so they can be easily iterated through a for
loop. Notice that we still have 1-to-1 relation here. To one Deployment
corresponds exactly one HorizontalPodAutoscaler
object. If you additionally need to deal with different namespaces
, the script can be further expanded.
Going back to your specific requirement, the question arises as to the legitimacy of such a solution. Although it may seem quite tempting to manage all your Deployments
by one single HorizontalPodAutoscaler
object (less work in the very beginning), if you take a closer look at all potential downsides of such approach, you would probably change your mind quickly. First of all, such solution isn't very scalable. In fact it is not scalable at all. Just imagine that for some reason you want to change the targetCPUUtilizationPercentage
for a single Deployment
object. Well... you have a problem. It is managed by one global autoscaler and you need to quickly redesign your environment and create a separate hpa. So 1-to-1 relation between HorizontalPodAutoscaler
and Deployment
/ReplicationController
/ReplicaSet
makes a perfect sense. What you usually need is more granular level of control rather than possibility to manage everything by one huge general object.