<p>I've created a GKE test cluster on Google Cloud. It has 3 nodes with 2 vCPUs / 8 GB RAM. I've deployed two java apps on it</p>

<p>Here's the yaml file:</p>

<pre><code>apiVersion: apps/v1            
kind: Deployment
metadata:                    
  name: myapi           
spec:
  selector:                                                                          
    matchLabels:
      app: myapi
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: myapi
    spec:
      containers:
      - image: eu.gcr.io/myproject/my-api:latest
        name: myapi
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
          name: myapi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myfrontend
spec:
  selector:
    matchLabels:
      app: myfrontend
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: myfrontend
    spec:
      containers:
      - image: eu.gcr.io/myproject/my-frontend:latest
        name: myfrontend
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
          name: myfrontend
---
</code></pre>

<p>Then I wanted to add a HPA with the following details:</p>

<pre><code>apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  name: myfrontend
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: myfrontend
  minReplicas: 2
  maxReplicas: 5
  targetCPUUtilizationPercentage: 50
---
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  name: myapi
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: myapi
  minReplicas: 2
  maxReplicas: 4
  targetCPUUtilizationPercentage: 80
---
</code></pre>

<p>If I check kubectl top pods it shows some really weird metrics:</p>

<pre><code>NAME                         CPU(cores)   MEMORY(bytes)   
myapi-6fcdb94fd9-m5sh7      194m         1074Mi          
myapi-6fcdb94fd9-sptbb      193m         1066Mi          
myapi-6fcdb94fd9-x6kmf      200m         1108Mi          
myapi-6fcdb94fd9-zzwmq      203m         1074Mi          
myfrontend-788d48f456-7hxvd   0m           111Mi           
myfrontend-788d48f456-hlfrn   0m           113Mi   
</code></pre>

<p>HPA info:</p>

<pre><code>NAME        REFERENCE              TARGETS    MINPODS   MAXPODS   REPLICAS   AGE
myapi      Deployment/myapi      196%/80%   2         4         4          32m
myfrontend   Deployment/myfrontend   0%/50%     2         5         2          32m
</code></pre>

<p>But If I check uptime on one of the nodes it shows a less lower value:</p>

<pre><code>[myapi@myapi-6fcdb94fd9-sptbb /opt/]$ uptime
 09:49:58 up 47 min,  0 users,  load average: 0.48, 0.64, 1.23
</code></pre>

<p>Any idea why it shows a completely different thing. Why hpa shows 200% of current CPU utilization? And because of this it uses the maximum replicas in idle, too. Any idea?</p>

Roberto
<p>The <code>targetCPUUtilizationPercentage</code> of the HPA is a percentage of the <a href="https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/" rel="nofollow noreferrer">CPU requests</a> of the containers of the target Pods. If you don't specify any CPU requests in your Pod specifications, the HPA can't do its calculations.</p>

<p>In your case it seems that the HPA assumes <code>100m</code> as the CPU requests (or perhaps you have a LimitRange that sets the default CPU request to <code>100m</code>). The current usage of your Pods is about <code>200m</code> and that's why the HPA displays a utilisation of about 200%.</p>

<p>To set up the HPA correctly, you need to specify CPU requests for your Pods. Something like:</p>

<pre class="lang-yaml prettyprint-override"><code>      containers:
      - image: eu.gcr.io/myproject/my-api:latest
        name: myapi
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
          name: myapi
        resources:
          requests:
            cpu: 500m
</code></pre>

<p>Or whatever value your Pods require. If you set the <code>targetCPUUtilizationPercentage</code> to 80, the HPA will trigger an upscale operation at <code>400m</code> usage, because 80% of <code>500m</code> is <code>400m</code>.</p>

<hr>

<p>Besides that, you use an outdated version of HorizontalPodAutoscaler:</p>

<ul>
<li>Your version: <a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#horizontalpodautoscaler-v1-autoscaling" rel="nofollow noreferrer">v1</a></li>
<li>Newest version: <a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#horizontalpodautoscaler-v2beta2-autoscaling" rel="nofollow noreferrer">v2beta2</a></li>
</ul>

<p>With the v2beta2 version, the specification looks a bit different. Something like:</p>

<pre class="lang-yaml prettyprint-override"><code>apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: myapi
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: myapi
  minReplicas: 2
  maxReplicas: 4
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 80
</code></pre>

<p>See <a href="https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/" rel="nofollow noreferrer">examples</a>.</p>

<p>However, the CPU utilisation mechanism described above still applies.</p>
