mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-21 19:01:49 +00:00
Merge pull request #114997 from Richabanker/metrics-slis-beta
Enable ComponentSLI as beta feature
This commit is contained in:
commit
1f02f43ec6
@ -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",
|
||||||
|
@ -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},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
14
test/e2e/framework/metrics/OWNERS
Normal file
14
test/e2e/framework/metrics/OWNERS
Normal 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
|
@ -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
|
|
||||||
}
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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)
|
||||||
|
@ -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())
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user