Monitoring Master Node Components Using Prometheus
This section describes how to use Prometheus to monitor the kube-apiserver, kube-controller, kube-scheduler and etcd-server components on the master nodes.
Collecting the Metrics of Master Node Components Using Self-Built Prometheus
This section describes how to collect the metrics of master node components using self-built Prometheus.

- The cluster version must be 1.19 or later.
- You need to install self-built Prometheus using Helm by referring to Prometheus. You need to use prometheus-operator to manage the installed Prometheus by referring to Prometheus Operator.
Because the Prometheus add-on (Prometheus) is end of maintenance and does not support this function, you are advised not to use this add-on.
- Use kubectl to connect to the cluster.
- Modify the ClusterRole of Prometheus.
kubectl edit ClusterRole prometheus -n {namespace}
Add the following content under the rules field:rules: ... - apiGroups: - proxy.exporter.k8s.io resources: - "*" verbs: ["get", "list", "watch"]
- Create a file named kube-apiserver.yaml and edit it.
vi kube-apiserver.yaml
Example file content:apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: labels: app.kubernetes.io/name: apiserver name: kube-apiserver namespace: monitoring # Change it to the namespace where Prometheus will be installed. spec: endpoints: - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token interval: 30s metricRelabelings: - action: keep regex: (aggregator_unavailable_apiservice|apiserver_admission_controller_admission_duration_seconds_bucket|apiserver_admission_webhook_admission_duration_seconds_bucket|apiserver_admission_webhook_admission_duration_seconds_count|apiserver_client_certificate_expiration_seconds_bucket|apiserver_client_certificate_expiration_seconds_count|apiserver_current_inflight_requests|apiserver_request_duration_seconds_bucket|apiserver_request_total|go_goroutines|kubernetes_build_info|process_cpu_seconds_total|process_resident_memory_bytes|rest_client_requests_total|workqueue_adds_total|workqueue_depth|workqueue_queue_duration_seconds_bucket|aggregator_unavailable_apiservice_total|rest_client_request_duration_seconds_bucket) sourceLabels: - __name__ - action: drop regex: apiserver_request_duration_seconds_bucket;(0.15|0.25|0.3|0.35|0.4|0.45|0.6|0.7|0.8|0.9|1.25|1.5|1.75|2.5|3|3.5|4.5|6|7|8|9|15|25|30|50) sourceLabels: - __name__ - le port: https scheme: https tlsConfig: caFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt serverName: kubernetes jobLabel: component namespaceSelector: matchNames: - default selector: matchLabels: component: apiserver provider: kubernetes
Create a ServiceMonitor:
kubectl apply -f kube-apiserver.yaml
- Create a file named kube-controller.yaml and edit it.
vi kube-controller.yaml
Example file content:apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: labels: app.kubernetes.io/name: kube-controller name: kube-controller-manager namespace: monitoring # Change it to the namespace where Prometheus will be installed. spec: endpoints: - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token interval: 15s honorLabels: true port: https relabelings: - regex: (.+) replacement: /apis/proxy.exporter.k8s.io/v1beta1/kube-controller-proxy/${1}/metrics sourceLabels: - __address__ targetLabel: __metrics_path__ - regex: (.+) replacement: ${1} sourceLabels: - __address__ targetLabel: instance - replacement: kubernetes.default.svc.cluster.local:443 targetLabel: __address__ scheme: https tlsConfig: caFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt jobLabel: app namespaceSelector: matchNames: - kube-system selector: matchLabels: app: kube-controller-proxy version: v1
Create a ServiceMonitor:
kubectl apply -f kube-controller.yaml
- Create a file named kube-scheduler.yaml and edit it.
vi kube-scheduler.yaml
Example file content:apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: labels: app.kubernetes.io/name: kube-scheduler name: kube-scheduler namespace: monitoring # Change it to the namespace where Prometheus will be installed. spec: endpoints: - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token interval: 15s honorLabels: true port: https relabelings: - regex: (.+) replacement: /apis/proxy.exporter.k8s.io/v1beta1/kube-scheduler-proxy/${1}/metrics sourceLabels: - __address__ targetLabel: __metrics_path__ - regex: (.+) replacement: ${1} sourceLabels: - __address__ targetLabel: instance - replacement: kubernetes.default.svc.cluster.local:443 targetLabel: __address__ scheme: https tlsConfig: caFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt jobLabel: app namespaceSelector: matchNames: - kube-system selector: matchLabels: app: kube-scheduler-proxy version: v1
Create a ServiceMonitor:
kubectl apply -f kube-scheduler.yaml
- Create a file named etcd-server.yaml and edit it.
vi etcd-server.yaml
Example file content:apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: labels: app.kubernetes.io/name: etcd-server name: etcd-server namespace: monitoring # Change it to the namespace where Prometheus will be installed. spec: endpoints: - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token interval: 15s honorLabels: true port: https relabelings: - regex: (.+) replacement: /apis/proxy.exporter.k8s.io/v1beta1/etcd-server-proxy/${1}/metrics sourceLabels: - __address__ targetLabel: __metrics_path__ - regex: (.+) replacement: ${1} sourceLabels: - __address__ targetLabel: instance - replacement: kubernetes.default.svc.cluster.local:443 targetLabel: __address__ scheme: https tlsConfig: caFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt jobLabel: app namespaceSelector: matchNames: - kube-system selector: matchLabels: app: etcd-server-proxy version: v1
Create a ServiceMonitor:
kubectl apply -f etcd-server.yaml
- Access Prometheus and choose Status > Targets.
The preceding master node components are displayed.
kube-apiserver Metrics
Category |
Metric |
Type |
Description |
Example PromQL Statement |
---|---|---|---|---|
Request metrics |
apiserver_request_total |
Counter |
The total number of API requests received by kube-apiserver, broken down by labels. Example labels:
|
|
apiserver_request_duration_seconds_bucket |
Histogram |
Response latency distribution, broken down by labels (such as request type, resource, and status code). This metric can be used to analyze P50, P90, and P99 latencies, identify slow requests and high-latency resources, and monitor kube-apiserver performance. Example labels:
|
|
|
apiserver_current_inflight_requests |
Gauge |
The number of API requests that are being executed. This metric typically contains the following labels:
|
|
|
etcd_request_duration_seconds_bucket |
Histogram |
etcd request latency. Example labels:
|
|
|
Error and rate limiting metrics |
apiserver_flowcontrol_current_executing_requests |
Gauge |
One of the core metrics in API Priority and Fairness (APF). It reflects the number of requests being executed by the API server in real time. For details, see API Priority and Fairness. Example labels:
|
|
apiserver_flowcontrol_current_inqueue_requests |
Gauge |
The number of requests waiting to be executed in the flow control queue. These requests have been received but are not executed because the number of concurrent requests has reached the configured limit. For details, see API Priority and Fairness. Example labels:
|
||
apiserver_flowcontrol_nominal_limit_seats |
Gauge |
The nominal request concurrency limit per priority level. For details, see API Priority and Fairness. This metric is classified by the priority_level label, which indicates the request priority level (such as system or workload-high). |
|
|
apiserver_flowcontrol_current_limit_seats |
Gauge |
The request concurrency limit per priority level. This metric allows you to learn the load of the API server and determine whether to adjust the traffic control policy in high-load scenarios. For details, see API Priority and Fairness. Unlike nominal_limit_seats, the value of this metric may be affected by the global traffic control policy. This metric is classified by the priority_level label, which indicates the request priority level (such as system or workload-high). |
To view the request concurrency limit at a priority level:
apiserver_flowcontrol_current_limit_seats{priority_level="system"} |
|
apiserver_flowcontrol_current_executing_seats |
Gauge |
The number of seats corresponding to the requests currently being executed in a priority queue. This metric reflects the concurrent resources being consumed in the queue and helps you understand the actual load of the queue. For details, see API Priority and Fairness. This metric is classified by the priority_level label, which indicates the request priority level (such as system or workload-high). If the value of current_executing_seats is close to that of current_limit_seats, the concurrent resources of the queue may be about to be used up. You can increase the values of max-mutating-requests-inflight and max-requests-inflight to optimize the configuration. For details, see Modifying Cluster Configurations. |
|
|
apiserver_flowcontrol_current_inqueue_seats |
Gauge |
The concurrent resources consumed by the requests waiting in queues for all priority levels. For details, see API Priority and Fairness. This metric is classified by the priority_level label, which indicates the request priority level (such as system or workload-high). |
|
|
apiserver_flowcontrol_request_execution_seconds_bucket |
Histogram |
The execution time of API requests. For details, see API Priority and Fairness. Example labels:
|
|
|
apiserver_flowcontrol_request_wait_duration_seconds_bucket |
Histogram |
The waiting time of API requests in a queue. For details, see API Priority and Fairness. Example labels:
|
|
|
apiserver_flowcontrol_dispatched_requests_total |
Counter |
The total number of API requests that have been scheduled (started to be executed). For details, see API Priority and Fairness. |
|
|
apiserver_flowcontrol_rejected_requests_total |
Counter |
The total number of rejected API requests. Requests are often rejected due to traffic control or insufficient resources. For details, see API Priority and Fairness. Example labels:
|
|
|
apiserver_flowcontrol_request_concurrency_limit |
Gauge |
The maximum number of concurrent requests for a priority queue. This metric is deprecated in Kubernetes 1.30 and removed from Kubernetes 1.31. You are advised to use apiserver_flowcontrol_nominal_limit_seats in clusters of v1.31 or later. |
To view the current global concurrency limit: apiserver_flowcontrol_request_concurrency_limit |
|
Authentication and authorization metrics |
apiserver_admission_controller_admission_duration_seconds_bucket |
Histogram |
The time that the admission controller takes to process API requests. Example labels:
|
|
apiserver_admission_webhook_admission_duration_seconds_bucket |
Histogram |
The time that the admission webhook takes to process requests. |
To calculate the processing time for 99% of requests: histogram_quantile(0.99,sum(rate(apiserver_admission_webhook_admission_duration_seconds_bucket[5m])) by (le, name)) |
|
Service availability metrics |
up |
Gauge |
Service availability. Options:
|
To check the availability of the current service: up |
kube-controller Metrics
Metric |
Type |
Description |
Example PromQL Statement |
---|---|---|---|
workqueue_adds_total |
Counter |
The number of adds processed by the workqueue. |
|
workqueue_depth |
Gauge |
How big the workqueue is. If the queue depth remains high for a long time, the controller cannot process tasks in the queue in a timely manner, causing task stacking. |
To view the depths of all queues:
workqueue_depth |
workqueue_queue_duration_seconds_bucket |
Histogram |
How long in seconds a task stays in the workqueue before being executed. Example labels:
|
|
rest_client_requests_total |
Counter |
The number of HTTP requests initiated by the Kubernetes client. Example labels:
|
|
rest_client_request_duration_seconds_bucket |
Histogram |
The latency of HTTP requests from the client. Example labels:
|
|
kube-scheduler Metrics
Metric |
Type |
Description |
Example PromQL Statement |
---|---|---|---|
scheduler_scheduler_cache_size |
Gauge |
The number of nodes, pods, and assumed pods (pods to be scheduled) in the scheduler cache. |
To view the number of cached pods: scheduler_scheduler_cache_size{type="pod"} |
scheduler_pending_pods |
Gauge |
The number of pending pods. This metric can be used to identify scheduling bottlenecks. This metric is usually classified by the following queue labels:
|
To view the number of pods in a specific queue: scheduler_pending_pods{queue="backoff"} |
scheduler_pod_scheduling_attempts_bucket |
Histogram |
The number of attempts to schedule a pod. Generally, this metric is labeled by le. The value can be 1, 2, 4, 8, 16, or +Inf. |
To detect high-frequency retries (more than eight attempts):
sum(rate(scheduler_pod_scheduling_attempts_bucket{le="+Inf"}[5m]))- sum(rate(scheduler_pod_scheduling_attempts_bucket{le="8"}[5m])) |
etcd-server Metrics
Category |
Metric |
Type |
Description |
Example PromQL Statement |
---|---|---|---|---|
etcd leader status metrics |
etcd_server_has_leader |
Gauge |
etcd elects a member in a cluster as the leader (master node) and other members as followers (slave nodes). The leader periodically sends heartbeats to all members for cluster stability. This metric controls whether there is a leader among the etcd servers. Options:
|
To view the leader status: etcd_server_has_leader |
etcd_server_is_leader |
Gauge |
Whether an etcd member is the leader. Options:
|
To check whether an etcd member is the leader: etcd_server_is_leader |
|
etcd_server_leader_changes_seen_total |
Counter |
The number of leader changes within a specific period of time. |
To monitor the leader change frequency within 1 hour: rate(etcd_server_leader_changes_seen_total[1h]) |
|
etcd storage metrics |
etcd_mvcc_db_total_size_in_bytes |
Gauge |
The total size of the etcd. |
To calculate the storage space usage: etcd_mvcc_db_total_size_in_use_in_bytes / etcd_mvcc_db_total_size_in_bytes |
etcd_mvcc_db_total_size_in_use_in_bytes |
Gauge |
The usage of the etcd. |
||
etcd_debugging_mvcc_keys_total |
Gauge |
The total number of keys in the etcd. |
To monitor the increase of keys: rate(etcd_debugging_mvcc_keys_total[5m]) |
|
etcd write performance metrics |
etcd_disk_backend_commit_duration_seconds_bucket |
Histogram |
Time required by the etcd for data at rest. This is the time that the etcd takes to write a data change to the storage backend and commit data. |
To calculate the P99 latency for writes: histogram_quantile(0.99,rate(etcd_disk_backend_commit_duration_seconds_bucket[5m])) |
etcd_server_proposals_committed_total |
Gauge |
The number of proposals submitted by the etcd. |
To calculate the write failure rate: rate(etcd_server_proposals_failed_total[5m]) / rate(etcd_server_proposals_committed_total[5m]) |
|
etcd_server_proposals_applied_total |
Gauge |
The number of applied or executed proposals. |
To calculate the write success rate: rate(etcd_server_proposals_applied_total[5m]) / rate(etcd_server_proposals_committed_total[5m]) |
|
etcd_server_proposals_pending |
Gauge |
The number of pending proposals. |
To detect the stacked writes: etcd_server_proposals_pending |
|
etcd_server_proposals_failed_total |
Counter |
The number of failed proposals. |
To calculate the write failure rate: rate(etcd_server_proposals_failed_total[5m]) / rate(etcd_server_proposals_committed_total[5m]) |
Helpful Link
For more information about Kubernetes system component metrics, see Kubernetes Metrics Reference.
Feedback
Was this page helpful?
Provide feedbackThank you very much for your feedback. We will continue working to improve the documentation.