Skip to content

Add ControllerGetNodeInfo RPC (alpha) - #603

Open
huww98 wants to merge 6 commits into
container-storage-interface:masterfrom
huww98:ControllerGetNodeInfo
Open

huww98 wants to merge 6 commits into
container-storage-interface:masterfrom
huww98:ControllerGetNodeInfo

Conversation

@huww98

@huww98 huww98 commented Mar 21, 2026 •

Copy link
Copy Markdown
Contributor

What type of PR is this?

/kind feature

What this PR does / why we need it:

See KEP-6011: CSI ControllerGetNodeInfo for details

Which issue(s) this PR fixes:

Fixes #

Special notes for your reviewer:

Does this PR introduce an API-breaking change?:

Add ControllerGetNodeInfo RPC and corresponding new field in NodeGetInfo (alpha)

@jdef

jdef commented Mar 21, 2026 via email

Copy link
Copy Markdown
Member

@huww98
huww98 force-pushed the ControllerGetNodeInfo branch from a727d32 to a6f4f25 Compare March 21, 2026 14:58
@huww98

huww98 commented Mar 21, 2026 •

Copy link
Copy Markdown
Contributor Author

There's a lot of k8s stuff in this PR desc, probably better suited for a
KEP that this PR might reference.

Yes, I will propose this to Kubernetes if it looks fine on the CSI side.
I provide them here for additional context.

what alternatives were considered and why were
they not sufficient?

There are not many alternatives actually.

