Merge pull request #114997 from Richabanker/metrics-slis-beta

Enable ComponentSLI as beta feature
This commit is contained in:
Kubernetes Prow Robot 2023-01-27 10:04:25 -08:00 committed by GitHub
commit 1f02f43ec6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 83 additions and 36 deletions

View File

@ -170,6 +170,7 @@ func TestNewWithDelegate(t *testing.T) {
"/livez/poststarthook/storage-object-count-tracker-hook", "/livez/poststarthook/storage-object-count-tracker-hook",
"/livez/poststarthook/wrapping-post-start-hook", "/livez/poststarthook/wrapping-post-start-hook",
"/metrics", "/metrics",
"/metrics/slis",
"/readyz", "/readyz",
"/readyz/delegate-health", "/readyz/delegate-health",
"/readyz/informer-sync", "/readyz/informer-sync",

View File

@ -29,7 +29,7 @@ const (
func featureGates() map[featuregate.Feature]featuregate.FeatureSpec { func featureGates() map[featuregate.Feature]featuregate.FeatureSpec {
return map[featuregate.Feature]featuregate.FeatureSpec{ return map[featuregate.Feature]featuregate.FeatureSpec{
ComponentSLIs: {Default: false, PreRelease: featuregate.Alpha}, ComponentSLIs: {Default: true, PreRelease: featuregate.Beta},
} }
} }

View File

@ -0,0 +1,14 @@
# See the OWNERS docs at https://go.k8s.io/owners
approvers:
- sig-instrumentation-approvers
emeritus_approvers:
- fabxc
- piosz
- fgrzadkowski
- kawych
- x13n
reviewers:
- sig-instrumentation-reviewers
labels:
- sig/instrumentation

View File

@ -17,8 +17,6 @@ limitations under the License.
package metrics package metrics
import ( import (
"context"
"k8s.io/component-base/metrics/testutil" "k8s.io/component-base/metrics/testutil"
) )
@ -42,11 +40,3 @@ func parseAPIServerMetrics(data string) (APIServerMetrics, error) {
} }
return result, nil return result, nil
} }
func (g *Grabber) getMetricsFromAPIServer(ctx context.Context) (string, error) {
rawOutput, err := g.client.CoreV1().RESTClient().Get().RequestURI("/metrics").Do(ctx).Raw()
if err != nil {
return "", err
}
return string(rawOutput), nil
}

View File

