Skip to content

feat(pvc): add metrics for VolumeAttributesClass support - #3036

Open
FRosner wants to merge 2 commits into
kubernetes:mainfrom
FRosner:worktree-vac
Open

feat(pvc): add metrics for VolumeAttributesClass support#3036
FRosner wants to merge 2 commits into
kubernetes:mainfrom
FRosner:worktree-vac

Conversation

@FRosner

@FRosner FRosner commented Jul 18, 2026

Copy link
Copy Markdown

Why

Kubernetes' VolumeAttributesClass API (GA, default-enabled since v1.34) lets a PersistentVolumeClaim reference a mutable class of storage attributes, and lets the CSI driver report progress as it applies changes. kube-state-metrics currently exposes no information about this on PVCs.

What

Adds three new EXPERIMENTAL metrics to the PVC store:

  • kube_persistentvolumeclaim_volume_attributes_class — the VolumeAttributesClass requested in the PVC spec.
  • kube_persistentvolumeclaim_status_current_volume_attributes_class — the VolumeAttributesClass currently applied, as reported by the CSI driver. Kept separate from the spec metric so drift between desired and applied class can be detected.
  • kube_persistentvolumeclaim_status_modify_volume_status — one-hot status (Pending/InProgress/Infeasible) of an in-progress ModifyVolume operation, with a target_volume_attributes_class label. Emits zero rows when no modification is in progress.

The two new PersistentVolumeClaimConditionType values (ModifyVolumeError, ModifyingVolume) introduced alongside this API are already covered for free by the existing generic kube_persistentvolumeclaim_status_condition metric.

This is scoped to PVC metrics only — no new standalone VolumeAttributesClass resource/store. I will add these metrics in a follow-up PR.

Summary by CodeRabbit

  • New Features

    • Added experimental Prometheus metrics for PersistentVolumeClaim volume attribute classes.
    • Added metrics for current volume attribute classes and modify-volume status, including target class details.
  • Bug Fixes

    • Prevented volume attribute class metrics from being emitted with empty label values when the corresponding fields are unset.
  • Documentation

    • Documented the new metrics, labels, gauge types, and experimental status.

@kubernetes-prow kubernetes-prow Bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jul 18, 2026
@kubernetes-prow

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: FRosner
Once this PR has been reviewed and has the lgtm label, please assign bhope for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@kubernetes-prow kubernetes-prow Bot added the needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. label Jul 18, 2026
@kubernetes-prow

Copy link
Copy Markdown
Contributor

This issue is currently awaiting triage.

If kube-state-metrics contributors determine this is a relevant issue, they will accept it by applying the triage/accepted label and provide further guidance.

The triage/accepted label can be added by org members by writing /triage accepted in a comment.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@linux-foundation-easycla

linux-foundation-easycla Bot commented Jul 18, 2026

Copy link
Copy Markdown

CLA Signed
The committers listed above are authorized under a signed CLA.

  • ✅ login: FRosner / name: Frank Rosner (d9330c6)

@kubernetes-prow

Copy link
Copy Markdown
Contributor

Welcome @FRosner!

It looks like this is your first PR to kubernetes/kube-state-metrics 🎉. Please refer to our pull request process documentation to help your PR have a smooth ride to approval.

You will be prompted by a bot to use commands during the review process. Do not be afraid to follow the prompts! It is okay to experiment. Here is the bot commands documentation.

You can also check if kubernetes/kube-state-metrics has its own contribution guidelines.

You may want to refer to our testing guide if you run into trouble with your tests not passing.

If you are having difficulty getting your pull request seen, please follow the recommended escalation practices. Also, for tips and tricks in the contribution process you may want to read the Kubernetes contributor cheat sheet. We want to make sure your contribution gets all the attention it needs!

Thank you, and welcome to Kubernetes. 😃

@github-project-automation github-project-automation Bot moved this to Needs Triage in SIG Instrumentation Jul 18, 2026
@kubernetes-prow kubernetes-prow Bot added cncf-cla: no Indicates the PR's author has not signed the CNCF CLA. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Jul 18, 2026
@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 84a78fe5-e43f-4c2d-8d7d-46d2b831537a

📥 Commits

Reviewing files that changed from the base of the PR and between d9330c6 and bdfe87a.

📒 Files selected for processing (2)
  • internal/store/persistentvolumeclaim.go
  • internal/store/persistentvolumeclaim_test.go
💤 Files with no reviewable changes (1)
  • internal/store/persistentvolumeclaim_test.go

Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review.


📝 Walkthrough

Walkthrough

PersistentVolumeClaim metric collection now exposes requested and current VolumeAttributesClass values and ModifyVolume status. Unset class fields no longer produce empty-label samples. Documentation and store tests cover the new experimental gauges.

Changes

PersistentVolumeClaim metrics

