All Products
Search
Document Center

Container Service for Kubernetes:Configure Prometheus monitoring for KServe

Last Updated:Jun 25, 2026

KServe provides default Prometheus metrics to monitor model service performance and health. This topic explains how to configure Prometheus monitoring for KServe.

Prerequisites

Step 1: Deploy KServe application

  1. Deploy a Scikit-learn KServe application:

    arena serve kserve \
        --name=sklearn-iris \
        --image=kube-ai-registry.cn-shanghai.cr.aliyuncs.com/ai-sample/kserve-sklearn-server:v0.12.0 \
        --cpu=1 \
        --memory=200Mi \
        --enable-prometheus=true \
        --metrics-port=8080 \
        "python -m sklearnserver --model_name=sklearn-iris --model_dir=/models --http_port=8080"

    Expected output:

    service/sklearn-iris-metric-svc created # A service named sklearn-iris-metric-svc is created.
    inferenceservice.serving.kserve.io/sklearn-iris created # The KServe InferenceService resource sklearn-iris is created.
    servicemonitor.monitoring.coreos.com/sklearn-iris-svcmonitor created # A ServiceMonitor resource is created to integrate with the Prometheus monitoring system and collect monitoring data exposed by the sklearn-iris-metric-svc service.
    INFO[0004] The Job sklearn-iris has been submitted successfully # The job is successfully submitted to the cluster.
    INFO[0004] You can run `arena serve get sklearn-iris --type kserve -n default` to check the job status

    Arena deployed a KServe service with a scikit-learn model and Prometheus monitoring.

  2. Write the inference input to an ./iris-input.json file:

    cat <<EOF > "./iris-input.json"
    {
      "instances": [
        [6.8,  2.8,  4.8,  1.4],
        [6.0,  3.4,  4.5,  1.6]
      ]
    }
    EOF
  3. Retrieve the NGINX Ingress gateway IP address and InferenceService hostname:

    NGINX_INGRESS_IP=`kubectl -n kube-system get svc nginx-ingress-lb -ojsonpath='{.status.loadBalancer.ingress[0].ip}'`
    SERVICE_HOSTNAME=$(kubectl get inferenceservice sklearn-iris -o jsonpath='{.status.url}' | cut -d "/" -f 3)
  4. Use the Hey stress testing tool to send repeated requests and generate monitoring data:

    Note

    See Hey.

    hey -z 2m -c 20 -m POST -host $SERVICE_HOSTNAME -H "Content-Type: application/json" -D ./iris-input.json http://${NGINX_INGRESS_IP}:80/v1/models/sklearn-iris:predict

    Expected output:

    Expected output

    Summary:
      Total:	120.0296 secs
      Slowest:	0.1608 secs
      Fastest:	0.0213 secs
      Average:	0.0275 secs
      Requests/sec:	727.3875
      Total data:	1833468 bytes
      Size/request:	21 bytes
    Response time histogram:
      0.021 [1]	|
      0.035 [85717]	|■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
      0.049 [1272]	|■
      0.063 [144]	|
      0.077 [96]	|
      0.091 [44]	|
      0.105 [7]	|
      0.119 [0]	|
      0.133 [0]	|
      0.147 [11]	|
      0.161 [16]	|
    Latency distribution:
      10% in 0.0248 secs
      25% in 0.0257 secs
      50% in 0.0270 secs
      75% in 0.0285 secs
      90% in 0.0300 secs
      95% in 0.0315 secs
      99% in 0.0381 secs
    Details (average, fastest, slowest):
      DNS+dialup:	0.0000 secs, 0.0213 secs, 0.1608 secs
      DNS-lookup:	0.0000 secs, 0.0000 secs, 0.0000 secs
      req write:	0.0000 secs, 0.0000 secs, 0.0225 secs
      resp wait:	0.0273 secs, 0.0212 secs, 0.1607 secs
      resp read:	0.0001 secs, 0.0000 secs, 0.0558 secs
    Status code distribution:
      [200]	87308 responses

    The output shows performance metrics such as processing speed, throughput, and response latency.

  5. (Optional) Verify that application metrics are exposed correctly.

    Collect monitoring metrics from the sklearn-iris Pod locally, without logging on to the Pod or exposing its port.

    1. Forward port 8080 from the sklearn-iris Pod (specified by $POD_NAME) to your local host:

      # Get the Pod name.
      POD_NAME=`kubectl get po|grep sklearn-iris |awk -F ' ' '{print $1}'`
      # Forward port 8080 of the pod to the local host.
      kubectl port-forward pod/$POD_NAME 8080:8080

      Expected output:

      Forwarding from 127.0.0.1:8080 -> 8080
      Forwarding from [::1]:8080 -> 8080

      Both IPv4 and IPv6 connections are forwarded to the Pod's port 8080.

    2. Open the following URL in a browser to view Pod metrics:

      http://localhost:8080/metrics

      Expected output:

      Expected output

      # HELP python_gc_objects_collected_total Objects collected during gc
      # TYPE python_gc_objects_collected_total counter
      python_gc_objects_collected_total{generation="0"} 10298.0
      python_gc_objects_collected_total{generation="1"} 1826.0
      python_gc_objects_collected_total{generation="2"} 0.0
      # HELP python_gc_objects_uncollectable_total Uncollectable object found during GC
      # TYPE python_gc_objects_uncollectable_total counter
      python_gc_objects_uncollectable_total{generation="0"} 0.0
      python_gc_objects_uncollectable_total{generation="1"} 0.0
      python_gc_objects_uncollectable_total{generation="2"} 0.0
      # HELP python_gc_collections_total Number of times this generation was collected
      # TYPE python_gc_collections_total counter
      python_gc_collections_total{generation="0"} 660.0
      python_gc_collections_total{generation="1"} 60.0
      python_gc_collections_total{generation="2"} 5.0
      # HELP python_info Python platform information
      # TYPE python_info gauge
      python_info{implementation="CPython",major="3",minor="9",patchlevel="18",version="3.9.18"} 1.0
      # HELP process_virtual_memory_bytes Virtual memory size in bytes.
      # TYPE process_virtual_memory_bytes gauge
      process_virtual_memory_bytes 1.406291968e+09
      # HELP process_resident_memory_bytes Resident memory size in bytes.
      # TYPE process_resident_memory_bytes gauge
      process_resident_memory_bytes 2.73207296e+08
      # HELP process_start_time_seconds Start time of the process since unix epoch in seconds.
      # TYPE process_start_time_seconds gauge
      process_start_time_seconds 1.71533439115e+09
      # HELP process_cpu_seconds_total Total user and system CPU time spent in seconds.
      # TYPE process_cpu_seconds_total counter
      process_cpu_seconds_total 228.18
      # HELP process_open_fds Number of open file descriptors.
      # TYPE process_open_fds gauge
      process_open_fds 16.0
      # HELP process_max_fds Maximum number of open file descriptors.
      # TYPE process_max_fds gauge
      process_max_fds 1.048576e+06
      # HELP request_preprocess_seconds pre-process request latency
      # TYPE request_preprocess_seconds histogram
      request_preprocess_seconds_bucket{le="0.005",model_name="sklearn-iris"} 259709.0
      request_preprocess_seconds_bucket{le="0.01",model_name="sklearn-iris"} 259709.0
      request_preprocess_seconds_bucket{le="0.025",model_name="sklearn-iris"} 259709.0
      request_preprocess_seconds_bucket{le="0.05",model_name="sklearn-iris"} 259709.0
      request_preprocess_seconds_bucket{le="0.075",model_name="sklearn-iris"} 259709.0
      request_preprocess_seconds_bucket{le="0.1",model_name="sklearn-iris"} 259709.0
      request_preprocess_seconds_bucket{le="0.25",model_name="sklearn-iris"} 259709.0
      request_preprocess_seconds_bucket{le="0.5",model_name="sklearn-iris"} 259709.0
      request_preprocess_seconds_bucket{le="0.75",model_name="sklearn-iris"} 259709.0
      request_preprocess_seconds_bucket{le="1.0",model_name="sklearn-iris"} 259709.0
      request_preprocess_seconds_bucket{le="2.5",model_name="sklearn-iris"} 259709.0
      request_preprocess_seconds_bucket{le="5.0",model_name="sklearn-iris"} 259709.0
      request_preprocess_seconds_bucket{le="7.5",model_name="sklearn-iris"} 259709.0
      request_preprocess_seconds_bucket{le="10.0",model_name="sklearn-iris"} 259709.0
      request_preprocess_seconds_bucket{le="+Inf",model_name="sklearn-iris"} 259709.0
      request_preprocess_seconds_count{model_name="sklearn-iris"} 259709.0
      request_preprocess_seconds_sum{model_name="sklearn-iris"} 1.7146860011853278
      # HELP request_preprocess_seconds_created pre-process request latency
      # TYPE request_preprocess_seconds_created gauge
      request_preprocess_seconds_created{model_name="sklearn-iris"} 1.7153354578475933e+09
      # HELP request_postprocess_seconds post-process request latency
      # TYPE request_postprocess_seconds histogram
      request_postprocess_seconds_bucket{le="0.005",model_name="sklearn-iris"} 259709.0
      request_postprocess_seconds_bucket{le="0.01",model_name="sklearn-iris"} 259709.0
      request_postprocess_seconds_bucket{le="0.025",model_name="sklearn-iris"} 259709.0
      request_postprocess_seconds_bucket{le="0.05",model_name="sklearn-iris"} 259709.0
      request_postprocess_seconds_bucket{le="0.075",model_name="sklearn-iris"} 259709.0
      request_postprocess_seconds_bucket{le="0.1",model_name="sklearn-iris"} 259709.0
      request_postprocess_seconds_bucket{le="0.25",model_name="sklearn-iris"} 259709.0
      request_postprocess_seconds_bucket{le="0.5",model_name="sklearn-iris"} 259709.0
      request_postprocess_seconds_bucket{le="0.75",model_name="sklearn-iris"} 259709.0
      request_postprocess_seconds_bucket{le="1.0",model_name="sklearn-iris"} 259709.0
      request_postprocess_seconds_bucket{le="2.5",model_name="sklearn-iris"} 259709.0
      request_postprocess_seconds_bucket{le="5.0",model_name="sklearn-iris"} 259709.0
      request_postprocess_seconds_bucket{le="7.5",model_name="sklearn-iris"} 259709.0
      request_postprocess_seconds_bucket{le="10.0",model_name="sklearn-iris"} 259709.0
      request_postprocess_seconds_bucket{le="+Inf",model_name="sklearn-iris"} 259709.0
      request_postprocess_seconds_count{model_name="sklearn-iris"} 259709.0
      request_postprocess_seconds_sum{model_name="sklearn-iris"} 1.625360683305189
      # HELP request_postprocess_seconds_created post-process request latency
      # TYPE request_postprocess_seconds_created gauge
      request_postprocess_seconds_created{model_name="sklearn-iris"} 1.7153354578482144e+09
      # HELP request_predict_seconds predict request latency
      # TYPE request_predict_seconds histogram
      request_predict_seconds_bucket{le="0.005",model_name="sklearn-iris"} 259708.0
      request_predict_seconds_bucket{le="0.01",model_name="sklearn-iris"} 259708.0
      request_predict_seconds_bucket{le="0.025",model_name="sklearn-iris"} 259709.0
      request_predict_seconds_bucket{le="0.05",model_name="sklearn-iris"} 259709.0
      request_predict_seconds_bucket{le="0.075",model_name="sklearn-iris"} 259709.0
      request_predict_seconds_bucket{le="0.1",model_name="sklearn-iris"} 259709.0
      request_predict_seconds_bucket{le="0.25",model_name="sklearn-iris"} 259709.0
      request_predict_seconds_bucket{le="0.5",model_name="sklearn-iris"} 259709.0
      request_predict_seconds_bucket{le="0.75",model_name="sklearn-iris"} 259709.0
      request_predict_seconds_bucket{le="1.0",model_name="sklearn-iris"} 259709.0
      request_predict_seconds_bucket{le="2.5",model_name="sklearn-iris"} 259709.0
      request_predict_seconds_bucket{le="5.0",model_name="sklearn-iris"} 259709.0
      request_predict_seconds_bucket{le="7.5",model_name="sklearn-iris"} 259709.0
      request_predict_seconds_bucket{le="10.0",model_name="sklearn-iris"} 259709.0
      request_predict_seconds_bucket{le="+Inf",model_name="sklearn-iris"} 259709.0
      request_predict_seconds_count{model_name="sklearn-iris"} 259709.0
      request_predict_seconds_sum{model_name="sklearn-iris"} 47.95311741752084
      # HELP request_predict_seconds_created predict request latency
      # TYPE request_predict_seconds_created gauge
      request_predict_seconds_created{model_name="sklearn-iris"} 1.7153354578476949e+09
      # HELP request_explain_seconds explain request latency
      # TYPE request_explain_seconds histogram

      The output confirms that metrics are exposed and requests are forwarded to the Pod application.

Step 2: Query KServe metrics

  1. Log on to the ARMS console.

  2. In the left-side navigation pane, click Integration Management, and then click Query Dashboards.

  3. On the Dashboards page, click the Kubernetes Pod dashboard to open the Grafana page.

  4. In the left-side navigation pane, click Explore. Enter the request_predict_seconds_bucket query to view metric values.

    Note

    Data may take up to 5 minutes to appear.

    The graph displays a line chart of the request_predict_seconds_bucket metric over time.

FAQ

Question

How can I verify that data for the request_predict_seconds_bucket metric has been collected successfully?

Solution

  1. Log on to the ARMS console.

  2. In Connected Environments, on the Container Service tab, click the target container environment, and then click the Self-Monitoring tab.

  3. In the left-side navigation pane, click Targets. If default/sklearn-iris-svcmonitor/0 (1/1 up) is displayed, metric collection is successful.

References

For default KServe metrics, see KServe Prometheus Metrics.