@ -93,31 +93,6 @@ func parseKubeletMetrics(data string) (KubeletMetrics, error) {
return result, nil return result, nil
} }
func (g *Grabber) getMetricsFromNode(ctx context.Context, nodeName string, kubeletPort int) (string, error) {
// There's a problem with timing out during proxy. Wrapping this in a goroutine to prevent deadlock.
finished := make(chan struct{}, 1)
var err error
var rawOutput []byte
go func() {
rawOutput, err = g.client.CoreV1().RESTClient().Get().
Resource("nodes").
SubResource("proxy").
Name(fmt.Sprintf("%v:%v", nodeName, kubeletPort)).
Suffix("metrics").
Do(ctx).Raw()
finished <- struct{}{}
}()
select {
case <-time.After(proxyTimeout):
return "", fmt.Errorf("Timed out when waiting for proxy to gather metrics from %v", nodeName)
case <-finished:
if err != nil {
return "", err
}
return string(rawOutput), nil
}
}
// KubeletLatencyMetric stores metrics scraped from the kubelet server's /metric endpoint. // KubeletLatencyMetric stores metrics scraped from the kubelet server's /metric endpoint.
// TODO: Get some more structure around the metrics and this type // TODO: Get some more structure around the metrics and this type
type KubeletLatencyMetric struct { type KubeletLatencyMetric struct {

View File

@ -54,6 +54,7 @@ var MetricsGrabbingDisabledError = errors.New("metrics grabbing disabled")
// Collection is metrics collection of components // Collection is metrics collection of components
type Collection struct { type Collection struct {
APIServerMetrics APIServerMetrics APIServerMetrics APIServerMetrics
APIServerMetricsSLIs APIServerMetrics
ControllerManagerMetrics ControllerManagerMetrics ControllerManagerMetrics ControllerManagerMetrics
SnapshotControllerMetrics SnapshotControllerMetrics SnapshotControllerMetrics SnapshotControllerMetrics
KubeletMetrics map[string]KubeletMetrics KubeletMetrics map[string]KubeletMetrics
@ -194,6 +195,31 @@ func (g *Grabber) grabFromKubeletInternal(ctx context.Context, nodeName string,
return parseKubeletMetrics(output) return parseKubeletMetrics(output)
} }
func (g *Grabber) getMetricsFromNode(ctx context.Context, nodeName string, kubeletPort int) (string, error) {
// There's a problem with timing out during proxy. Wrapping this in a goroutine to prevent deadlock.
finished := make(chan struct{}, 1)
var err error
var rawOutput []byte
go func() {
rawOutput, err = g.client.CoreV1().RESTClient().Get().
Resource("nodes").
SubResource("proxy").
Name(fmt.Sprintf("%v:%v", nodeName, kubeletPort)).
Suffix("metrics").
Do(ctx).Raw()
finished <- struct{}{}
}()
select {
case <-time.After(proxyTimeout):
return "", fmt.Errorf("Timed out when waiting for proxy to gather metrics from %v", nodeName)
case <-finished:
if err != nil {
return "", err
}
return string(rawOutput), nil
}
}
// GrabFromScheduler returns metrics from scheduler // GrabFromScheduler returns metrics from scheduler
func (g *Grabber) GrabFromScheduler(ctx context.Context) (SchedulerMetrics, error) { func (g *Grabber) GrabFromScheduler(ctx context.Context) (SchedulerMetrics, error) {
if !g.grabFromScheduler { if !g.grabFromScheduler {
@ -323,6 +349,31 @@ func (g *Grabber) GrabFromAPIServer(ctx context.Context) (APIServerMetrics, erro
return parseAPIServerMetrics(output) return parseAPIServerMetrics(output)
} }
// GrabMetricsSLIsFromAPIServer returns metrics from API server
func (g *Grabber) GrabMetricsSLIsFromAPIServer(ctx context.Context) (APIServerMetrics, error) {
output, err := g.getMetricsSLIsFromAPIServer(ctx)
if err != nil {
return APIServerMetrics{}, err
}
return parseAPIServerMetrics(output)
}
func (g *Grabber) getMetricsFromAPIServer(ctx context.Context) (string, error) {
rawOutput, err := g.client.CoreV1().RESTClient().Get().RequestURI("/metrics").Do(ctx).Raw()
if err != nil {
return "", err
}
return string(rawOutput), nil
}
func (g *Grabber) getMetricsSLIsFromAPIServer(ctx context.Context) (string, error) {
rawOutput, err := g.client.CoreV1().RESTClient().Get().RequestURI("/metrics/slis").Do(ctx).Raw()
if err != nil {
return "", err
}
return string(rawOutput), nil
}
// Grab returns metrics from corresponding component // Grab returns metrics from corresponding component
func (g *Grabber) Grab(ctx context.Context) (Collection, error) { func (g *Grabber) Grab(ctx context.Context) (Collection, error) {
result := Collection{} result := Collection{}
@ -334,6 +385,12 @@ func (g *Grabber) Grab(ctx context.Context) (Collection, error) {
} else { } else {
result.APIServerMetrics = metrics result.APIServerMetrics = metrics
} }
metrics, err = g.GrabMetricsSLIsFromAPIServer(ctx)
if err != nil {
errs = append(errs, err)
} else {
result.APIServerMetricsSLIs = metrics
}
} }
if g.grabFromScheduler { if g.grabFromScheduler {
metrics, err := g.GrabFromScheduler(ctx) metrics, err := g.GrabFromScheduler(ctx)

View File

@ -93,4 +93,14 @@ var _ = instrumentation.SIGDescribe("MetricsGrabber", func() {
framework.ExpectNoError(err) framework.ExpectNoError(err)
gomega.Expect(response).NotTo(gomega.BeEmpty()) gomega.Expect(response).NotTo(gomega.BeEmpty())
}) })
ginkgo.It("should grab all metrics slis from API server.", func(ctx context.Context) {
ginkgo.By("Connecting to /metrics/slis endpoint")
response, err := grabber.GrabMetricsSLIsFromAPIServer(ctx)
if errors.Is(err, e2emetrics.MetricsGrabbingDisabledError) {
e2eskipper.Skipf("%v", err)
}
framework.ExpectNoError(err)
gomega.Expect(response).NotTo(gomega.BeEmpty())
})
}) })