How to retrieve all the data from kubectl describe pods <namespace> from an in-cluster client-go api call

9/10/2019

I need to grab some pod information which will be used for some unit tests which will be run in-cluster. I need all the information which kubectl describe po gives but from an in cluster api call.

I have some working code which makes an api call to apis/metrics.k8s.io/v1beta1/pods, and have installed the metrics-server on minikube for testing which is all working and gives me output like this:

Namespace: kube-system
Pod name: heapster-rgnlj
SelfLink: /apis/metrics.k8s.io/v1beta1/namespaces/kube-system/pods/heapster-rgnlj
CreationTimestamp: 2019-09-10 12:27:13 +0000 UTC
Window: 30s
Timestamp: 2019-09-10 12:26:23 +0000 UTC
Name: heapster
Cpu usage: 82166n
Mem usage: 19420Ki 
...
func getMetrics(clientset *kubernetes.Clientset, pods *PodMetricsList) error {
    data, err := clientset.RESTClient().Get().AbsPath("apis/metrics.k8s.io/v1beta1/pods").DoRaw()
    if err != nil {
        return err
    }
    err = json.Unmarshal(data, &pods)
    return err
}

func main() {

    config, err := rest.InClusterConfig()
    if err != nil {
        fmt.Println(err)
    }
    // creates the clientset
    clientset, err := kubernetes.NewForConfig(config)
    if err != nil {
        fmt.Println(err)
    }
    var pods PodMetricsList
    err = getMetrics(clientset, &pods)
    if err != nil {
        fmt.Println(err)
    }

    for _, m := range pods.Items {

        fmt.Print("Namespace: ", m.Metadata.Namespace, "\n", "Pod name: ", m.Metadata.Name, "\n", )
        fmt.Print("SelfLink: ", m.Metadata.SelfLink, "\n", "CreationTimestamp: ", m.Metadata.CreationTimestamp, "\n", )
        fmt.Print("Window: ", m.Window, "\n", "Timestamp: ", m.Timestamp, "\n", )

        for _, c := range m.Containers {
            fmt.Println("Name:", c.Name)
            fmt.Println("Cpu usage:", c.Usage.CPU)
            fmt.Println("Mem usage:", c.Usage.Memory, "\n")
...

As I say, what i really need is what you'd get with a 'describe pods' type call. Having looked through the kubernetes source this NodeDescriber looks like the right type of function, but I'm slightly at a loss as to how to integrate / implement it to get the desired results.

kubernetes/pkg/printers/internalversion/describe.go

Line 2451 in 4f2d7b9

func (d *NodeDescriber) Describe(namespace, name string, describerSettings...etc)

I'm new to Go and not particularly familiar with kubernetes. Any pointers as to how to go about it would be greatly appreciated.

-- Ben Lord
client-go
go
kubectl
kubernetes

2 Answers

9/11/2019

I didn't try, but I would suggest to start with:

1. using kubectl with --verbosity option to see the full api request

 kubectl describe pod xxx -v=8 

like:

  GET https://xx.xx.xx.xx:6443/api/v1/namespaces/default/events?fieldSelector=involvedObject.uid%3Ddd77c4aa-28e6-4bf0-8dfe-0d8610cbe9c9%2CinvolvedObject.name%3Dmy-app%2CinvolvedObject.namespace%3Ddefault

It contains fields related to your POD: fieldSelector=involvedObject.uid, involvedObject.name, involvedObject.namespace

2. I thing the good start it will be the code from github func describePod to start with.

Hope this help.

-- Hanx
Source: StackOverflow

9/11/2019

Looking at the describePod and Describe funcs from staging/src/k8s.io/kubectl/pkg/describe/versioned/describe.go should give you a better picture of how to do this. And since Describe and PodDescriber are public, you can reuse these for your use case.

You could couple this with a CoreV1Client which has a Pods func, that returns a PodInterface that has a List func which would return a list of Pod objects for the given namespace.

Those pod objects will provide the Name needed for the Describe func, the Namespace is already known, and the describe.DescriberSettings is just a struct type that you could inline to enable showing events in the Describe output.

Using the List func will only list the pods that one time. If you're interested in having this list be updated regularly, you might want to look at the Reflector and Informer patterns; both of which are largely implemented in the tools/cache package, and the docs briefly explain this concept in the Efficient detection of changes section.

Hope this helps.

-- cewood
Source: StackOverflow