cpu / memory amount not populated in core.v1.Pod.PodSpec

6/7/2018

Using the following code:

func GetPods(clientset *kubernetes.Clientset, name, namespace string) ([]corev1.Pod, error) {
    list, err := clientset.CoreV1().Pods(namespace).List(metav1.ListOptions{
        LabelSelector: fmt.Sprintf("app=%s", name),
    })
    if err != nil {
        return nil, err
    }
return list.Items, nil
}

And then dump the results into yaml using gopkg.in/yaml.v2, and here's the yaml clause that describes container resource:

resources:
  limits:
    cpu:
      format: DecimalSI
    memory:
      format: BinarySI
  requests:
    cpu:
      format: DecimalSI
    memory:
      format: BinarySI

Which includes none of the actual resource amount that I'm actually interested in, which should look like this using kubectl get pod xxx -o yaml:

resources:
  limits:
    cpu: "4"
    memory: 8Gi
  requests:
    cpu: 200m
    memory: 100Mi

So how can I properly get the pod spec yaml, that includes all the resource info, using the golang library? What did I do wrong in the above process?

Update

I noticed the Pod.String and Pod.Marshal methods.

The pod.String() output seems to be a formatted string of the core.v1.Pod instance, this isn't much use to me since it's not serialized.

Pod.Marshal() gives a byte array, contains lots of gibberish when printed. The method itself is one of those undocumented methods inside k8s.io/api/core/v1/generated.pb.go, I really don't know what to do with its output:

func (p *PodResolver) SpecYaml() (string, error) {
    bs, err := p.pod.Marshal()
    fmt.Println(string(bs))
    return string(bs), err
}
// prints a whole lot of gibberish like cpu\x12\x03\n\x014\n\x0f\n\x06memory\x12\x05\n\x038Gi\x12\r\n\x03cpu\x12\x06\n\x04200m\x12\x11\n\x06memory\x12\a\n\x05100MiJ-\n\n
-- timfeirg
go
kubernetes

3 Answers

6/9/2018

So instead of using yaml.Marshal, I should use json.Marshal, that'd give me all the information including cpu and memory quantity.

As mentioned by @user2326871, Quantity struct is missing yaml tags.

What a weird library, and all its weird methods, I was so sure that kubectl must be using the same Pod struct to generate all its yaml outputs.

-- timfeirg
Source: StackOverflow

9/3/2019

Try this out:

func GetPods(clientset *kubernetes.Clientset, name, namespace string) ([]corev1.Pod, error) {
list, err := clientset.CoreV1().Pods(namespace).List(metav1.ListOptions{
    LabelSelector: fmt.Sprintf("app=%s", name),
})
if err != nil {
    return nil, err
}
for _, l := range list.Items {
    fmt.Println("Request CPU ==> ", l.Spec.Containers[0].Resources.Requests.Cpu(), " Request Memory ==> ", l.Spec.Containers[0].Resources.Requests.Memory())
    fmt.Println("Limit CPU ==> ", l.Spec.Containers[0].Resources.Limits.Cpu(), " Limit Memory ==> ", l.Spec.Containers[0].Resources.Limits.Memory()) } return list.Items, nil }

Keep in mind that every time something becomes complex it's time to choose another path.

k8s APIs are not so well documented as could be, in this case my suggestion is open up the debug console and navigate through component trees which will certainly indicate which interface use and it's structure.

-- Caue Augusto dos Santos
Source: StackOverflow

6/7/2018

You can simply call the String() method on the quantity fields which would return something like "100m"

There doesnt seem to be any yaml tags on the Quantity type.

-- user2326871
Source: StackOverflow