remove feature gate ServiceAccountTokenPodNodeInfo
Project: kubernetes/kubernetes | Language: Go | Concepts: api-versioning, backwards-compatibility, refactoring | Difficulty: mid
Link: https://github.com/kubernetes/kubernetes/pull/135338
The problem
The Kubernetes codebase still contained the ServiceAccountTokenPodNodeInfo feature gate, even though this feature had already graduated to general availability (GA) and was locked to enabled since v1.32. Keeping the feature gate around was unnecessary and added maintenance overhead and confusion.
Why it's non-trivial
Naively removing a feature gate can break compatibility or subtly change behavior if any code still checks the gate or if test cases, documentation, or validation logic reference it. Care must be taken to fully remove all references, update dependent logic to always act as if the feature is enabled, and adjust documentation and tests accordingly.
The approach
1. Remove the feature gate constant and its registration
The feature gate constant and its registration were deleted from the main features file:
- // Controls whether the apiserver embeds the node name and uid for the associated node when issuing
- // service account tokens bound to Pod objects.
- ServiceAccountTokenPodNodeInfo featuregate.Feature = "ServiceAccountTokenPodNodeInfo"
This removes the definition and disables its use anywhere in the codebase.
2. Remove feature gate from the versioned feature gates map
All versioned specs and references for the removed feature gate were deleted:
- ServiceAccountTokenPodNodeInfo: {
- {Version: version.MustParse("1.29"), Default: false, PreRelease: featuregate.Alpha},
- {Version: version.MustParse("1.30"), Default: true, PreRelease: featuregate.Beta},
- {Version: version.MustParse("1.32"), Default: true, PreRelease: featuregate.GA, LockToDefault: true},
- },
This ensures the feature gate is no longer tracked or available for configuration.
3. Remove feature gate from dependencies
- ServiceAccountTokenPodNodeInfo: {},
This prevents any other feature gates from depending on the removed gate.
4. Update logic to always behave as if the feature is enabled
Wherever the code previously checked the feature gate, the check was removed and the "enabled" code path made unconditional:
- if utilfeature.DefaultFeatureGate.Enabled(features.ServiceAccountTokenPodNodeInfo) {
- if nodeName := pod.Spec.NodeName; nodeName != "" {
- ...
- }
- }
+ if nodeName := pod.Spec.NodeName; nodeName != "" {
+ ...
+ }
This pattern was applied in multiple places, both in token creation and validation logic.
5. Update test data, documentation, and error messages
References to the feature gate in test YAMLs, error messages, and documentation were removed or clarified:
- no node association found for user, this user must run in a pod on a node and ServiceAccountTokenPodNodeInfo must be enabled
+ no node association found for user, this user must run in a pod on a node
This prevents confusion for users and developers who might otherwise think the feature gate still exists.
6. Remove from compatibility and feature lists
The feature gate was deleted from compatibility documentation and versioned feature lists:
-| ServiceAccountTokenPodNodeInfo | :ballot_box_with_check: 1.30+ | :closed_lock_with_key: 1.32+ | 1.29 | 1.30–1.31 | 1.32– | | | [code](https://cs.k8s.io/?q=%5CbServiceAccountTokenPodNodeInfo%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbServiceAccountTokenPodNodeInfo%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) |
From the review thread
No notable review discussion on this PR.
Takeaways
- When a feature gate is locked and always enabled, remove it entirely to reduce code complexity and avoid confusion.
- Update all related logic to always execute the "enabled" code path, and remove conditional checks.
- Review and update all documentation, error messages, and tests to reflect the removal of the feature gate, preventing stale references.