-
Notifications
You must be signed in to change notification settings - Fork 1.9k
/
Copy pathconfig.go
120 lines (109 loc) · 3.62 KB
/
config.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// Copyright 2018 The Kubernetes Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package server
import (
"fmt"
"net/http"
"strings"
"time"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/labels"
apimetrics "k8s.io/apiserver/pkg/endpoints/metrics"
genericapiserver "k8s.io/apiserver/pkg/server"
"k8s.io/client-go/rest"
"k8s.io/component-base/metrics"
"k8s.io/component-base/metrics/legacyregistry"
_ "k8s.io/component-base/metrics/prometheus/restclient" // for client-go metrics registration
"sigs.k8s.io/metrics-server/pkg/api"
"sigs.k8s.io/metrics-server/pkg/scraper"
"sigs.k8s.io/metrics-server/pkg/scraper/client"
"sigs.k8s.io/metrics-server/pkg/scraper/client/resource"
"sigs.k8s.io/metrics-server/pkg/storage"
)
type Config struct {
Apiserver *genericapiserver.Config
Rest *rest.Config
Kubelet *client.KubeletClientConfig
MetricResolution time.Duration
ScrapeTimeout time.Duration
NodeSelector string
}
func (c Config) Complete() (*server, error) {
var labelRequirement []labels.Requirement
podInformerFactory, err := runningPodMetadataInformer(c.Rest)
if err != nil {
return nil, err
}
podInformer := podInformerFactory.ForResource(corev1.SchemeGroupVersion.WithResource("pods"))
informer, err := informerFactory(c.Rest)
if err != nil {
return nil, err
}
kubeletClient, err := resource.NewForConfig(c.Kubelet)
if err != nil {
return nil, fmt.Errorf("unable to construct a client to connect to the kubelets: %v", err)
}
nodes := informer.Core().V1().Nodes()
ns := strings.TrimSpace(c.NodeSelector)
if ns != "" {
labelRequirement, err = labels.ParseToRequirements(ns)
if err != nil {
return nil, err
}
}
scrape := scraper.NewScraper(nodes.Lister(), kubeletClient, c.ScrapeTimeout, labelRequirement)
// Disable default metrics handler and create custom one
c.Apiserver.EnableMetrics = false
metricsHandler, err := c.metricsHandler()
if err != nil {
return nil, err
}
genericServer, err := c.Apiserver.Complete(nil).New("metrics-server", genericapiserver.NewEmptyDelegate())
if err != nil {
return nil, err
}
genericServer.Handler.NonGoRestfulMux.HandleFunc("/metrics", metricsHandler)
store := storage.NewStorage(c.MetricResolution)
if err := api.Install(store, podInformer.Lister(), nodes.Lister(), genericServer, labelRequirement); err != nil {
return nil, err
}
s := NewServer(
nodes.Informer(),
podInformer.Informer(),
genericServer,
store,
scrape,
c.MetricResolution,
)
err = s.RegisterProbes(podInformerFactory)
if err != nil {
return nil, err
}
return s, nil
}
func (c Config) metricsHandler() (http.HandlerFunc, error) {
// Create registry for Metrics Server metrics
registry := metrics.NewKubeRegistry()
err := RegisterMetrics(registry, c.MetricResolution)
if err != nil {
return nil, err
}
// Register apiserver metrics in legacy registry
apimetrics.Register()
// Return handler that serves metrics from both legacy and Metrics Server registry
return func(w http.ResponseWriter, req *http.Request) {
legacyregistry.Handler().ServeHTTP(w, req)
metrics.HandlerFor(registry, metrics.HandlerOpts{}).ServeHTTP(w, req)
}, nil
}