Showing posts with label Metrics. Show all posts
Showing posts with label Metrics. Show all posts

Monday, 3 August 2026

Prometheus Metrics



The 4 Core Prometheus Metric Types


Prometheus defines four primary metric types. Choosing the right type depends on how the value behaves over time.


                              ┌───────────────────────────┐
                              │ Prometheus Metric Types   │
                              └─────────────┬─────────────┘
                                            │
         ┌───────────────────┬──────────────┴───────────────┬────────────────────┐
         ▼                   ▼                              ▼                    ▼
  ┌──────────────┐    ┌──────────────┐              ┌──────────────┐     ┌──────────────┐
  │    Gauge     │    │   Counter    │              │  Histogram   │     │   Summary    │
  ├──────────────┤    ├──────────────┤              ├──────────────┤     ├──────────────┤
  │ Value goes   │    │ Value ONLY   │              │ Groups values│     │ Calculates   │
  │ UP and DOWN  │    │ increases    │              │ into buckets │     │ quantiles    │
  │ (Snapshot)   │    │ (Cumulative) │              │ (Client-side)│     │ (Client-side)│
  └──────────────┘    └──────────────┘              └──────────────┘     └──────────────┘

1. Gauge


  • Behavior: Can increase, decrease, or stay the same.
  • Use Case: Current state, temperatures, memory usage, concurrent connections, replica counts.
  • PromQL Functions: avg_over_time(), max_over_time(), direct evaluation.

In Prometheus (and OpenMetrics standards), a Gauge is a metric that represents a single numerical value that can arbitrarily go up and down.

It acts like a digital display or a vehicle's speedometer—it gives you a point-in-time snapshot of a current state.

Understanding the Gauge Type


Because a Gauge can fluctuate freely, it is used to measure snapshot values, current state levels, and instantaneous statuses.

  • Example Real-World Analogy: A car's speedometer (can go from 0 to 70 mph, back to 30 mph), ambient temperature, or fuel tank level.
  • Kubernetes/KSM Examples:
    • kube_cronjob_status_last_successful_time: Holds a Unix timestamp (moves forward or stays fixed).
    • kube_deployment_status_replicas_available: Number of ready pods (e.g., 3 → 5 → 2).
    • node_memory_MemAvailable_bytes: Available system memory in bytes.

Key Feature: Instantaneous Operations


Because gauges fluctuate, you do not run rate or increase functions like rate() or increase() on them in PromQL. Instead, you query their current value directly or perform operations like running averages (avg_over_time()), min/max checks, or scalar math (e.g., time() - gauge).



2. Counter


  • Behavior: A cumulative metric that only increases (or resets to 0 upon process restart). It never decreases naturally.
  • Use Case: Counting total occurrences of events (e.g., total HTTP requests served, total pipeline errors, network bytes transmitted).
  • PromQL Functions: rate(), irate(), increase().

Why use a Counter instead of a Gauge? A counter allows PromQL's rate() function to accurately calculate "per-second rates" while automatically handling process restarts (resets).

3. Histogram


  • Behavior: Samples observations (usually things like request durations or payload sizes) and counts them in configurable buckets. It also provides a sum of all observed values.
  • Exposed Data:
    • <basename>_bucket{le="<upper_bound>"}: Counter of observations with value <= upper bound.
    • <basename>_count: Total number of observations (Counter).
    • <basename>_sum: Sum of all observed values (Counter).
  • Use Case: Measuring latencies, response times, or request sizes where you want to calculate percentiles (e.g., p95, p99) on the server side using PromQL (histogram_quantile()).

4. Summary


  • Behavior: Similar to a histogram, but calculates configurable quantiles (e.g., 0.50, 0.90, 0.99) directly on the client application side over a sliding time window.
  • Exposed Data:
    • <basename>{quantile="0.95"}: The 95th percentile value.
    • <basename>_count: Total observations.
    • <basename>_sum: Sum of observations.
  • Use Case: When client-side percentile calculation is required and you don't need to aggregate quantiles across multiple instances in Prometheus.


Summary Comparison Matrix


Metric Type
  • Can Decrease?
  • Typical PromQL Functions
  • Best Used For

Gauge
  • Yes
  • Direct value, avg_over_time()
  • Current state, memory usage, counts of current objects

Counter
  • No (only on restart)
  • rate(), increase()
  • Total count of events over time, request volume

Histogram
  • No (bucket counts increase)
  • histogram_quantile(), rate()
  • Request latencies, payload sizes (aggregatable)

Summary
  • No (counts/sums increase)
  • Direct quantile query
  • Request latencies (pre-calculated on client)




Container Metrics


container_memory_rss



container_memory_rss is a Prometheus metric (exposed by cAdvisor) that measures a container's Resident Set Size—specifically, the amount of physical RAM allocated to non-reclaimable, non-file-backed memory.

Key Technical Breakdown


Under the hood in Linux cgroups, container_memory_rss tracks:
  • Anonymous Memory: Process heap allocations, execution stack, and memory allocated via malloc or mmap(MAP_ANONYMOUS).  
  • Swap Cache: Memory swapped out to disk that is being brought back into RAM.

What it EXCLUDES:

Unlike standard Linux host RSS metrics, container_memory_rss in cAdvisor excludes file-backed page caches (memory used to cache files read from disk). Because of this, it only measures memory that cannot be automatically freed by the Linux kernel under memory pressure.  


container_memory_rss vs. Other Container Metrics


To understand its role, it helps to see how it fits into cAdvisor's other core memory metrics:

Metric
  • Includes
  • Purpose / Key Characteristic

container_memory_rss
  • Heap + Stack (Anonymous memory)
  • Stable indicator of process memory footprint. Does not fluctuate with disk I/O.

container_memory_working_set_bytes
  • Heap + Stack + Active Page Cache
  • What Kubernetes actually monitors. Fluctuates with file reads/writes.

container_memory_usage_bytes
  • Heap + Stack + Active Cache + Inactive Cache
  • Raw total RAM usage. Can be misleading because inactive cache is easily reclaimed by the OS.

Why is container_memory_rss Important?

  • Memory Leak Detection: Because it excludes cached file reads, container_memory_rss provides a much cleaner signal for application-level memory leaks. If this metric steadily climbs over time without dropping, your application (e.g., Go heap, JVM heap, Node process) is holding onto unmanaged memory. 
  • Debugging OOM Kills: While Kubernetes triggers OOMKills based on container_memory_working_set_bytes hitting resource limits, container_memory_rss helps you determine why it happened:  
    • High RSS + High Working Set --> Application memory leak or underestimated heap limit.
    • Low RSS + High Working Set --> Heavy disk I/O / file caching (e.g., reading massive log files or database indexes into memory).  

When container_memory_rss is NOT a relevant metric?


Example:

WiredTiger is the default storage engine that MongoDB (here, the Percona Server for MongoDB / PSMDB cluster) uses to actually read and write data to disk. In <ticketID> it matters specifically because of how it uses memory, which is what breaks those four Grafana alert rules.

The relevant behavior:

WiredTiger keeps a large in-memory cache. It maintains its own cache of frequently-accessed data and indexes, and it deliberately sizes that cache to roughly half the container's memory limit (the issue cites ~10 GiB against a 21Gi limit on rs0/rs2, and it's tunable per <ticketID>). WiredTiger runs its own eviction, targeting about 80% cache fill under normal operation and triggering aggressive eviction around 95%.

That cached data shows up as page cache, not RSS. This is the crux of the ticket. container_memory_rss counts anonymous/resident process memory but excludes the OS page cache — and for a WiredTiger workload the file-backed pages (the cache) are the bulk of the real footprint. So rss / limit sits structurally pinned around 50-58% no matter how much memory pressure the pod is actually under. An alert keyed on container_memory_rss > 0.90 can therefore never fire for a WiredTiger container. It's dead. (alert is defined as: container_memory_rss{container="mongod"} / limit > 0.90)

But you can't just switch to working-set either. container_memory_working_set_bytes does include those active file pages, so on the busy replicas it reads 95-96%. That looks alarming but is expected and healthy: it's the WiredTiger cache sitting at its designed ~half-of-limit size and WT's own eviction watermark. The kernel reclaims those pages under real pressure, and the evidence is that nothing in the mongodb namespace has ever been OOMKilled. Flipping the metric would just move the rule from never-firing to always-firing.

The signal that actually matters is WiredTiger cache fill. Because WT stalls user operations when its cache can't evict fast enough, the meaningful early-warning metric is cache utilization (the existing MongoDB WiredTiger cache fill — above 95% for 30m rule from <ticketID>), not container RSS or working set. That's why the ticket argues the RSS rules are redundant, not just broken, and leans toward deleting them.

So in this issue's context, "WiredTiger" is essentially shorthand for "a workload whose memory lives mostly in a large, self-managed, page-cache-backed database cache" — which is exactly the profile that makes RSS-based memory alerting meaningless and makes cache-fill the correct signal instead. (The same logic applies to the Elasticsearch rules, where the JVM heap plays the analogous role.)


Example PromQL Query


To track application heap growth without the noise of filesystem caching, query RSS like this:

# Rate of container RSS growth over 5-minute intervals
rate(container_memory_rss{namespace="production", container!=""}[5m])


container_memory_working_set_bytes


...

container_memory_usage_bytes


...

Introduction to cAdvisor (Container Advisor)




cAdvisor (short for Container Advisor) is an open-source tool created by Google to collect, aggregate, process, and export resource usage and performance metrics for running containers.

It acts as a daemon that monitors resource isolation parameters, historical resource usage, and network statistics directly from the host node.



How It Works


cAdvisor doesn't require instrumenting code inside containers. Instead, it inspects the node environment where containers run:
  • Queries Linux Kernel Structures: It pulls raw performance data directly from kernel mechanisms—primarily cgroups (control groups) for CPU, memory, and disk utilization, and network interfaces for throughput metrics.
  • Discovers Running Containers: It automatically detects running containers across multiple runtimes (Docker, containerd, CRI-O, systemd containers).
  • Exposes Metrics: It formats gathered data and exposes it over a /metrics HTTP endpoint (primarily in Prometheus format) for scrapers to ingest.


Role in Kubernetes


In Kubernetes, cAdvisor is not deployed as a standalone pod. Instead, it is built directly into the kubelet binary that runs on every node.
  • The kubelet uses cAdvisor internally to monitor local container resource usage.
  • It exposes cAdvisor metrics under the /metrics/cadvisor endpoint on the kubelet API port (typically 10250).
  • Tools like Prometheus scrape this endpoint to collect system-wide container metrics (container_cpu_usage_seconds_total, container_memory_rss, container_network_transmit_bytes_total, etc.).

Core Capabilities


  • Resource Usage Monitoring: Tracks real-time CPU utilization, memory breakdown (RSS, cache, swap), network I/O, and disk space usage per container.
  • Historical Trend Aggregation: Keeps a small buffer of historical telemetry in memory for local inspection.
  • Multi-Runtime Support: Works out of the box with containerd, Docker, and CRI-compliant container engines.
  • Built-in Web UI: When run as a standalone binary or Docker container outside Kubernetes, it provides a lightweight built-in dashboard for quick visual inspection of container stats.


Summary of Metric Flow


Linux Kernel / cgroups --> cAdvisor --> Prometheus --> Grafana

cAdvisor sits right at the boundary between the underlying host/kernel layer and the monitoring stack, turning low-level kernel counters into structured metrics for alerting and visualization.


Friday, 6 February 2026

Kubernetes Metrics Server

 


Kubernetes Metrics Server is a foundational component required by several other critical cluster modules and tools: 

1. Horizontal Pod Autoscaler (HPA)

2. Vertical Pod Autoscaler (VPA) 
  • Purpose: While HPA adds more pods, the Vertical Pod Autoscaler (VPA) adjusts the CPU and memory requests/limits of existing pods.
  • Dependency: VPA relies on Metrics Server for the real-time resource data it uses to recommend or apply these resource changes. 

2. Native CLI Observability (kubectl top) 
  • Purpose: Commands used for ad-hoc debugging and performance monitoring.
  • Dependency: Both kubectl top pods and kubectl top nodes query the Metrics API directly. Without the server, these commands will return an error. 

3. Kubernetes Dashboard 
  • Purpose: A web-based UI for managing and troubleshooting clusters.
  • Dependency: The Kubernetes Dashboard uses Metrics Server to display resource usage graphs and live statistics for nodes and pods. 

4. Third-Party Monitoring Tools & Adapters
  • Custom Metrics Adapters: Some adapters that bridge external sources (like CloudWatch or Datadog) to Kubernetes may use the standard Metrics API for fallback or basic resource data.
  • Resource Management Tools: Operational tools such as Goldilocks, which suggests "just right" resource requests, often depend on the baseline metrics provided by this server. 

Key Distinction


While the Metrics Server is essential for these control loops (HPA, VPA), it is not a replacement for a full observability stack like Prometheus. It only stores a short-term, in-memory snapshot and does not provide historical data

How to to install the Metrics Server as an EKS Community Add-on to enable these features?


In March 2025, AWS introduced a new catalog of community add-ons that includes the Metrics Server. This allows you to manage it directly through EKS-native tools like any other AWS-managed add-on (e.g., VPC CNI or CoreDNS). 

Method 1: Using the AWS Management Console


The easiest way to install it is through the EKS console: 
  • Navigate to your EKS cluster in the AWS Console.
  • Select the Add-ons tab and click Get more add-ons.
  • Scroll down to the Community add-ons section.
  • Find Metrics Server, select it, and click Next.
  • Choose the desired version (usually the latest recommended) and click Create. 

Method 2: Using the AWS CLI


You can also install the community add-on via the command line:

aws eks create-addon \
  --cluster-name <YOUR_CLUSTER_NAME> \
  --addon-name metrics-server

Verification


Once the installation status moves to Active, verify that the pods are running in the kube-system namespace: 

kubectl get deployment metrics-server -n kube-system

Finally, test that the Metrics API is responding:

kubectl top nodes

Note: If you are using AWS Fargate, you may need to update the containerPort from 10250 to 10251 in the deployment configuration to ensure compatibility with Fargate's networking constraints. 


Metrics Server Configuration



To configure custom resource limits for the Metrics Server EKS community add-on, you can use Configuration Values during installation or update. This is essential for high-pod-count clusters where the default allocation may lead to OOMKilled errors. 

1. Scaling Recommendations


The Metrics Server's resource consumption scales linearly with your cluster's size. Baseline recommendations include: 
  • CPU: Approximately 1 millicore per node in the cluster.
  • Memory: Approximately 2 MB of memory per node.
  • Large Clusters: If your cluster exceeds 100 nodes, it is recommended to double these defaults and monitor performance. 

2. How to Apply Custom Limits


You can provide a JSON or YAML configuration block via the AWS EKS Add-ons API. 

Via AWS CLI


Use the configuration-values flag to pass your resource overrides:

aws eks create-addon \
  --cluster-name <YOUR_CLUSTER_NAME> \
  --addon-name metrics-server \
  --configuration-values '{
    "resources": {
      "requests": { "cpu": "100m", "memory": "200Mi" },
      "limits": { "cpu": "200m", "memory": "500Mi" }
    }
  }'


Via AWS Console

  • Go to the Add-ons tab in your EKS cluster.
  • Click Edit on the metrics-server add-on.
  • Expand the Optional configuration settings.
  • Paste the JSON configuration into the Configuration values text box. 

3. Critical Configuration for High Traffic


In addition to resource limits, you may want to adjust the scraping frequency to make HPA more responsive.

  • Metric Resolution: The default is 60s. For faster scaling, add --metric-resolution=15s to the container arguments via the same configuration block.
  • High Availability: The community add-on defaults to 2 replicas to prevent downtime during scaling events. 



Friday, 9 August 2024

Software Development Lifecycle, Environments and DevOps Metrics


Agile Software Development Lifecycle can be visualised as in the following infogram:


image source: LinkedIn (Brij kishore Pandey)



Why do we need multiple environments?


Developers and testers might not like to work on the same environment as they may use and modify the same data and it may impact the developer's troubleshooting ability or the tester's test result reliability. This is why devops may setup multiples of the same infrastructure stack and call them by different names (environments).


QA vs QC vs Testing


Before we list environments, we need to clarify that these terms are not the same:
  • Quality Assurance - ensures that processes and procedures are in place to achieve quality
  • Quality Control - ensures product quality
  • Testing - validates the product against specifications
    • functional
    • non-functional
    • acceptance testing
This is why QA environment might not be the same as Testing environment.



DevOps Environments


Continuous Testing is performed in at least two environment families:
  • Lower environments - any architecture which is not a direct copy of production; environments with different purposes, which don't necessarily need to replicate the Prod system.
    • Dev/Local development
    • Sandbox environments
    • CI environments
    • Test environments
    • QA environments
    • Nonfunctional testing envs 
  • Production replica environments:
    • Pre-Production / Staging -  test deployment into a Prod replica without Prod data; live environments with non-production data and beta testing
    • NPPD (Non-Production environment with Production Data) is a prod replica with prod data.
    • Customer UAT (User Acceptance Testing) /training environment

Production environment - for end users.





image source: LinkedIn (Brij kishore Pandey)