Layer / File(s) Summary
Metric family emission and documentation
internal/store/persistentvolumeclaim.go, docs/metrics/storage/persistentvolumeclaim-metrics.md
Requested and current VolumeAttributesClass gauges emit only when their fields are set. The documentation defines the three experimental gauge metrics and their labels.
PVC fixture coverage
internal/store/persistentvolumeclaim_test.go
PVC fixtures now include requested and current classes and an in-progress ModifyVolume status.
Metric exposition validation
internal/store/persistentvolumeclaim_test.go
Expected output validates HELP and TYPE declarations, labeled samples, metric-family lists, and omission of empty class samples.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk: ⚪ Minimal · up to bdfe8

This PR adds localized experimental PVC metrics without any supplied evidence of an actionable merge-blocking risk.

Suggested labels: sig/instrumentation, kind/feature

Suggested reviewers: catherinef-dev, nmn3m, rexagod

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: adding PersistentVolumeClaim metrics for VolumeAttributesClass support.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@FRosner FRosner changed the title Add PVC metrics for VolumeAttributesClass (VAC) support feat(pvc): add metrics for VolumeAttributesClass support Jul 18, 2026
Expose the desired vs. currently-applied VolumeAttributesClass on a
PersistentVolumeClaim, and the state of any in-progress ModifyVolume
operation, via three new EXPERIMENTAL metrics:
kube_persistentvolumeclaim_volume_attributes_class,
kube_persistentvolumeclaim_status_current_volume_attributes_class, and
kube_persistentvolumeclaim_status_modify_volume_status.
@FRosner
FRosner marked this pull request as ready for review July 19, 2026 06:59
@kubernetes-prow kubernetes-prow Bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jul 19, 2026
@kubernetes-prow
kubernetes-prow Bot requested review from dgrisonnet and nmn3m July 19, 2026 06:59
@FRosner

FRosner commented Jul 20, 2026

Copy link
Copy Markdown
Author

CLA Signed
The committers listed above are authorized under a signed CLA.

@CatherineF-dev

Copy link
Copy Markdown
Contributor

@FRosner you can click the test failure link inside "EasyCLA — Missing CLA Authorization." presubmit, it will redirect you to sign.

@FRosner

FRosner commented Jul 23, 2026

Copy link
Copy Markdown
Author

@FRosner you can click the test failure link inside "EasyCLA — Missing CLA Authorization." presubmit, it will redirect you to sign.

Yeah I'm doing it. I am trying to sign as an employee and I'm in contact with our CLA manager but it's a bit difficult for me. I went through this at least 4 times. Now a 5th time and it finally went through :)

@kubernetes-prow kubernetes-prow Bot added cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. and removed cncf-cla: no Indicates the PR's author has not signed the CNCF CLA. labels Jul 23, 2026
@FRosner

FRosner commented Jul 28, 2026

Copy link
Copy Markdown
Author

/pony Twilight Sparkle

@kubernetes-prow

Copy link
Copy Markdown
Contributor

@FRosner: pony image

Details

In response to this:

/pony Twilight Sparkle

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@FRosner

FRosner commented Jul 30, 2026

Copy link
Copy Markdown
Author

@CatherineF-dev would you be the one to review the PR? What's the expected timeline to get a reviewer assigned? :)

@CatherineF-dev

Copy link
Copy Markdown
Contributor
  1. What are the use cases of these metrics?
  2. Is it possible to have fewer metrics to contain these data?

@FRosner

FRosner commented Aug 6, 2026

Copy link
Copy Markdown
Author

Thanks for picking this up @CatherineF-dev!

What are the use cases of these metrics?

The motivating case: I have StatefulSets whose PVCs I want to migrate to a different VolumeAttributesClass at runtime (e.g. bumping IOPS/throughput tier), without recreating the PVC. Today kube-state-metrics gives no visibility into any of this. Concretely:

  1. Drift detection — alert when the requested class and the applied class disagree for longer than expected:
    kube_persistentvolumeclaim_volume_attributes_class
      != on(namespace, persistentvolumeclaim)
    kube_persistentvolumeclaim_status_current_volume_attributes_class
    
  2. Stuck/failed modifications — page when a ModifyVolume operation goes Infeasible, or has been InProgress/Pending too long:
    kube_persistentvolumeclaim_status_modify_volume_status{status="Infeasible"} == 1
    
  3. Rollout tracking — during a fleet-wide VAC migration, count how many PVCs still have the old class vs. the new one, to track progress of the rollout across a StatefulSet.
  4. Auditing — inventory which storage class/tier every PVC is actually running, for cost or compliance reporting.

None of this is derivable from any existing KSM metric today — VolumeAttributesClassName and ModifyVolumeStatus aren't surfaced anywhere else.

Is it possible to have fewer metrics to contain these data?

I did consider collapsing these, but I think 3 is the right number given KSM's existing conventions:

  • The spec vs. status split (..._volume_attributes_class vs. ..._status_current_volume_attributes_class) follows the same pattern KSM already uses everywhere else for desired-vs-observed pairs (e.g. kube_deployment_spec_replicas / kube_deployment_status_replicas). Merging them into one metric with a type="requested"|"current" label would be a departure from that convention and would actually make the drift-detection query above harder to write, not easier.
  • The one-hot modify_volume_status metric is intentionally implemented identically to kube_persistentvolumeclaim_status_phase (same boolFloat64 one-hot-per-possible-value pattern, same file). It's not a new shape — it's reusing the existing idiom for "the status is one of a fixed small enum," which is what makes == 1 alerting queries and sum by (status) aggregations work consistently across the codebase.

