<p>Helo i am running a .NET application in Azure Kubernetes Services as a 3 pod cluster (1 pod per node).
I am trying to understand how can i make my cluster elastic depending on load ?
How can i configure the <code>deployment.yaml</code> so that after a certain <code>%</code> of the cpu utilization and/or <code>%</code> of memory per pod it spawns another pod? The same thing when load decreases, how do i shut down instances.</p>
<p>Is there any guide/tutorial to set this up based on percentage (ideally) ?</p>

Bercovici Adrian
<p>The basic feature you need to use is called <code>HorizontalPodAutoscaler</code> or for short <code>HPA</code>. There you can configure cpu or memory limits and if the limit is exceeded, the pod replica number will be increased. E.g. from <a href="https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/" rel="nofollow noreferrer">this walkthrough</a>:</p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: php-apache
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: php-apache
  minReplicas: 1
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 50
</code></pre>
<p>This will scale out the php-apache deployment, as soon as the pods cpu utilization is greater than 50 %. Be aware that calculating the resource utilization and the resulting number of replicas is not as intuitive, as it might seam. Also see <a href="https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/#algorithm-details" rel="nofollow noreferrer">docs</a> (the whole page should be quite interesting too). You can also combine criteria for scale out.</p>
<p>There are also addons that help you scale based on other parameters, like the number of messages in a queue. Check out <a href="https://www.keda.sh" rel="nofollow noreferrer">keda</a>, they provide different scalers, like RabbitMQ, Kafka, AWS CloudWatch, Azure Monitor, etc.</p>
<p>And since you wrote</p>
<blockquote>
<p>1 pod per node</p>
</blockquote>
<p>you might be running a <code>DaemonSet</code>. In that case your only option to scale out would be to add additional nodes, since with daemonsets there is always exactly one pod per node. If that's the case you could think about using a <code>Deployment</code> combined with a <code>PodAntiAffinity</code> instead, see <a href="https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/" rel="nofollow noreferrer">docs</a>. By that you can configure pods to preferably run on nodes where pods of the same deployment are not running yet, e.g.:</p>
<pre class="lang-yaml prettyprint-override"><code>[...]
spec:
  affinity:
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: security
              operator: In
              values:
              - S2
          topologyKey: topology.kubernetes.io/zone
[...]
</code></pre>
<p>From <a href="https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#an-example-of-a-pod-that-uses-pod-affinity" rel="nofollow noreferrer">docs</a>:</p>
<blockquote>
<p>The anti-affinity rule says that the scheduler should try to avoid scheduling the Pod onto a node that is in the same zone as one or more Pods with the label security=S2. More precisely, the scheduler should try to avoid placing the Pod on a node that has the topology.kubernetes.io/zone=R label if there are other nodes in the same zone currently running Pods with the Security=S2 Pod label.</p>
</blockquote>
<p>That would make scale out more flexible as it is with a daemonset, yet you have a similar effect of pods being equally distributed through out the cluster.</p>
<p>If you want/need to stick to a daemonset you can check out the <a href="https://learn.microsoft.com/en-us/learn/modules/aks-cluster-autoscaling/" rel="nofollow noreferrer">AKS Cluster Autoscaler</a>, that can be used to automatically add/remove additional nodes from your cluster, based on resource consumption.</p>
