Commit 148588e6 authored by Random-Liu's avatar Random-Liu

1) Add docker operation timeout metrics.

2) Cleanup kubelet stats and add runtime operation error and timeout rate monitoring. 3) Monitor runtime operation error and timeout rate in kubelet perf.
parent 66678354
...@@ -38,13 +38,18 @@ func newInstrumentedDockerInterface(dockerClient DockerInterface) DockerInterfac ...@@ -38,13 +38,18 @@ func newInstrumentedDockerInterface(dockerClient DockerInterface) DockerInterfac
// recordOperation records the duration of the operation. // recordOperation records the duration of the operation.
func recordOperation(operation string, start time.Time) { func recordOperation(operation string, start time.Time) {
metrics.DockerOperations.WithLabelValues(operation).Inc()
metrics.DockerOperationsLatency.WithLabelValues(operation).Observe(metrics.SinceInMicroseconds(start)) metrics.DockerOperationsLatency.WithLabelValues(operation).Observe(metrics.SinceInMicroseconds(start))
} }
// recordError records error for metric if an error occurred. // recordError records error for metric if an error occurred.
func recordError(operation string, err error) { func recordError(operation string, err error) {
if err != nil { if err != nil {
metrics.DockerErrors.WithLabelValues(operation).Inc() if _, ok := err.(operationTimeout); ok {
metrics.DockerOperationsTimeout.WithLabelValues(operation).Inc()
}
// Docker operation timeout error is also a docker error, so we don't add else here.
metrics.DockerOperationsErrors.WithLabelValues(operation).Inc()
} }
} }
......
...@@ -32,8 +32,10 @@ const ( ...@@ -32,8 +32,10 @@ const (
PodStartLatencyKey = "pod_start_latency_microseconds" PodStartLatencyKey = "pod_start_latency_microseconds"
PodStatusLatencyKey = "generate_pod_status_latency_microseconds" PodStatusLatencyKey = "generate_pod_status_latency_microseconds"
ContainerManagerOperationsKey = "container_manager_latency_microseconds" ContainerManagerOperationsKey = "container_manager_latency_microseconds"
DockerOperationsKey = "docker_operations_latency_microseconds" DockerOperationsLatencyKey = "docker_operations_latency_microseconds"
DockerErrorsKey = "docker_errors" DockerOperationsKey = "docker_operations"
DockerOperationsErrorsKey = "docker_operations_errors"
DockerOperationsTimeoutKey = "docker_operations_timeout"
PodWorkerStartLatencyKey = "pod_worker_start_latency_microseconds" PodWorkerStartLatencyKey = "pod_worker_start_latency_microseconds"
PLEGRelistLatencyKey = "pleg_relist_latency_microseconds" PLEGRelistLatencyKey = "pleg_relist_latency_microseconds"
PLEGRelistIntervalKey = "pleg_relist_interval_microseconds" PLEGRelistIntervalKey = "pleg_relist_interval_microseconds"
...@@ -94,16 +96,32 @@ var ( ...@@ -94,16 +96,32 @@ var (
DockerOperationsLatency = prometheus.NewSummaryVec( DockerOperationsLatency = prometheus.NewSummaryVec(
prometheus.SummaryOpts{ prometheus.SummaryOpts{
Subsystem: KubeletSubsystem, Subsystem: KubeletSubsystem,
Name: DockerOperationsKey, Name: DockerOperationsLatencyKey,
Help: "Latency in microseconds of Docker operations. Broken down by operation type.", Help: "Latency in microseconds of Docker operations. Broken down by operation type.",
}, },
[]string{"operation_type"}, []string{"operation_type"},
) )
DockerErrors = prometheus.NewCounterVec( DockerOperations = prometheus.NewCounterVec(
prometheus.CounterOpts{
Subsystem: KubeletSubsystem,
Name: DockerOperationsKey,
Help: "Cumulative number of Docker operations by operation type.",
},
[]string{"operation_type"},
)
DockerOperationsErrors = prometheus.NewCounterVec(
prometheus.CounterOpts{
Subsystem: KubeletSubsystem,
Name: DockerOperationsErrorsKey,
Help: "Cumulative number of Docker operation errors by operation type.",
},
[]string{"operation_type"},
)
DockerOperationsTimeout = prometheus.NewCounterVec(
prometheus.CounterOpts{ prometheus.CounterOpts{
Subsystem: KubeletSubsystem, Subsystem: KubeletSubsystem,
Name: DockerErrorsKey, Name: DockerOperationsTimeoutKey,
Help: "Cumulative number of Docker errors by operation type.", Help: "Cumulative number of Docker operation timeout by operation type.",
}, },
[]string{"operation_type"}, []string{"operation_type"},
) )
...@@ -137,7 +155,9 @@ func Register(containerCache kubecontainer.RuntimeCache) { ...@@ -137,7 +155,9 @@ func Register(containerCache kubecontainer.RuntimeCache) {
prometheus.MustRegister(SyncPodsLatency) prometheus.MustRegister(SyncPodsLatency)
prometheus.MustRegister(PodWorkerStartLatency) prometheus.MustRegister(PodWorkerStartLatency)
prometheus.MustRegister(ContainersPerPodCount) prometheus.MustRegister(ContainersPerPodCount)
prometheus.MustRegister(DockerErrors) prometheus.MustRegister(DockerOperations)
prometheus.MustRegister(DockerOperationsErrors)
prometheus.MustRegister(DockerOperationsTimeout)
prometheus.MustRegister(newPodAndContainerCollector(containerCache)) prometheus.MustRegister(newPodAndContainerCollector(containerCache))
prometheus.MustRegister(PLEGRelistLatency) prometheus.MustRegister(PLEGRelistLatency)
prometheus.MustRegister(PLEGRelistInterval) prometheus.MustRegister(PLEGRelistInterval)
......
...@@ -134,7 +134,6 @@ func parseMetrics(data string, knownMetrics map[string][]string, output *Metrics ...@@ -134,7 +134,6 @@ func parseMetrics(data string, knownMetrics map[string][]string, output *Metrics
if isKnownMetric || isCommonMetric { if isKnownMetric || isCommonMetric {
(*output)[name] = append((*output)[name], metric) (*output)[name] = append((*output)[name], metric)
} else { } else {
glog.Warningf("Unknown metric %v", metric)
if unknownMetrics != nil { if unknownMetrics != nil {
unknownMetrics.Insert(name) unknownMetrics.Insert(name)
} }
......
...@@ -18,6 +18,8 @@ package metrics ...@@ -18,6 +18,8 @@ package metrics
import ( import (
"fmt" "fmt"
"io/ioutil"
"net/http"
"time" "time"
"k8s.io/kubernetes/pkg/util/sets" "k8s.io/kubernetes/pkg/util/sets"
...@@ -71,7 +73,9 @@ var NecessaryKubeletMetrics = map[string][]string{ ...@@ -71,7 +73,9 @@ var NecessaryKubeletMetrics = map[string][]string{
"kubelet_containers_per_pod_count": {"quantile"}, "kubelet_containers_per_pod_count": {"quantile"},
"kubelet_containers_per_pod_count_count": {}, "kubelet_containers_per_pod_count_count": {},
"kubelet_containers_per_pod_count_sum": {}, "kubelet_containers_per_pod_count_sum": {},
"kubelet_docker_errors": {"operation_type"}, "kubelet_docker_operations": {"operation_type"},
"kubelet_docker_operations_errors": {"operation_type"},
"kubelet_docker_operations_timeout": {"operation_type"},
"kubelet_docker_operations_latency_microseconds": {"operation_type", "quantile"}, "kubelet_docker_operations_latency_microseconds": {"operation_type", "quantile"},
"kubelet_docker_operations_latency_microseconds_count": {"operation_type"}, "kubelet_docker_operations_latency_microseconds_count": {"operation_type"},
"kubelet_docker_operations_latency_microseconds_sum": {"operation_type"}, "kubelet_docker_operations_latency_microseconds_sum": {"operation_type"},
...@@ -126,6 +130,22 @@ func NewKubeletMetrics() KubeletMetrics { ...@@ -126,6 +130,22 @@ func NewKubeletMetrics() KubeletMetrics {
return KubeletMetrics(result) return KubeletMetrics(result)
} }
// GrabKubeletMetricsWithoutProxy retrieve metrics from the kubelet on the given node using a simple GET over http.
// Currently only used in integration tests.
func GrabKubeletMetricsWithoutProxy(nodeName string) (KubeletMetrics, error) {
metricsEndpoint := "http://%s/metrics"
resp, err := http.Get(fmt.Sprintf(metricsEndpoint, nodeName))
if err != nil {
return KubeletMetrics{}, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return KubeletMetrics{}, err
}
return parseKubeletMetrics(string(body))
}
func parseKubeletMetrics(data string) (KubeletMetrics, error) { func parseKubeletMetrics(data string) (KubeletMetrics, error) {
result := NewKubeletMetrics() result := NewKubeletMetrics()
if err := parseMetrics(data, NecessaryKubeletMetrics, (*Metrics)(&result), nil); err != nil { if err := parseMetrics(data, NecessaryKubeletMetrics, (*Metrics)(&result), nil); err != nil {
......
...@@ -189,6 +189,7 @@ func verifyCPULimits(expected framework.ContainersCPUSummary, actual framework.N ...@@ -189,6 +189,7 @@ func verifyCPULimits(expected framework.ContainersCPUSummary, actual framework.N
var _ = framework.KubeDescribe("Kubelet [Serial] [Slow]", func() { var _ = framework.KubeDescribe("Kubelet [Serial] [Slow]", func() {
var nodeNames sets.String var nodeNames sets.String
f := framework.NewDefaultFramework("kubelet-perf") f := framework.NewDefaultFramework("kubelet-perf")
var om *framework.RuntimeOperationMonitor
var rm *framework.ResourceMonitor var rm *framework.ResourceMonitor
BeforeEach(func() { BeforeEach(func() {
...@@ -197,12 +198,15 @@ var _ = framework.KubeDescribe("Kubelet [Serial] [Slow]", func() { ...@@ -197,12 +198,15 @@ var _ = framework.KubeDescribe("Kubelet [Serial] [Slow]", func() {
for _, node := range nodes.Items { for _, node := range nodes.Items {
nodeNames.Insert(node.Name) nodeNames.Insert(node.Name)
} }
om = framework.NewRuntimeOperationMonitor(f.Client)
rm = framework.NewResourceMonitor(f.Client, framework.TargetContainers(), containerStatsPollingPeriod) rm = framework.NewResourceMonitor(f.Client, framework.TargetContainers(), containerStatsPollingPeriod)
rm.Start() rm.Start()
}) })
AfterEach(func() { AfterEach(func() {
rm.Stop() rm.Stop()
result := om.GetLatestRuntimeOperationErrorRate()
framework.Logf("runtime operation error metrics:\n%s", framework.FormatRuntimeOperationErrorRate(result))
}) })
framework.KubeDescribe("regular resource usage tracking", func() { framework.KubeDescribe("regular resource usage tracking", func() {
// We assume that the scheduler will make reasonable scheduling choices // We assume that the scheduler will make reasonable scheduling choices
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment