k8shorizmetrics
is a library that provides the internal workings of the Kubernetes Horizontal Pod Autoscaler (HPA)
wrapped up in a simple API. The project allows querying metrics just as the HPA does, and also running the calculations
to work out the target replica count that the HPA does.
go get -u github.com/jthomperoo/k8shorizmetrics/v2@v2.0.2
- Simple API, based directly on the code from the HPA, but detangled for ease of use.
- Dependent only on versioned and public Kubernetes Golang modules, allows easy install without replace directives.
- Splits the HPA into two parts, metric gathering and evaluation, only use what you need.
- Allows insights into how the HPA makes decisions.
- Supports scaling to and from 0.
The following is a simple program that can run inside a Kubernetes cluster that gets the CPU resource metrics for
pods with the label run: php-apache
.
package main
import (
"log"
"time"
"github.com/jthomperoo/k8shorizmetrics"
"github.com/jthomperoo/k8shorizmetrics/metricsclient"
"github.com/jthomperoo/k8shorizmetrics/podsclient"
"k8s.io/api/autoscaling/v2"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
)
func main() {
// Kubernetes API setup
clusterConfig, _ := rest.InClusterConfig()
clientset, _ := kubernetes.NewForConfig(clusterConfig)
// Metrics and pods clients setup
metricsclient := metricsclient.NewClient(clusterConfig, clientset.Discovery())
podsclient := &podsclient.OnDemandPodLister{Clientset: clientset}
// HPA configuration options
cpuInitializationPeriod := time.Duration(300) * time.Second
initialReadinessDelay := time.Duration(30) * time.Second
// Setup gatherer
gather := k8shorizmetrics.NewGatherer(metricsclient, podsclient, cpuInitializationPeriod, initialReadinessDelay)
// Target resource values
namespace := "default"
podSelector := labels.SelectorFromSet(labels.Set{
"run": "php-apache",
})
// Metric spec to gather, CPU resource utilization
spec := v2.MetricSpec{
Type: v2.ResourceMetricSourceType,
Resource: &v2.ResourceMetricSource{
Name: corev1.ResourceCPU,
Target: v2.MetricTarget{
Type: v2.UtilizationMetricType,
},
},
}
metric, _ := gather.GatherSingleMetric(spec, namespace, podSelector)
for pod, podmetric := range metric.Resource.PodMetricsInfo {
actualCPU := podmetric.Value
requestedCPU := metric.Resource.Requests[pod]
log.Printf("Pod: %s, CPU usage: %dm (%0.2f%% of requested)\n", pod, actualCPU, float64(actualCPU)/float64(requestedCPU)*100.0)
}
}
See the Go doc.
There are two changes you need to make to migrate from v1
to v2
:
- Switch from using
k8s.io/api/autoscaling/v2beta2
tok8s.io/api/autoscaling/v2
. - Switch from using
github.com/jthomperoo/k8shorizmetrics
togithub.com/jthomperoo/k8shorizmetrics/v2
.
See the examples directory for some examples, cpuprint is a good start.
See the contribution guidelines and code of conduct.