New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DRA: generated resource claim names #117351
DRA: generated resource claim names #117351
Conversation
/remove-sig api-machinery |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also need to fix comments in type ClaimSource
- "The name of the ResourceClaim will be..."
pkg/apis/core/types.go
Outdated
// the corresponding ResourceClaim. | ||
type PodResourceClaimStatus struct { | ||
// Name uniquely identifies this resource claim inside the pod. | ||
// This must be a DNS_LABEL. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And must match a defined resource claim?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. I wonder whether that should replace "must be a DNS_LABEL" because that follows from "must be the name of an entry in pod.spec.resourceClaims". I'll use both for now.
pkg/apis/core/types.go
Outdated
Name string | ||
|
||
// ResourceClaimName is the name of the ResourceClaim that was | ||
// generated for the Pod. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...in the same namespace as this pod.
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, let's call that out explicitly.
d0c7f40
to
820fdc9
Compare
820fdc9
to
67ac68e
Compare
a8e4a55
to
f408285
Compare
f408285
to
ac5ddb8
Compare
ac5ddb8
to
a7597e7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With comments from Jordan address through use of MutationCache, the controller changes lgtm
func Name(pod *v1.Pod, podClaim *v1.PodResourceClaim) string { | ||
if podClaim.Source.ResourceClaimName != nil { | ||
return *podClaim.Source.ResourceClaimName | ||
func Name(pod *v1.Pod, podClaim *v1.PodResourceClaim) (name *string, mustCheckOwner bool, err error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How much overhead is it to just always check for the owner? It just feels awkward to have this extra boolean returned from here. Or better yet, why can't we just check for the owner in here and return an error if the pod passed in is not the owner whenever it "must" be checked.
pkg/kubelet/cm/dra/manager.go
Outdated
klog.V(3).InfoS("Processing resource", "podClaim", podClaim.Name, "pod", pod.Name) | ||
claimName, mustCheckOwner, err := resourceclaim.Name(pod, podClaim) | ||
if err != nil { | ||
return err |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably wrap this error to be consistent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay.
if claimName == nil { | ||
// Nothing to do. | ||
continue | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When would there ever be no error, but claimName == nil
? I would think that that would be an error condition from within resourceclaim.Name()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's the new feature: if creating a claim was intentionally skipped (nil in the claim name field), then all code dealing with the pod can skip the claim. resourceclaim.Name
indicates that with a nil claimName
. Returning a special error code also would work.
This was a use case that came up with Multi-Network. We don't use this with "normal" claims yet, but if we ever need it, all releases >1.28 will support it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it's not an error to have a nil
claim name, then it shouldn't be hidden behind an error. Maybe just adding a comment above the check as to why it might ever be nil is sufficient (at which point we can remove the comment of "Nothing to do" as that should be obvious from the new comment).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment changed.
// The error usually has already enough context ("resourcevolumeclaim "myclaim" not found"), | ||
// but we can do better for generic ephemeral inline volumes where that situation | ||
// is normal directly after creating a pod. | ||
if isEphemeral && apierrors.IsNotFound(err) { | ||
err = fmt.Errorf("waiting for dynamic resource controller to create the resourceclaim %q", claimName) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have a whole lot of context on why this was needed to begin with, but why is this not needed anymore? I guess it's all captured within the resourceclaim.Name()
call now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct. It'll check for this based on the pod status field.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ack
a7597e7
to
aff8342
Compare
|
||
if claimName == nil { | ||
// Nothing to do. | ||
continue | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add a comment such as the following here? Looks like it will need to be propagated to 3 places in total.
// The claim name might be nil if no underlying resource claim
// was generated for the referenced claim. There are valid use
// cases when this might happen, so we simply skip it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed - please take another look.
func Name(pod *v1.Pod, podClaim *v1.PodResourceClaim) string { | ||
if podClaim.Source.ResourceClaimName != nil { | ||
return *podClaim.Source.ResourceClaimName | ||
func Name(pod *v1.Pod, podClaim *v1.PodResourceClaim) (name *string, mustCheckOwner bool, err error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK. I don't feel too strongly, so we can leave it as is.
Generating the name avoids all potential name collisions. It's not clear how much of a problem that was because users can avoid them and the deterministic names for generic ephemeral volumes have not led to reports from users. But using generated names is not too hard either. What makes it relatively easy is that the new pod.status.resourceClaimStatus map stores the generated name for kubelet and node authorizer, i.e. the information in the pod is sufficient to determine the name of the ResourceClaim. The resource claim controller becomes a bit more complex and now needs permission to modify the pod status. The new failure scenario of "ResourceClaim created, updating pod status fails" is handled with the help of a new special "resource.kubernetes.io/pod-claim-name" annotation that together with the owner reference identifies exactly for what a ResourceClaim was generated, so updating the pod status can be retried for existing ResourceClaims. The transition from deterministic names is handled with a special case for that recovery code path: a ResourceClaim with no annotation and a name that follows the Kubernetes <= 1.27 naming pattern is assumed to be generated for that pod claim and gets added to the pod status. There's no immediate need for it, but just in case that it may become relevant, the name of the generated ResourceClaim may also be left unset to record that no claim was needed. Components processing such a pod can skip whatever they normally would do for the claim. To ensure that they do and also cover other cases properly ("no known field is set", "must check ownership"), resourceclaim.Name gets extended.
This is not something that normally happens, but the API supports it because it might be needed at some point, so we have to test it.
This addresses the following bad sequence of events: - controller creates ResourceClaim - updating pod status fails - pod gets retried before the informer receives the created ResourceClaim - another ResourceClaim gets created Storing the generated ResourceClaim in a MutationCache ensures that the controller knows about it during the retry. A positive side effect is that ResourceClaims now get index by pod owner and thus iterating over existing ones becomes a bit more efficient.
aff8342
to
fec2578
Compare
/lgtm For kubelet changes |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: klueska, pohly, soltysh, thockin The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
LGTM label has been added. Git tree hash: 71a041eaa079748cc524c5a3a0c5bf53fd73857e
|
The Kubernetes project has merge-blocking tests that are currently too flaky to consistently pass. This bot retests PRs for certain kubernetes repos according to the following rules:
You can:
/retest |
This is a follow-up to kubernetes#117351 which just got merged.
What type of PR is this?
/kind cleanup
/kind api-change
What this PR does / why we need it:
One concern raised during the initial DRA reviews and again in #116254 (comment) was the risk of name conflicts between automatically and manually created ResourceClaims.
This PR addresses that by switching to generated names for automatically created ResourceClaims, with a pod.status extension to record that generated name for code where listing all ResourceClaims is impossible (kubelet) or more complex (node authorizer).
Which issue(s) this PR fixes:
Fixes #113722
Special notes for your reviewer:
Does this PR introduce a user-facing change?
Additional documentation e.g., KEPs (Kubernetes Enhancement Proposals), usage docs, etc.: