Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
0547bbf7
Commit
0547bbf7
authored
Jun 07, 2018
by
Krzysztof Siedlecki
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Revert "Fixing scheduling latency metrics"
This reverts commit
0e833bfc
.
parent
c855acca
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
64 additions
and
111 deletions
+64
-111
BUILD
cmd/kube-scheduler/app/BUILD
+0
-1
server.go
cmd/kube-scheduler/app/server.go
+4
-17
metrics.go
pkg/scheduler/metrics/metrics.go
+38
-45
scheduler.go
pkg/scheduler/scheduler.go
+3
-3
BUILD
test/e2e/framework/BUILD
+0
-1
metrics_util.go
test/e2e/framework/metrics_util.go
+17
-43
density.go
test/e2e/scalability/density.go
+2
-1
No files found.
cmd/kube-scheduler/app/BUILD
View file @
0547bbf7
...
...
@@ -21,7 +21,6 @@ go_library(
"//pkg/scheduler/api:go_default_library",
"//pkg/scheduler/api/latest:go_default_library",
"//pkg/scheduler/factory:go_default_library",
"//pkg/scheduler/metrics:go_default_library",
"//pkg/util/configz:go_default_library",
"//pkg/util/flag:go_default_library",
"//pkg/version:go_default_library",
...
...
cmd/kube-scheduler/app/server.go
View file @
0547bbf7
...
...
@@ -19,7 +19,6 @@ package app
import
(
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
...
...
@@ -52,7 +51,6 @@ import (
schedulerapi
"k8s.io/kubernetes/pkg/scheduler/api"
latestschedulerapi
"k8s.io/kubernetes/pkg/scheduler/api/latest"
"k8s.io/kubernetes/pkg/scheduler/factory"
"k8s.io/kubernetes/pkg/scheduler/metrics"
"k8s.io/kubernetes/pkg/util/configz"
utilflag
"k8s.io/kubernetes/pkg/util/flag"
"k8s.io/kubernetes/pkg/version"
...
...
@@ -223,23 +221,11 @@ func buildHandlerChain(handler http.Handler, authn authenticator.Request, authz
return
handler
}
func
installMetricHandler
(
pathRecorderMux
*
mux
.
PathRecorderMux
)
{
configz
.
InstallHandler
(
pathRecorderMux
)
defaultMetricsHandler
:=
prometheus
.
Handler
()
.
ServeHTTP
pathRecorderMux
.
HandleFunc
(
"/metrics"
,
func
(
w
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
if
req
.
Method
==
"DELETE"
{
metrics
.
Reset
()
io
.
WriteString
(
w
,
"metrics reset
\n
"
)
return
}
defaultMetricsHandler
(
w
,
req
)
})
}
// newMetricsHandler builds a metrics server from the config.
func
newMetricsHandler
(
config
*
componentconfig
.
KubeSchedulerConfiguration
)
http
.
Handler
{
pathRecorderMux
:=
mux
.
NewPathRecorderMux
(
"kube-scheduler"
)
installMetricHandler
(
pathRecorderMux
)
configz
.
InstallHandler
(
pathRecorderMux
)
pathRecorderMux
.
Handle
(
"/metrics"
,
prometheus
.
Handler
())
if
config
.
EnableProfiling
{
routes
.
Profiling
{}
.
Install
(
pathRecorderMux
)
if
config
.
EnableContentionProfiling
{
...
...
@@ -256,7 +242,8 @@ func newHealthzHandler(config *componentconfig.KubeSchedulerConfiguration, separ
pathRecorderMux
:=
mux
.
NewPathRecorderMux
(
"kube-scheduler"
)
healthz
.
InstallHandler
(
pathRecorderMux
)
if
!
separateMetrics
{
installMetricHandler
(
pathRecorderMux
)
configz
.
InstallHandler
(
pathRecorderMux
)
pathRecorderMux
.
Handle
(
"/metrics"
,
prometheus
.
Handler
())
}
if
config
.
EnableProfiling
{
routes
.
Profiling
{}
.
Install
(
pathRecorderMux
)
...
...
pkg/scheduler/metrics/metrics.go
View file @
0547bbf7
...
...
@@ -23,38 +23,29 @@ import (
"github.com/prometheus/client_golang/prometheus"
)
const
(
// SchedulerSubsystem - subsystem name used by scheduler
SchedulerSubsystem
=
"scheduler"
// SchedulingLatencyName - scheduler latency metric name
SchedulingLatencyName
=
"scheduling_latencies_summary"
// OperationLabel - operation label name
OperationLabel
=
"operation"
// Binding - binding operation label value
Binding
=
"binding"
// SchedulingAlgorithm - scheduling algorithm operation label value
SchedulingAlgorithm
=
"scheduling_algorithm"
// E2eScheduling - e2e scheduling operation label value
E2eScheduling
=
"e2e_scheduling"
)
const
schedulerSubsystem
=
"scheduler"
// All the histogram based metrics have 1ms as size for the smallest bucket.
var
(
SchedulingLatency
=
prometheus
.
NewSummaryVec
(
prometheus
.
SummaryOpts
{
Subsystem
:
SchedulerSubsystem
,
Name
:
SchedulingLatencyName
,
Help
:
"Scheduling latency in microseconds split by sub-parts of the scheduling operation"
,
// Make the sliding window of 5h.
// TODO: The value for this should be based on some SLI definition (long term).
MaxAge
:
5
*
time
.
Hour
,
E2eSchedulingLatency
=
prometheus
.
NewHistogram
(
prometheus
.
HistogramOpts
{
Subsystem
:
schedulerSubsystem
,
Name
:
"e2e_scheduling_latency_microseconds"
,
Help
:
"E2e scheduling latency (scheduling algorithm + binding)"
,
Buckets
:
prometheus
.
ExponentialBuckets
(
1000
,
2
,
15
),
},
)
SchedulingAlgorithmLatency
=
prometheus
.
NewHistogram
(
prometheus
.
HistogramOpts
{
Subsystem
:
schedulerSubsystem
,
Name
:
"scheduling_algorithm_latency_microseconds"
,
Help
:
"Scheduling algorithm latency"
,
Buckets
:
prometheus
.
ExponentialBuckets
(
1000
,
2
,
15
),
},
[]
string
{
OperationLabel
},
)
SchedulingAlgorithmPredicateEvaluationDuration
=
prometheus
.
NewHistogram
(
prometheus
.
HistogramOpts
{
Subsystem
:
S
chedulerSubsystem
,
Subsystem
:
s
chedulerSubsystem
,
Name
:
"scheduling_algorithm_predicate_evaluation"
,
Help
:
"Scheduling algorithm predicate evaluation duration"
,
Buckets
:
prometheus
.
ExponentialBuckets
(
1000
,
2
,
15
),
...
...
@@ -62,7 +53,7 @@ var (
)
SchedulingAlgorithmPriorityEvaluationDuration
=
prometheus
.
NewHistogram
(
prometheus
.
HistogramOpts
{
Subsystem
:
S
chedulerSubsystem
,
Subsystem
:
s
chedulerSubsystem
,
Name
:
"scheduling_algorithm_priority_evaluation"
,
Help
:
"Scheduling algorithm priority evaluation duration"
,
Buckets
:
prometheus
.
ExponentialBuckets
(
1000
,
2
,
15
),
...
...
@@ -70,48 +61,50 @@ var (
)
SchedulingAlgorithmPremptionEvaluationDuration
=
prometheus
.
NewHistogram
(
prometheus
.
HistogramOpts
{
Subsystem
:
S
chedulerSubsystem
,
Subsystem
:
s
chedulerSubsystem
,
Name
:
"scheduling_algorithm_preemption_evaluation"
,
Help
:
"Scheduling algorithm preemption evaluation duration"
,
Buckets
:
prometheus
.
ExponentialBuckets
(
1000
,
2
,
15
),
},
)
BindingLatency
=
prometheus
.
NewHistogram
(
prometheus
.
HistogramOpts
{
Subsystem
:
schedulerSubsystem
,
Name
:
"binding_latency_microseconds"
,
Help
:
"Binding latency"
,
Buckets
:
prometheus
.
ExponentialBuckets
(
1000
,
2
,
15
),
},
)
PreemptionVictims
=
prometheus
.
NewGauge
(
prometheus
.
GaugeOpts
{
Subsystem
:
S
chedulerSubsystem
,
Subsystem
:
s
chedulerSubsystem
,
Name
:
"pod_preemption_victims"
,
Help
:
"Number of selected preemption victims"
,
})
PreemptionAttempts
=
prometheus
.
NewCounter
(
prometheus
.
CounterOpts
{
Subsystem
:
S
chedulerSubsystem
,
Subsystem
:
s
chedulerSubsystem
,
Name
:
"total_preemption_attempts"
,
Help
:
"Total preemption attempts in the cluster till now"
,
})
metricsList
=
[]
prometheus
.
Collector
{
SchedulingLatency
,
SchedulingAlgorithmPredicateEvaluationDuration
,
SchedulingAlgorithmPriorityEvaluationDuration
,
SchedulingAlgorithmPremptionEvaluationDuration
,
PreemptionVictims
,
PreemptionAttempts
,
}
)
var
registerMetrics
sync
.
Once
// Register all metrics.
func
Register
()
{
// Register the metrics.
registerMetrics
.
Do
(
func
()
{
for
_
,
metric
:=
range
metricsList
{
prometheus
.
MustRegister
(
metric
)
}
})
}
prometheus
.
MustRegister
(
E2eSchedulingLatency
)
prometheus
.
MustRegister
(
SchedulingAlgorithmLatency
)
prometheus
.
MustRegister
(
BindingLatency
)
// Reset resets metrics
func
Reset
()
{
SchedulingLatency
.
Reset
()
prometheus
.
MustRegister
(
SchedulingAlgorithmPredicateEvaluationDuration
)
prometheus
.
MustRegister
(
SchedulingAlgorithmPriorityEvaluationDuration
)
prometheus
.
MustRegister
(
SchedulingAlgorithmPremptionEvaluationDuration
)
prometheus
.
MustRegister
(
PreemptionVictims
)
prometheus
.
MustRegister
(
PreemptionAttempts
)
})
}
// SinceInMicroseconds gets the time since the specified start in microseconds.
...
...
pkg/scheduler/scheduler.go
View file @
0547bbf7
...
...
@@ -429,7 +429,7 @@ func (sched *Scheduler) bind(assumed *v1.Pod, b *v1.Binding) error {
return
err
}
metrics
.
SchedulingLatency
.
WithLabelValues
(
metrics
.
Binding
)
.
Observe
(
metrics
.
SinceInMicroseconds
(
bindingStart
))
metrics
.
BindingLatency
.
Observe
(
metrics
.
SinceInMicroseconds
(
bindingStart
))
sched
.
config
.
Recorder
.
Eventf
(
assumed
,
v1
.
EventTypeNormal
,
"Scheduled"
,
"Successfully assigned %v/%v to %v"
,
assumed
.
Namespace
,
assumed
.
Name
,
b
.
Target
.
Name
)
return
nil
}
...
...
@@ -461,7 +461,7 @@ func (sched *Scheduler) scheduleOne() {
}
return
}
metrics
.
Scheduling
Latency
.
WithLabelValues
(
metrics
.
SchedulingAlgorithm
)
.
Observe
(
metrics
.
SinceInMicroseconds
(
start
))
metrics
.
Scheduling
AlgorithmLatency
.
Observe
(
metrics
.
SinceInMicroseconds
(
start
))
// Tell the cache to assume that a pod now is running on a given node, even though it hasn't been bound yet.
// This allows us to keep scheduling without waiting on binding to occur.
assumedPod
:=
pod
.
DeepCopy
()
...
...
@@ -496,7 +496,7 @@ func (sched *Scheduler) scheduleOne() {
Name
:
suggestedHost
,
},
})
metrics
.
SchedulingLatency
.
WithLabelValues
(
metrics
.
E2eScheduling
)
.
Observe
(
metrics
.
SinceInMicroseconds
(
start
))
metrics
.
E2eSchedulingLatency
.
Observe
(
metrics
.
SinceInMicroseconds
(
start
))
if
err
!=
nil
{
glog
.
Errorf
(
"Internal error binding pod: (%v)"
,
err
)
}
...
...
test/e2e/framework/BUILD
View file @
0547bbf7
...
...
@@ -72,7 +72,6 @@ go_library(
"//pkg/master/ports:go_default_library",
"//pkg/scheduler/algorithm/predicates:go_default_library",
"//pkg/scheduler/cache:go_default_library",
"//pkg/scheduler/metrics:go_default_library",
"//pkg/security/podsecuritypolicy/seccomp:go_default_library",
"//pkg/ssh:go_default_library",
"//pkg/util/file:go_default_library",
...
...
test/e2e/framework/metrics_util.go
View file @
0547bbf7
...
...
@@ -32,7 +32,6 @@ import (
"k8s.io/apimachinery/pkg/util/sets"
clientset
"k8s.io/client-go/kubernetes"
"k8s.io/kubernetes/pkg/master/ports"
schedulermetric
"k8s.io/kubernetes/pkg/scheduler/metrics"
"k8s.io/kubernetes/pkg/util/system"
"k8s.io/kubernetes/test/e2e/framework/metrics"
...
...
@@ -131,8 +130,6 @@ func (m *MetricsForE2E) SummaryKind() string {
return
"MetricsForE2E"
}
var
SchedulingLatencyMetricName
=
model
.
LabelValue
(
schedulermetric
.
SchedulerSubsystem
+
"_"
+
schedulermetric
.
SchedulingLatencyName
)
var
InterestingApiServerMetrics
=
[]
string
{
"apiserver_request_count"
,
"apiserver_request_latencies_summary"
,
...
...
@@ -445,29 +442,27 @@ func getMetrics(c clientset.Interface) (string, error) {
return
string
(
body
),
nil
}
// Sends REST request to kube scheduler metrics
func
sendRestRequestToScheduler
(
c
clientset
.
Interface
,
op
string
)
(
string
,
error
)
{
opUpper
:=
strings
.
ToUpper
(
op
)
if
opUpper
!=
"GET"
&&
opUpper
!=
"DELETE"
{
return
""
,
fmt
.
Errorf
(
"Unknown REST request"
)
}
// Retrieves scheduler latency metrics.
func
getSchedulingLatency
(
c
clientset
.
Interface
)
(
*
SchedulingMetrics
,
error
)
{
result
:=
SchedulingMetrics
{}
// Check if master Node is registered
nodes
,
err
:=
c
.
CoreV1
()
.
Nodes
()
.
List
(
metav1
.
ListOptions
{})
ExpectNoError
(
err
)
var
data
string
var
masterRegistered
=
false
for
_
,
node
:=
range
nodes
.
Items
{
if
system
.
IsMasterNode
(
node
.
Name
)
{
masterRegistered
=
true
}
}
var
responseText
string
if
masterRegistered
{
ctx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
SingleCallTimeout
)
defer
cancel
()
body
,
err
:=
c
.
CoreV1
()
.
RESTClient
()
.
Verb
(
opUpper
)
.
var
rawData
[]
byte
rawData
,
err
=
c
.
CoreV1
()
.
RESTClient
()
.
Get
()
.
Context
(
ctx
)
.
Namespace
(
metav1
.
NamespaceSystem
)
.
Resource
(
"pods"
)
.
...
...
@@ -477,46 +472,33 @@ func sendRestRequestToScheduler(c clientset.Interface, op string) (string, error
Do
()
.
Raw
()
ExpectNoError
(
err
)
responseText
=
string
(
body
)
data
=
string
(
rawData
)
}
else
{
// If master is not registered fall back to old method of using SSH.
if
TestContext
.
Provider
==
"gke"
{
Logf
(
"Not grabbing scheduler metrics through master SSH: unsupported for gke"
)
return
""
,
nil
return
nil
,
nil
}
cmd
:=
"curl -X "
+
opUpper
+
" http://localhost:10251/metrics"
cmd
:=
"curl http://localhost:10251/metrics"
sshResult
,
err
:=
SSH
(
cmd
,
GetMasterHost
()
+
":22"
,
TestContext
.
Provider
)
if
err
!=
nil
||
sshResult
.
Code
!=
0
{
return
""
,
fmt
.
Errorf
(
"unexpected error (code: %d) in ssh connection to master: %#v"
,
sshResult
.
Code
,
err
)
return
&
result
,
fmt
.
Errorf
(
"unexpected error (code: %d) in ssh connection to master: %#v"
,
sshResult
.
Code
,
err
)
}
responseText
=
sshResult
.
Stdout
data
=
sshResult
.
Stdout
}
return
responseText
,
nil
}
// Retrieves scheduler latency metrics.
func
getSchedulingLatency
(
c
clientset
.
Interface
)
(
*
SchedulingMetrics
,
error
)
{
result
:=
SchedulingMetrics
{}
data
,
err
:=
sendRestRequestToScheduler
(
c
,
"GET"
)
samples
,
err
:=
extractMetricSamples
(
data
)
if
err
!=
nil
{
return
nil
,
err
}
for
_
,
sample
:=
range
samples
{
if
sample
.
Metric
[
model
.
MetricNameLabel
]
!=
SchedulingLatencyMetricName
{
continue
}
var
metric
*
LatencyMetric
=
nil
switch
sample
.
Metric
[
schedulermetric
.
Operation
Label
]
{
case
schedulermetric
.
SchedulingAlgorithm
:
switch
sample
.
Metric
[
model
.
MetricName
Label
]
{
case
"scheduler_scheduling_algorithm_latency_microseconds"
:
metric
=
&
result
.
SchedulingLatency
case
schedulermetric
.
Binding
:
case
"scheduler_binding_latency_microseconds"
:
metric
=
&
result
.
BindingLatency
case
schedulermetric
.
E2eScheduling
:
case
"scheduler_e2e_scheduling_latency_microseconds"
:
metric
=
&
result
.
E2ELatency
}
if
metric
==
nil
{
...
...
@@ -528,7 +510,7 @@ func getSchedulingLatency(c clientset.Interface) (*SchedulingMetrics, error) {
if
err
!=
nil
{
return
nil
,
err
}
setQuantile
(
metric
,
quantile
,
time
.
Duration
(
int64
(
latency
)))
setQuantile
(
metric
,
quantile
,
time
.
Duration
(
int64
(
latency
))
*
time
.
Microsecond
)
}
return
&
result
,
nil
}
...
...
@@ -542,14 +524,6 @@ func VerifySchedulerLatency(c clientset.Interface) (*SchedulingMetrics, error) {
return
latency
,
nil
}
func
ResetSchedulerMetrics
(
c
clientset
.
Interface
)
error
{
responseText
,
err
:=
sendRestRequestToScheduler
(
c
,
"DELETE"
)
if
err
!=
nil
||
responseText
!=
"metrics reset
\n
"
{
return
fmt
.
Errorf
(
"Unexpected response: %q"
,
responseText
)
}
return
nil
}
func
PrettyPrintJSON
(
metrics
interface
{})
string
{
output
:=
&
bytes
.
Buffer
{}
if
err
:=
json
.
NewEncoder
(
output
)
.
Encode
(
metrics
);
err
!=
nil
{
...
...
test/e2e/scalability/density.go
View file @
0547bbf7
...
...
@@ -413,6 +413,8 @@ var _ = SIGDescribe("Density", func() {
}
// Verify scheduler metrics.
// TODO: Reset metrics at the beginning of the test.
// We should do something similar to how we do it for APIserver.
latency
,
err
:=
framework
.
VerifySchedulerLatency
(
c
)
framework
.
ExpectNoError
(
err
)
if
err
==
nil
{
...
...
@@ -467,7 +469,6 @@ var _ = SIGDescribe("Density", func() {
uuid
=
string
(
utiluuid
.
NewUUID
())
framework
.
ExpectNoError
(
framework
.
ResetSchedulerMetrics
(
c
))
framework
.
ExpectNoError
(
framework
.
ResetMetrics
(
c
))
framework
.
ExpectNoError
(
os
.
Mkdir
(
fmt
.
Sprintf
(
framework
.
TestContext
.
OutputDir
+
"/%s"
,
uuid
),
0777
))
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment