Как получить метрики kubernetes через client-go и golang

Я хочу получить доступ к метрикам из kubernetes с помощью golang. Что-то вроде процессора и памяти на узел, а также то же самое для модулей и/или пространств имен.

Я немного потерялся здесь, потому что документация не так ясна, как могла бы быть.

Я узнал, что есть heapster (который устарел в соответствии с репозиторием github). Так же есть metric server и остальные апи.

Где я могу найти несколько примеров для начала? Я не хочу устанавливать другое приложение, пакет или сервис в kubernetes. Я хотел бы получить информацию как можно более родной. Каков предпочтительный способ доступа к этой информации с помощью client-go и golang?


person silverfighter    schedule 26.08.2018    source источник
comment
Что-то вроде: stackoverflow.com/ вопросы/49192508/ ?   -  person Vishal Biyani    schedule 27.08.2018


Ответы (3)


Для этого есть гораздо лучший API: https://github.com/kubernetes/metrics. Используя это, вам не нужно создавать структуры данных или обрабатывать срезы байтов строк.

import (
  metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  metricsv "k8s.io/metrics/pkg/client/clientset/versioned"
  ...
)

...
clientset, err := metricsv.NewForConfig(config)
podMetricsList, err := clientset.MetricsV1beta1().PodMetricses("").List(metav1.ListOptions{})
person gnvk    schedule 26.09.2019
comment
Теперь .List() принимает аргумент context.Context: clientset.MetricsV1beta1().PodMetricses("").List(context.TODO(), metav1.ListOptions{}) - person sshow; 28.03.2021

Вот пример использования REST API для запроса метрик узла и возврата []byte в формате JSON. Замените «узлы» на «модули», чтобы получить метрики модуля/контейнера.

data, err := clientset.RESTClient().Get().AbsPath("apis/metrics.k8s.io/v1beta1/nodes").DoRaw()
person Richard Schofield    schedule 09.10.2018

Как поясняется в вопросе, документация непонятна для новичка. Даже примеры go-client извлекают данные, я хотел получить поддержку Type.

Как поясняется в ответе выше, вы можете получить данные в []byte в формате JSON. Вот как я это сделал.

package main

import (
    "encoding/json"
    "fmt"
    "time"

    "k8s.io/client-go/kubernetes"
    "k8s.io/client-go/rest"
)

// PodMetricsList : PodMetricsList
type PodMetricsList struct {
    Kind       string `json:"kind"`
    APIVersion string `json:"apiVersion"`
    Metadata   struct {
        SelfLink string `json:"selfLink"`
    } `json:"metadata"`
    Items []struct {
        Metadata struct {
            Name              string    `json:"name"`
            Namespace         string    `json:"namespace"`
            SelfLink          string    `json:"selfLink"`
            CreationTimestamp time.Time `json:"creationTimestamp"`
        } `json:"metadata"`
        Timestamp  time.Time `json:"timestamp"`
        Window     string    `json:"window"`
        Containers []struct {
            Name  string `json:"name"`
            Usage struct {
                CPU    string `json:"cpu"`
                Memory string `json:"memory"`
            } `json:"usage"`
        } `json:"containers"`
    } `json:"items"`
}

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() {
    // creates the in-cluster config
    // https://github.com/kubernetes/client-go/tree/master/examples#configuration
    config, err := rest.InClusterConfig()
    if err != nil {
        panic(err.Error())
    }
    // creates the clientset
    clientset, err := kubernetes.NewForConfig(config)
    if err != nil {
        panic(err.Error())
    }
    var pods PodMetricsList
    err = getMetrics(clientset, &pods)
    if err != nil {
        panic(err.Error())
    }
    for _, m := range pods.Items {
        fmt.Println(m.Metadata.Name, m.Metadata.Namespace, m.Timestamp.String())
    }
}

Установите следующие пакеты Go: go get -u k8s.io/client-go/kubernetes k8s.io/client-go/rest

Вы можете использовать следующие конечные точки для получения данных по своему усмотрению;

  • Узлы: apis/metrics.k8s.io/v1beta1/nodes
  • Пакеты: apis/metrics.k8s.io/v1beta1/pods
  • Поды пространства имен default: apis/metrics.k8s.io/v1beta1/namespaces/default/pods
  • Конкретный модуль: /apis/metrics.k8s.io/v1beta1/namespaces/default/pods/<POD-NAME>

ПРИМЕЧАНИЕ. Возможно, вам потребуется изменить тип перед json.Unmarshal. Вы можете определить Тип только для интересующего вас поля.

person gihanchanuka    schedule 01.02.2019
comment
@mR.aTA, можете ли вы предоставить более подробную информацию? Также убедитесь, что у вашего клиента есть разрешение на доступ к метрикам. - person gihanchanuka; 02.11.2019
comment
Это ссылка на дамп конфига Также хорошо работает команда kubectl get --raw /apis/metrics.k8s.io/v1beta1/pods. Как я могу убедиться, что у моего клиента достаточно разрешений? Он паникует в data, err := clientset.RESTClient().Get().AbsPath("apis/metrics.k8s.io/v1beta1/pods").DoRaw(), а err - это unknown. У меня также есть эти два в моем kubelet confi: authenticationTokenWebhook: true и authorizationMode: Webhook. - person mR.aTA; 03.11.2019
comment
Я обновил свой authenticatioinMode:AlwaysAllow, поэтому пример здесь для получения списка узлов работает нормально, но код для получения метрик возвращает ошибку unknown. - person mR.aTA; 03.11.2019
comment
Убедитесь, что вы установили metrics-server. Создайте роль кластера для пространства имен по умолчанию с помощью kubectl create clusterrolebinding default-cluster-admin --clusterrole=cluster-admin --serviceaccount=default:default - person gihanchanuka; 03.11.2019
comment
Спасибо @gihanchanuka! Однако я не использовал роль администратора кластера, но я написал rbca clusterrol/clusterrolbinding с пользовательскими разрешениями, и теперь это работает. Спасибо еще раз. - person mR.aTA; 04.11.2019