kubernetes client-go Quantity explanation

What is quantity? quantity is a string representation of some countable resources, comprised by a number, either an int64 or a bigint value, and a unit suffix. for example 100Mi, 1000m, 100. The resources can be cpu, gpu, memory, pods, ephemeral-storage, etc, we can get the full resources list from the nodes.Status.Capacity.

In this article, we mainly talk about how to use quantity in client-go library. First, let’s see how Quantity is represented in golang:

type Quantity struct {
     i int64Amount
     d infDecAmount
     // cache String() result
     s string
     // string, available values are: DecimalSI, BinarySI, DecimalExponent
     Format
}

This struct has a s field, used for caching String() method return value. the Format field indicates the quantity number type, may be decimal, binary and decimal exponent. the int64Amount and infDecAmount both have a value field and a scale field. The value field stores the corresponding number without any unit suffix, and the scale field stores the multiplication times / shift bits number to convert the origin value to a unit-less form.

int64Amount represents a fixed precision numerator and arbitrary scale exponent. It is faster than operations on inf.Dec for values that can be represented as int64.

type int64Amount struct {
    value int64
    scale Scale
}

type infDecAmount struct {
    *inf.Dec
}

infDecAmount implements common operations over an inf.Dec that are specific to the quantity representation.

type Dec struct {
    unscaled big.Int
    scale    Scale
}

Now, let’s create some quantity values using different methods, and print their number value and string representation.

package main

import (
    "fmt"
    "gopkg.in/inf.v0"
    "k8s.io/apimachinery/pkg/api/resource"
)

func main() {
    q1, _ := resource.ParseQuantity("1100000m")
    fmt.Println(q1.Value(), q1.String(), q1.Format)
    q11, _ := resource.ParseQuantity("11.1111k")
    fmt.Println(q11.Value(), q11.String(), q11.Format)

    q2 := resource.NewMilliQuantity(1100001, resource.BinarySI)
    fmt.Println(q2.Value(), q2.String(), q2.Format)

    q3 := resource.NewQuantity(1024, resource.BinarySI)
    fmt.Println(q3.Value(), q3.String())

    // Flowing two functions seldom used in kubernetes

    q4 := resource.NewDecimalQuantity(*inf.NewDec(103000, -3), resource.DecimalExponent)
    fmt.Println(q4.Value(), q4.String())

    q5 := resource.NewScaledQuantity(1100, -3)
    fmt.Println(q5.Value(), q5.String(), q5.Format)
}

By running this brief program, we can get the following results:

1100 1100 DecimalSI
11112 11111100m DecimalSI
1101 1100001m BinarySI
1024 1Ki
103000000 103e6
2 1100m DecimalSI

There a few notable points:

  • we can see the Value() of 1100000m is 1100, because the meaning of m is milli, so it is divided by 1000
  • the String() value of 1100000m is also 1100
  • the String() value will use a best unit automatically, the value of 11000000m will be 11k
  • the milli value of 1100001’s Value() is 1101, it is rounded up
  • the exponent value 103000000’s String() representation is 103e6, here the “e6” can be regarded as the unit

For all supported units, corresponding scale value, and formats, please refer the following tables.

Unit Scale Format
Ki 210 BinarySI
Mi 220 BinarySI
Gi 230 BinarySI
Ti 240 BinarySI
Pi 250 BinarySI
Ei 260 BinarySI
n 10-9 DecimalSI
u 10-6 DecimalSI
m 10-3 DecimalSI
“” empty 100 DecimalSI
k 103 DecimalSI
M 106 DecimalSI
G 109 DecimalSI
T 1012 DecimalSI
P 1015 DecimalSI
E 1018 DecimalSI
Ex or ex, exponent format, e.g. e3 10x DecimalExponent

The last, NewDecimalQuantity() and NewScaledQuantity() functions are seldom used in kubernetnes. For cpu resource, it is reported as milli value, and for memory resource, it reported as a byte (unit-less) value, both cpu and memory resource are reported by kubelet. If you want to use the quantities, it is best to use the form as they reported to make the value more precise.

Note: client-go version is v0.29.1.

Leave a Reply

Your email address will not be published. Required fields are marked *