I could technically fold modify_volume_status into status_current_volume_attributes_class via extra labels, but that would conflate "what class is currently applied" (always present) with "is a modification in progress" (transient, and needs its own target/status labels) — two different lifecycles — and would break the existing convention that phase-like fields get their own one-hot family. Cardinality-wise the cost is also minimal: modify_volume_status emits zero rows when no modification is in progress, and the other two emit exactly one row per PVC either way, so there's no meaningful reduction available by merging.

Happy to adjust if you see a cleaner shape, though.

@CatherineF-dev

Copy link
Copy Markdown
Contributor

The motivating case: I have StatefulSets whose PVCs I want to migrate to a different VolumeAttributesClass at runtime (e.g. bumping IOPS/throughput tier),

Do you think it's a common use case for other users?

@FRosner

FRosner commented Aug 7, 2026

Copy link
Copy Markdown
Author

Do you think it's a common use case for other users?

If they are using VolumeAttributeClasses, yes. I don't know how widely they are adopted, but they are stable since Kubernetes v1.36 so I think it makes sense to provide observability around them.

@rndinfosecguy

Copy link
Copy Markdown

Don't see the point. These metrics are quite useful

@CatherineF-dev

CatherineF-dev commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

I see.

VolumeAttributesClass is a new resource type.
Option1:
kube_persistentvolumeclaim_volumeattributesclass_info
kube_persistentvolumeclaim_volumeattributesclass_status

Option2:
kube_volumeattributesclass_info
kube_volumeattributesclass_status

Option2 will increase query friction on joining pvc and vac metric

How do you think @dgrisonnet which option is preferred?

@FRosner

FRosner commented Aug 13, 2026

Copy link
Copy Markdown
Author

VolumeAttributesClass is a new resource type.

Yes. Please note that I am going to submit another PR to add metrics about the VACs. This PR here is only limited to the VAC related fields in PVC, not the VAC resources themselves. So that means Option 2 is anyway going to happen and is not related to this PR.

How about adding labels into kube_persistentvolumeclaim_info?

You asked that earlier. We could do it, it already carries the storage class and it would require one less join. Why I chose to add a new metric:

  • Stability policy: kube_persistentvolumeclaim_info is STABLE. The developer guide is explicit: "Make metrics experimental first when introducing them" (docs/developer/guide.md, see Add Metrics for EndpointSlices #1910). Landing it as its own ALPHA/EXPERIMENTAL metric lets us iterate freely; landing it as a label on a STABLE metric locks us in immediately and makes any future correction a breaking change instead of a fast follow-up.
  • Mutability mismatch: Every existing label on _info (storageclass, volumename, volumemode) is fixed at PVC creation and never changes for the life of the object. VolumeAttributesClassName is the opposite — it's designed to be mutated at runtime, which is the entire premise of this feature and my use case. Attaching a frequently-mutating value as a label on an otherwise-static info row means every VAC change kills one series and spawns another, which could be a meaningfully different churn profile than what _info consumers expect today.
  • Breaks the drift-detection use case: The most valuable query here is comparing requested vs. currently-applied class. That needs two independent metrics so PromQL can do a native vector match (!=/== on(namespace, persistentvolumeclaim)). If both values were label keys on the same _info row, you can't diff two labels on one series without label_replace() gymnastics — it makes the primary use case harder, not easier.
  • modify_volume_status can't fit _info at all, regardless of the above: it's a multi-row one-hot (Pending/InProgress/Infeasible) that emits zero rows when nothing is in progress. _info is always exactly one row per PVC. There's no clean way to represent that as additional labels on a singleton row.

I'm open to suggestions, just outlining my reasoning.

@dgrisonnet dgrisonnet left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VolumeAttributesClass is a new resource type.
Option1:
kube_persistentvolumeclaim_volumeattributesclass_info
kube_persistentvolumeclaim_volumeattributesclass_status
Option2:
kube_volumeattributesclass_info
kube_volumeattributesclass_status
Option2 will increase query friction on joining pvc and vac metric
How do you think @dgrisonnet which option is preferred?

For VAC metric, they should be named kube_volumeattributesclass_ like your option 2, but for PVC metrics about VAC, it should be kube_persistentvolumeclaim_volume_attributes_class like it is in this PR

Comment thread internal/store/persistentvolumeclaim.go Outdated
"",
wrapPersistentVolumeClaimFunc(func(p *v1.PersistentVolumeClaim) *metric.Family {
volumeAttributesClassName := ""
if p.Spec.VolumeAttributesClassName != nil {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if it is nil, it would be better to skip the metric

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense! bdfe87a

Emitting a row with an empty volume_attributes_class label for every
PVC not using VolumeAttributesClass added noise; follow the existing
convention (e.g. modify_volume_status) of omitting the metric instead.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.

Projects

Status: Needs Triage

Development

Successfully merging this pull request may close these issues.

4 participants