Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Metric Server - consolidate apiserver to one port #4982

Merged
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ To learn more about active deprecations, we recommend checking [GitHub Discussio
- **General**: Adding a changelog validating script to check for formatting and order ([#3190](https://github.com/kedacore/keda/issues/3190))
- **General**: Update golangci-lint version documented in CONTRIBUTING.md since old version doesn't support go 1.20 (N/A)
- **General**: Updated AWS SDK and updated all the aws scalers ([#4905](https://github.com/kedacore/keda/issues/4905))
- **General**: Add apiserver prometheus metrics to keda metric server ([#4460](https://github.com/kedacore/keda/issues/4460))
- **Azure Pod Identity**: Introduce validation to prevent usage of empty identity ID for Azure identity providers ([#4528](https://github.com/kedacore/keda/issues/4528))
- **Prometheus Scaler**: Remove trailing whitespaces in customAuthHeader and customAuthValue ([#4960](https://github.com/kedacore/keda/issues/4960))
- **Pulsar Scaler**: Add support for OAuth extensions ([#4700](https://github.com/kedacore/keda/issues/4700))
Expand Down
61 changes: 59 additions & 2 deletions cmd/adapter/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,29 @@ import (
"context"
"flag"
"fmt"
"net/http"
"os"

appsv1 "k8s.io/api/apps/v1"
apimetrics "k8s.io/apiserver/pkg/endpoints/metrics"
"k8s.io/client-go/kubernetes/scheme"
kubemetrics "k8s.io/component-base/metrics"
"k8s.io/component-base/metrics/legacyregistry"
"k8s.io/klog/v2"
"k8s.io/klog/v2/klogr"
ctrl "sigs.k8s.io/controller-runtime"
ctrlcache "sigs.k8s.io/controller-runtime/pkg/cache"
ctrlmetrics "sigs.k8s.io/controller-runtime/pkg/metrics"
"sigs.k8s.io/controller-runtime/pkg/metrics/server"

basecmd "sigs.k8s.io/custom-metrics-apiserver/pkg/cmd"
"sigs.k8s.io/custom-metrics-apiserver/pkg/provider"

kedav1alpha1 "github.com/kedacore/keda/v2/apis/keda/v1alpha1"
"github.com/kedacore/keda/v2/pkg/metricsservice"
kedaprovider "github.com/kedacore/keda/v2/pkg/provider"
kedautil "github.com/kedacore/keda/v2/pkg/util"
"github.com/prometheus/client_golang/prometheus/collectors"
)

// Adapter creates External Metrics Provider
Expand Down Expand Up @@ -96,10 +103,9 @@ func (a *Adapter) makeProvider(ctx context.Context) (provider.ExternalMetricsPro
cfg.Burst = adapterClientRequestBurst
cfg.DisableCompression = disableCompression

metricsBindAddress := fmt.Sprintf(":%v", metricsAPIServerPort)
mgr, err := ctrl.NewManager(cfg, ctrl.Options{
Metrics: server.Options{
BindAddress: metricsBindAddress,
BindAddress: "0", // disabled since we use our own server to serve metrics
},
Scheme: scheme,
Cache: ctrlcache.Options{
Expand Down Expand Up @@ -131,6 +137,54 @@ func (a *Adapter) makeProvider(ctx context.Context) (provider.ExternalMetricsPro
return kedaprovider.NewProvider(ctx, logger, mgr.GetClient(), *grpcClient), stopCh, nil
}

// getMetricHandler returns a http handler that exposes metrics from controller-runtime and apiserver
func getMetricHandler() http.HandlerFunc {
zroubalik marked this conversation as resolved.
Show resolved Hide resolved
// Register apiserver metrics in legacy registry
// this contains the apiserver_* metrics
apimetrics.Register()

// unregister duplicate collectors that are already handled by controller-runtime's registry
legacyregistry.Registerer().Unregister(collectors.NewProcessCollector(collectors.ProcessCollectorOpts{}))
legacyregistry.Registerer().Unregister(collectors.NewGoCollector(collectors.WithGoCollectorRuntimeMetrics(collectors.MetricsAll)))

// Return handler that serves metrics from both legacy and controller-runtime registry
return func(w http.ResponseWriter, req *http.Request) {
legacyregistry.Handler().ServeHTTP(w, req)

kubemetrics.HandlerFor(ctrlmetrics.Registry, kubemetrics.HandlerOpts{}).ServeHTTP(w, req)
}
}

// RunMetricsServer runs a http listener and handles the /metrics endpoint
zroubalik marked this conversation as resolved.
Show resolved Hide resolved
func RunMetricsServer(stopCh <-chan struct{}) {
h := getMetricHandler()
mux := http.NewServeMux()
mux.Handle("/metrics", h)
metricsBindAddress := fmt.Sprintf(":%v", metricsAPIServerPort)

server := &http.Server{
Addr: metricsBindAddress,
Handler: mux,
}

go func() {
zroubalik marked this conversation as resolved.
Show resolved Hide resolved
logger.Info("starting /metrics server endpoint")
// nosemgrep: use-tls
err := server.ListenAndServe()
if err != nil {
panic(err)
}
}()

go func() {
<-stopCh
logger.Info("Shutting down the /metrics server gracefully...")
if err := server.Shutdown(context.TODO()); err != nil {
BojanZelic marked this conversation as resolved.
Show resolved Hide resolved
logger.Error(err, "http server shutdown error")
}
}()
}

// generateDefaultMetricsServiceAddr generates default Metrics Service gRPC Server address based on the current Namespace.
// By default the Metrics Service gRPC Server runs in the same namespace on the keda-operator pod.
func generateDefaultMetricsServiceAddr() string {
Expand Down Expand Up @@ -196,6 +250,9 @@ func main() {
cmd.WithExternalMetrics(kedaProvider)

logger.Info(cmd.Message)

RunMetricsServer(stopCh)

if err = cmd.Run(stopCh); err != nil {
return
}
Expand Down
Loading