Helm template float arithmetic

Viewed 2862
$ helm version
version.BuildInfo{Version:"v3.3.0", GitCommit:"8a4aeec08d67a7b84472007529e8097ec3742105", GitTreeState:"dirty", GoVersion:"go1.14.6"}

So I have my template:

  minAvailable: {{ mul .Values.autoscaling.minReplicas 0.75 }}

values.yaml:

autoscaling:
  minReplicas: 3

I would have expected a rendered output of 2.25, but I get 0 (3 * 0 because 0.75 gets floored...)

I've tried things like

  minAvailable: {{ mul (float .Values.autoscaling.minReplicas) 0.75 }}

Ultimately I'm going to floor the value to get back to an int...

  minAvailable: {{ floor ( mul .Values.autoscaling.minReplicas 0.75 ) }}

But I just don't understand why I can't seem to do simple float arithmetic


Other things I've tried

  minAvailable: {{ float64 .Values.autoscaling.minReplicas }} 
  minAvailable: {{ float64 .Values.autoscaling.minReplicas | toString }} 

nothing produces a float number....

I've even tried doing this in values.yaml

autoscaling:
  minReplicas: 3.0
3 Answers

These arithmetic functions aren't part of the core Go text/template language. They come from a package of useful extensions called Sprig that Helm includes. In particular, the documentation for its Math Functions states at the top of the page

All math functions operate on int64 values unless specified otherwise.

Instead of trying to calculate floating-point x * 0.75, you could calculate integer x * 3 / 4. Factor this as (x * 3) / 4 and you can do this as reasonably precise integer arithmetic:

minAvailable: {{ div (mul .Values.autoscaling.minReplicas 3) 4 }}

Helm and its templates support the default Go text/template functions and the function provided by the Sprig extension. Since Sprig version 3.2 it also supports Float Math Functions like addf, subf, mulf, divf, etc. In your case you would just need:

  minAvailable: {{ mulf .Values.autoscaling.minReplicas 0.75 }}

Pod Disruption Budgets actually take percentages...

so can do

  minAvailable: "66%" # 2/3

or

  minAvailable: "75%" # 3/4

From the docs:

if you have 7 Pods and you set minAvailable to "50%", it's not immediately obvious whether that means 3 Pods or 4 Pods must be available. Kubernetes rounds up to the nearest integer, so in this case, 4 Pods must be available.

So essentially, 66% of 3 is 1.98 so will be rounded up to 2

Related