volcano.sh/volcano@v1.9.0/pkg/scheduler/metrics/source/metrics_client_prometheus_adapt.go (about)

     1  /*
     2   Copyright 2023 The Volcano Authors.
     3  
     4   Licensed under the Apache License, Version 2.0 (the "License");
     5   you may not use this file except in compliance with the License.
     6   You may obtain a copy of the License at
     7  
     8       http://www.apache.org/licenses/LICENSE-2.0
     9  
    10   Unless required by applicable law or agreed to in writing, software
    11   distributed under the License is distributed on an "AS IS" BASIS,
    12   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   See the License for the specific language governing permissions and
    14   limitations under the License.
    15  */
    16  
    17  package source
    18  
    19  import (
    20  	"context"
    21  
    22  	"k8s.io/apimachinery/pkg/labels"
    23  	"k8s.io/apimachinery/pkg/runtime/schema"
    24  	"k8s.io/client-go/discovery"
    25  	cacheddiscovery "k8s.io/client-go/discovery/cached/memory"
    26  	"k8s.io/client-go/rest"
    27  	"k8s.io/client-go/restmapper"
    28  	"k8s.io/klog/v2"
    29  	customclient "k8s.io/metrics/pkg/client/custom_metrics"
    30  )
    31  
    32  const (
    33  	// CustomNodeCPUUsageAvg record name of cpu average usage defined in prometheus adapt rules
    34  	CustomNodeCPUUsageAvg = "node_cpu_usage_avg"
    35  	// CustomNodeMemUsageAvg record name of mem average usage defined in prometheus adapt rules
    36  	CustomNodeMemUsageAvg = "node_memory_usage_avg"
    37  )
    38  
    39  type KMetricsClient struct {
    40  	customMetricsCli customclient.CustomMetricsClient
    41  }
    42  
    43  var kMetricsClient *KMetricsClient
    44  
    45  func NewCustomMetricsClient(cfg *rest.Config) (*KMetricsClient, error) {
    46  	if kMetricsClient != nil {
    47  		return kMetricsClient, nil
    48  	}
    49  
    50  	klog.V(3).Infof("Create custom metrics api client")
    51  	discoveryClient := discovery.NewDiscoveryClientForConfigOrDie(cfg)
    52  	cachedDiscoClient := cacheddiscovery.NewMemCacheClient(discoveryClient)
    53  	restMapper := restmapper.NewDeferredDiscoveryRESTMapper(cachedDiscoClient)
    54  	apiVersionsGetter := customclient.NewAvailableAPIsGetter(discoveryClient)
    55  	customMetricsClient := customclient.NewForConfig(cfg, restMapper, apiVersionsGetter)
    56  
    57  	kMetricsClient = &KMetricsClient{
    58  		customMetricsCli: customMetricsClient,
    59  	}
    60  	return kMetricsClient, nil
    61  }
    62  
    63  func (km *KMetricsClient) NodesMetricsAvg(ctx context.Context, nodeMetricsMap map[string]*NodeMetrics) error {
    64  	klog.V(5).Infof("Get node metrics from Custom Metrics")
    65  
    66  	groupKind := schema.GroupKind{
    67  		Group: "",
    68  		Kind:  "Node",
    69  	}
    70  
    71  	for _, metricName := range []string{CustomNodeCPUUsageAvg, CustomNodeMemUsageAvg} {
    72  		metricsValue, err := km.customMetricsCli.RootScopedMetrics().GetForObjects(groupKind, labels.NewSelector(), metricName, labels.NewSelector())
    73  		if err != nil {
    74  			klog.Errorf("Failed to query the indicator %s, error is: %v.", metricName, err)
    75  			return err
    76  		}
    77  		for _, metricValue := range metricsValue.Items {
    78  			nodeName := metricValue.DescribedObject.Name
    79  			if _, ok := nodeMetricsMap[nodeName]; !ok {
    80  				klog.Warningf("The node %s information is obtained through the custom metrics API, but the volcano cache does not contain the node information.", nodeName)
    81  				continue
    82  			}
    83  			klog.V(5).Infof("The current usage information of node %s is %v", nodeName, nodeMetricsMap[nodeName])
    84  			switch metricName {
    85  			case CustomNodeCPUUsageAvg:
    86  				nodeMetricsMap[nodeName].MetricsTime = metricValue.Timestamp.Time
    87  				nodeMetricsMap[nodeName].CPU = metricValue.Value.AsApproximateFloat64() * 100
    88  			case CustomNodeMemUsageAvg:
    89  				nodeMetricsMap[nodeName].MetricsTime = metricValue.Timestamp.Time
    90  				nodeMetricsMap[nodeName].Memory = metricValue.Value.AsApproximateFloat64() * 100
    91  			default:
    92  				klog.Errorf("Node supports %s and %s metrics, and %s indicates abnormal metrics.", CustomNodeCPUUsageAvg, CustomNodeMemUsageAvg, metricName)
    93  			}
    94  			klog.V(5).Infof("The updated usage information of node %s is %v.", nodeName, nodeMetricsMap[nodeName])
    95  		}
    96  	}
    97  
    98  	return nil
    99  }