Created
November 1, 2023 15:01
-
-
Save able8/bd8774bb8a297dfc27da5184f330648d to your computer and use it in GitHub Desktop.
Get Node and Pod Resource Usages using K8s metricsClient
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
// https://cloud.tencent.com/developer/ask/sof/115441746 | |
import ( | |
"bytes" | |
"context" | |
"flag" | |
"fmt" | |
"log" | |
"path/filepath" | |
"time" | |
v1 "k8s.io/api/core/v1" | |
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | |
"k8s.io/client-go/kubernetes" | |
"k8s.io/client-go/tools/clientcmd" | |
"k8s.io/client-go/util/homedir" | |
"k8s.io/kubectl/pkg/metricsutil" | |
metricsapi "k8s.io/metrics/pkg/apis/metrics" | |
metricsv1beta1api "k8s.io/metrics/pkg/apis/metrics/v1beta1" | |
metrics "k8s.io/metrics/pkg/client/clientset/versioned" | |
) | |
var ( | |
namespaceName = "infra" | |
podName = "thanos-xxx-7dfbffbd4b-nbvvd" | |
nodeName = "cn-hongkong.i-j6cjxxxx" | |
) | |
func main() { | |
var kubeconfig *string | |
if home := homedir.HomeDir(); home != "" { | |
kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file") | |
} else { | |
kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file") | |
} | |
flag.Parse() | |
// Init Kubernetes REST Client | |
config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig) | |
if err != nil { | |
panic(err.Error()) | |
} | |
clientset, err := kubernetes.NewForConfig(config) | |
if err != nil { | |
panic(err.Error()) | |
} | |
metricsClient, err := metrics.NewForConfig(config) | |
if err != nil { | |
panic(err) | |
} | |
for { | |
podOutput, err := RunTopPod(metricsClient, podName, namespaceName) | |
if err != nil { | |
log.Println(err) | |
} | |
nodeOutput, err := RunTopNode(clientset, metricsClient, nodeName) | |
if err != nil { | |
log.Println(err) | |
} | |
fmt.Println(podOutput, nodeOutput) | |
time.Sleep(3 * time.Second) | |
} | |
} | |
func RunTopPod(metricsClient metrics.Interface, podName string, namespaceName string) (string, error) { | |
var buf bytes.Buffer | |
printer := metricsutil.NewTopCmdPrinter(&buf) | |
m, err := metricsClient.MetricsV1beta1().PodMetricses(namespaceName).Get(context.TODO(), podName, metav1.GetOptions{}) | |
if err != nil { | |
return "", err | |
} | |
versionedMetrics := &metricsv1beta1api.PodMetricsList{} | |
versionedMetrics.Items = []metricsv1beta1api.PodMetrics{*m} | |
metrics := &metricsapi.PodMetricsList{} | |
err = metricsv1beta1api.Convert_v1beta1_PodMetricsList_To_metrics_PodMetricsList(versionedMetrics, metrics, nil) | |
if err != nil { | |
return "", err | |
} | |
printer.PrintPodMetrics(metrics.Items, false, false, false, "CPU", false) | |
fmt.Fprintf(&buf, "Collected: %s ago, at %s\n", m.ObjectMeta.CreationTimestamp.Time.Sub(m.Timestamp.Time), m.Timestamp.Time) | |
return buf.String(), nil | |
} | |
func RunTopNode(clientset kubernetes.Interface, metricsClient metrics.Interface, nodeName string) (string, error) { | |
var buf bytes.Buffer | |
printer := metricsutil.NewTopCmdPrinter(&buf) | |
node, err := clientset.CoreV1().Nodes().Get(context.TODO(), nodeName, metav1.GetOptions{}) | |
if err != nil { | |
return "", err | |
} | |
availableResources := make(map[string]v1.ResourceList) | |
availableResources[node.Name] = node.Status.Allocatable | |
m, err := metricsClient.MetricsV1beta1().NodeMetricses().Get(context.TODO(), nodeName, metav1.GetOptions{}) | |
if err != nil { | |
return "", err | |
} | |
versionedMetrics := &metricsv1beta1api.NodeMetricsList{} | |
versionedMetrics.Items = []metricsv1beta1api.NodeMetrics{*m} | |
metrics := &metricsapi.NodeMetricsList{} | |
err = metricsv1beta1api.Convert_v1beta1_NodeMetricsList_To_metrics_NodeMetricsList(versionedMetrics, metrics, nil) | |
if err != nil { | |
return "", err | |
} | |
printer.PrintNodeMetrics(metrics.Items, availableResources, false, "CPU") | |
fmt.Fprintf(&buf, "Collected: %s ago, At %s\n", m.ObjectMeta.CreationTimestamp.Time.Sub(m.Timestamp.Time), m.Timestamp.Time) | |
return buf.String(), nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
K8s Metrics API (Also used by HPA)
Source code from kubectl top node and kubectl top pod, see RunTopPod
Simple example: Get current resource usage of a pod in Kubernetes with Go client