The instance metadata service (e.g., http://169.254.169.254 or http://100.100.100.200) typically only provides basic info like instance-id and zone. It does not provide disk attachment limits or supported disk categories, which require cloud API calls.

The information required by NodeGetInfo is not fetchable from node with the security requirement. We have considered adding a new private CRD and a new controller in Kubernetes. The controller watches for new node, fetches the required info and store them in a CR, then node watches for the CR to get the info. But this still have major drawbacks:

  • The permission to invoke Cloud API is replaced with a service account with CR read permission, which does not fundamentally solve the security issue.
  • Requires more network roundtrips
    • This proposal: Cloud -> csi-controller -> external-attacher -> APIServer(CSINode) -> scheduler
    • With CRD: Cloud -> new controller -> APIServer(CR) -> csi-node -> kubelet -> APIServer(CSINode) -> scheduler
  • Even harder considering the new capability to fetch max_volumes_per_node immediately after publish failure. Will need some way for node to tell controller to do an update immediately, which requires write permission, making things even worse.
  • This is Kubernetes specific, not resolving the security requirement for other CO.

The core insight is: max_volumes_per_node and accessible_topology is consumed by scheduler, not node. So this piece of infomation should not appear on node for optimal security, hence this proposal.

huww98 added a commit to huww98/enhancements that referenced this pull request Apr 14, 2026
…ller-side node info retrieval

This KEP proposes two new CSI RPCs to enable node topology and capacity
information retrieval from the controller side, eliminating the need for
cloud API credentials on worker nodes:

- NodeGetID: Returns only the node identifier without cloud API access
- ControllerGetNodeInfo: Fetches topology and capacity from controller side

Benefits:
- Security: Node components no longer require cloud API credentials
- Scalability: Controller can aggregate and cache API calls for large clusters
- Accuracy: Controller-side VolumeAttachment info enables accurate non-CSI attachment detection

Depends on CSI spec PR kubernetes#603: container-storage-interface/spec#603
huww98 added a commit to huww98/enhancements that referenced this pull request Apr 14, 2026
…ller-side node info retrieval

This KEP proposes two new CSI RPCs to enable node topology and capacity
information retrieval from the controller side, eliminating the need for
cloud API credentials on worker nodes:

- NodeGetID: Returns only the node identifier without cloud API access
- ControllerGetNodeInfo: Fetches topology and capacity from controller side

Benefits:
- Security: Node components no longer require cloud API credentials
- Scalability: Controller can aggregate and cache API calls for large clusters
- Accuracy: Controller-side VolumeAttachment info enables accurate non-CSI attachment detection

Depends on CSI spec PR kubernetes#603: container-storage-interface/spec#603
huww98 added a commit to huww98/enhancements that referenced this pull request Apr 14, 2026
…ller-side node info retrieval

This KEP proposes two new CSI RPCs to enable node topology and capacity
information retrieval from the controller side, eliminating the need for
cloud API credentials on worker nodes:

- NodeGetID: Returns only the node identifier without cloud API access
- ControllerGetNodeInfo: Fetches topology and capacity from controller side

Benefits:
- Security: Node components no longer require cloud API credentials
- Scalability: Controller can aggregate and cache API calls for large clusters
- Accuracy: Controller-side VolumeAttachment info enables accurate non-CSI attachment detection

Depends on CSI spec PR kubernetes#603: container-storage-interface/spec#603
huww98 added a commit to huww98/enhancements that referenced this pull request Apr 14, 2026
…ller-side node info retrieval

This KEP proposes two new CSI RPCs to enable node topology and capacity
information retrieval from the controller side, eliminating the need for
cloud API credentials on worker nodes:

- NodeGetID: Returns only the node identifier without cloud API access
- ControllerGetNodeInfo: Fetches topology and capacity from controller side

Benefits:
- Security: Node components no longer require cloud API credentials
- Scalability: Controller can aggregate and cache API calls for large clusters
- Accuracy: Controller-side VolumeAttachment info enables accurate non-CSI attachment detection

Depends on CSI spec PR kubernetes#603: container-storage-interface/spec#603
huww98 added a commit to huww98/enhancements that referenced this pull request Apr 14, 2026
…ller-side node info retrieval

This KEP proposes two new CSI RPCs to enable node topology and capacity
information retrieval from the controller side, eliminating the need for
cloud API credentials on worker nodes:

- NodeGetID: Returns only the node identifier without cloud API access
- ControllerGetNodeInfo: Fetches topology and capacity from controller side

Benefits:
- Security: Node components no longer require cloud API credentials
- Scalability: Controller can aggregate and cache API calls for large clusters
- Accuracy: Controller-side VolumeAttachment info enables accurate non-CSI attachment detection

Depends on CSI spec PR kubernetes#603: container-storage-interface/spec#603
huww98 added a commit to huww98/enhancements that referenced this pull request Apr 14, 2026
…ller-side node info retrieval

This KEP proposes two new CSI RPCs to enable node topology and capacity
information retrieval from the controller side, eliminating the need for
cloud API credentials on worker nodes:

- NodeGetID: Returns only the node identifier without cloud API access
- ControllerGetNodeInfo: Fetches topology and capacity from controller side

Benefits:
- Security: Node components no longer require cloud API credentials
- Scalability: Controller can aggregate and cache API calls for large clusters
- Accuracy: Controller-side VolumeAttachment info enables accurate non-CSI attachment detection

Depends on CSI spec PR kubernetes#603: container-storage-interface/spec#603
huww98 added a commit to huww98/enhancements that referenced this pull request Apr 14, 2026
…ller-side node info retrieval

This KEP proposes two new CSI RPCs to enable node topology and capacity
information retrieval from the controller side, eliminating the need for
cloud API credentials on worker nodes:

- NodeGetID: Returns only the node identifier without cloud API access
- ControllerGetNodeInfo: Fetches topology and capacity from controller side

Benefits:
- Security: Node components no longer require cloud API credentials
- Scalability: Controller can aggregate and cache API calls for large clusters
- Accuracy: Controller-side VolumeAttachment info enables accurate non-CSI attachment detection

Depends on CSI spec PR kubernetes#603: container-storage-interface/spec#603
@bswartz

bswartz commented Apr 22, 2026

Copy link
Copy Markdown
Contributor

I don't see any point to the NodeGetID RPC. NodeGetInfo already returns a superset of the information.

@huww98

huww98 commented Apr 22, 2026 •

Copy link
Copy Markdown
Contributor Author

I design NodeGetID as a per-node switch for this feature, so that we can upgrade controller first, then upgrade nodes gradually: if node reports GET_ID cap, we go for the new workflow, otherwise we go for the old flow. We can also safely install new CSI driver (with new sidecars) in old Kubernetes cluster this way: old kubelet don't call NodeGetID, then new sidecar should not call ControllerGetNodeInfo, even if both sidecar and CSI driver support this.

As just discussed in the meeting, an operator may choose to remove credential from node side, so that NodeGetInfo can no longer retrieve topology info. I think it would be better for SP to fail NodeGetInfo instead of returning incomplete info.

Alternative: Adding a new field in NodeGetInfoResponse (say incomplete) as the switch stated above. But for old CO (kubelet) that don't understand this field, it may silently accept the incomplete topology or capacity, leading to confusing scheduling result. Also we may need to consider what to do if node and controller returns conflicting topology.

For the periodical update scalability issue, I take the number from https://kubernetes.io/docs/setup/best-practices/cluster-large/:

No more than 150,000 total pods
No more than 300,000 total containers

if every container have a volume, we can have 300,000 volumes in the cluster (we didn't tested this large scale). Our DescribeDisks API call can return at most 500 disks per-call. The default rate limit is 1000/60s in a region. So we can actually finish the query of the whole cluster in less than 1 min. So I think this is fine.

I can see that it could be hard for SPs that want to determine topology at controller side but capacity from node side. But I haven't come up with a better idea though.

@huww98
huww98 force-pushed the ControllerGetNodeInfo branch from 172f8f5 to 5e8c20a Compare May 27, 2026 05:38
@huww98 huww98 changed the title Add ControllerGetNodeInfo and NodeGetID RPCs (alpha) Add ControllerGetNodeInfo RPC (alpha) Jul 16, 2026
@huww98
huww98 force-pushed the ControllerGetNodeInfo branch from 020daf5 to f67692f Compare July 16, 2026 05:17
@torredil

Copy link
Copy Markdown

@huww98 This has a merge conflict now, please rebase when you get a chance. Feel free to ping when its updated and reviewable.

@torredil torredil left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Largely lgtm, will take another look after its rebased.

Comment thread spec.md Outdated
Comment thread spec.md
Comment thread spec.md
Comment thread spec.md
| Parameters not supported | 3 INVALID_ARGUMENT | Indicates that the CO has specified invalid mutable parameter keys or values, or the specified volume cannot support the specified parameters. The SP MUST NOT have applied any modification to the volume as part of this specific call. | A caller may verify volume capabilities by calling ValidateVolumeCapabilities and then retry the request with valid mutable parameters. |
| Volume does not exist | 5 NOT_FOUND | Indicates that a volume corresponding to the specified volume_id does not exist. | Caller MUST verify that the volume_id is correct and that the volume is accessible and has not been deleted before retrying with exponential back off. |

#### `ControllerGetNodeInfo`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This is something again I mentioned in the KEP, a driver that choses to implement ControllerGetNodeInfo without implemeneting/supporting controller-publish of volumes will force users to deploy external-attacher.

So, question is - should drivers that don't support controller-publish of volume still implement this capability.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

+1, in Kubernetes a plugin without PUBLISH_UNPUBLISH_VOLUME that advertises NODE_INFO_FROM_CONTROLLER would actually end up with no topology and no limit since external-attacher's trivial handler only exists to mark VA objects as attached and has no CSI connection.

I think the cleanest fix is to require that a plugin with GET_NODE_INFO also supports PUBLISH_UNPUBLISH_VOLUME.

@huww98 huww98 Sep 29, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

will force users to deploy external-attacher

This is a Kubernetes issue, right? I don't see anything inconsistent in the CSI layer.

Kubernetes a plugin without PUBLISH_UNPUBLISH_VOLUME that advertises NODE_INFO_FROM_CONTROLLER would actually end up with no topology and no limit

I didn't get this. This seems also a implementation issue? I think from CSI level it is fine for CO to call ControllerGetNodeInfo without ControllerPublishVolume to retrieve real topology and attach limit.

should drivers that don't support controller-publish of volume still implement this capability

My call: go implement this if it is useful for that driver. Kubernetes will additionally check for CSIDriver.spec.attachRequired before actually using it, ensuring we have external-attacher deployed and VolumeAttachments created for the driver. No matter whether the driver supports controller-publish or not.

the cleanest fix is to require that a plugin with GET_NODE_INFO also supports PUBLISH_UNPUBLISH_VOLUME.

If we really want to go this way, I think we need to require a plugin to not advertise NODE_INFO_FROM_CONTROLLER if it does not support PUBLISH_UNPUBLISH_VOLUME. Since CO needs to check it on node side to determine which flow to go with. But I cannot find a good reason for this requirement.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Requiring SPs to support also PUBLISH_UNPUBLISH_VOLUME if they want to support NODE_INFO_FROM_CONTROLLER is not a significant implementation burden. Those operations can be no-ops and the CO will work just fine (NetApp actually did this for some time).

Do we have an example of a driver (hypothetical or real) which would need the NODE_INFO_FROM_CONTROLLER capability and not need the PUBLISH_UNPUBLISH_VOLUME capability? That would be a good use case to focus on if we want to argue to not make the capability dependent.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Requiring SPs to support also PUBLISH_UNPUBLISH_VOLUME if they want to support

We now require SPs to support also PUBLISH_UNPUBLISH_VOLUME in the latest version of this PR.
This makes things simpler anyway. We can reconsider when we really see a use-case.

Those operations can be no-ops

Exactly. But on the other hand, that seems to mean CO can just pretend SP has a no-op publish operation if PUBLISH_UNPUBLISH_VOLUME is not advertised? Kubernetes external-attacher already doing this with its trivial handler.

Do we have an example of a driver (hypothetical or real)

I don't have a real use-case.
For hypothetical one, we are looking for network attached storage (no controller publish needed). Those drivers typically don't have volume count limitation, but topology constriant is possible.
For example. ceph-csi do support topology, it fetches Kubernetes node object for labels, which requires RBAC permission in daemonset. This step can be moved to controller side theoretically to remove credential from node. Note ceph-csi actually supports PUBLISH_UNPUBLISH_VOLUME, so it is not a direct example.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

From a security perspective, SPs that don't do controller publish can't achieve both (1) no sensitive secrets on the node AND (2) protection from attacks by malicious nodes, so I'm not sure what the point of moving the topology information from the node to the controller would be. They can do topology on the node like they do now.

The bigger concern is whether to run the external-attacher sidecar, because that's a noticeable burden, but to enable this feature they're going to have to run some additional sidecar, and it may as well be the external-attacher with possibly a no-op controllerpublish/unpublish implementation. Is anyone proposing a different sidecar to consume the new RPC?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure what the point of moving the topology information from the node to the controller would be. They can do topology on the node like they do now.

Yes, I agree for these drivers moving NodeGetInfo to controller has little benefit.

But we have NodePublishVolumeRequest.secrets. Those secrets can be scoped to volumes scheduled to the node, and not present on file-system. It should be slightly safer than a global permission from Kubernetes projected volume mounted to csi plugin daemonset.

Is anyone proposing a different sidecar to consume the new RPC?

The published_volume_ids feature can only work from external-attacher. It needs the in-memory state of currently processing volumes to avoid race condition.
And it seems only external-attacher caring about the node_id and CSINode object. I think it is a perfect fit.

@huww98
huww98 force-pushed the ControllerGetNodeInfo branch 2 times, most recently from 24e7a5e to d4debb8 Compare September 29, 2026 15:08
Comment thread spec.md Outdated
Comment thread spec.md Outdated
Comment thread spec.md Outdated
Comment thread spec.md

The CO SHALL combine these volumes with its own records (deduplicating as needed) when calculating available slots.
The CO MUST NOT use these volume IDs for any purpose other than slot accounting. In particular, the CO MUST NOT attempt to unpublish or otherwise operate on volumes it did not publish.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

IMO - I would avoid being too prescriptive here about what to do with returned published_volume_ids. It is fine to put this under an example, but I would avoid making it too prescriptive at this stage.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Removed "The CO MUST NOT use these volume IDs for any purpose other than slot accounting".

Other sentences are necessary IMO. SP generally needs an idea on how CO will behaviour with the IDs. And it still leaves room for implementation. It only say combine, not how.
But I'm not sure I get the meaning of "prescriptive".

I also added an example below.

@gnufied gnufied Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The CO SHALL combine these volumes with its own records (deduplicating as needed) when calculating available slots.

SHALL is basically same as MUST and I wonder if that is suitable language in CSI spec.

How about following (feel free to rephrase as you see fit):

The SP MAY additionally populate published_volume_ids with the IDs of volumes currently published to the node that count toward max_volumes_per_node, including volumes attached out-of-band, such as a root disk or manually attached volumes. The CO MAY use this information to determine effective maximum number of volumes it allows to publish on this node.

huww98 added 4 commits October 2, 2026 02:20
This proposal adds two new RPCs to enable node registration without
requiring cloud API credentials on the node side:

- NodeGetID: Returns only the node identifier, which can be obtained
  locally (e.g., from instance metadata) without cloud API access.

- ControllerGetNodeInfo: Fetches node topology and max_volumes_per_node
  from the controller side, where cloud API credentials are available.

New capabilities:
- NodeServiceCapability.RPC.GET_ID
- ControllerServiceCapability.RPC.GET_NODE_INFO

Key design decisions:
- If SP supports GET_ID, it MUST also support GET_NODE_INFO
- published_volume_ids field allows accurate calculation of remaining
  attachable volumes by distinguishing CSI-managed vs non-CSI volumes
- Both RPCs are marked as alpha

This addresses security requirements where cloud API credentials should
not be distributed to node components.

Signed-off-by: 胡玮文 <huweiwen.hww@alibaba-inc.com>
Remove the separate NodeGetID RPC and instead add a
controller_get_node_info flag to NodeGetInfoRequest. When set, the SP
MAY omit accessible_topology and max_volumes_per_node from
NodeGetInfoResponse and return only node_id; the CO obtains topology and
capacity from ControllerGetNodeInfo. The node capability GET_ID is
renamed to NODE_INFO_FROM_CONTROLLER accordingly.

This lets the >100 existing CSI drivers adopt the controller-side flow
with only a capability plus one optional field rather than implementing
a new RPC, and keeps node_id on a single node-side message.

Regenerate csi.proto and Go bindings.
@huww98
huww98 force-pushed the ControllerGetNodeInfo branch from d4debb8 to b397ce0 Compare October 1, 2026 18:24
@huww98

huww98 commented Oct 1, 2026

Copy link
Copy Markdown
Contributor Author

Also added something I learned when writing the KEP about the race condition in this round:

The SP MAY include or exclude volumes being published or unpublished during the ControllerGetNodeInfo call.
The CO MUST be resilient to that.
For ControllerGetNodeInfo calls that start after ControllerUnpublishVolume succeeds, the SP MUST exclude the volume from published_volume_ids for each affected node, unless a new publish operation for that volume on that node has since started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants