Skip to content
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: CDI: maximum annotation length #123889

Open
pohly opened this issue Mar 12, 2024 · 16 comments
Open

DRA: CDI: maximum annotation length #123889

pohly opened this issue Mar 12, 2024 · 16 comments
Assignees
Labels
kind/feature Categorizes issue or PR as related to a new feature. priority/important-longterm Important over the long term, but may not be staffed and/or may need multiple releases to complete. priority/important-soon Must be staffed and worked on either currently, or very soon, ideally in time for the next release. sig/node Categorizes an issue or PR as relevant to SIG Node. triage/accepted Indicates an issue or PR is ready to be actively worked on.

Comments

@pohly
Copy link
Contributor

pohly commented Mar 12, 2024

What would you like to be added?

This code checks that "plugin name" (= DRA driver name) + "CDI device ID" with "_" as separator is at most maxNameLen = 63:

name := pluginName + "_" + strings.ReplaceAll(deviceID, "/", "_")
if len(name) > maxNameLen {
return "", fmt.Errorf("invalid plugin+deviceID %q, too long", name)
}

Can that happen for valid driver and CDI device IDs? Do CDI driver authors have to avoid this? If yes, we need to document it.

/cc @klueska @bart0sh
/sig node

Why is this needed?

Avoid surprises...

@pohly pohly added the kind/feature Categorizes issue or PR as related to a new feature. label Mar 12, 2024
@k8s-ci-robot k8s-ci-robot added sig/node Categorizes an issue or PR as relevant to SIG Node. needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. labels Mar 12, 2024
@ffromani
Copy link
Contributor

/triage accepted
/priority important-longterm

not sure between important-soon or important-longterm, taking a conservative approach for starters

@k8s-ci-robot k8s-ci-robot added triage/accepted Indicates an issue or PR is ready to be actively worked on. priority/important-longterm Important over the long term, but may not be staffed and/or may need multiple releases to complete. and removed needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. labels Mar 12, 2024
@varunrsekar
Copy link

varunrsekar commented May 28, 2024

@pohly Could maxNameLen atleast be 127/128 chars? If deviceID is a uuid, then it already takes up 36 chars.

Example that will break: foobar.resource.example.com_dd84eb13-3eca-4caf-9042-4f556c8f6d48 (65 chars)

We use UUIDs when working with vGPUs and mediated devices. So having atleast 127 chars will help satisfy that.

@pohly
Copy link
Contributor Author

pohly commented May 28, 2024

I'm not sure where the maxNameLen = 63 limit comes from. @bart0sh, can you clarify?

/assign @bart0sh

@varunrsekar
Copy link

Just found that k8s has some limits on the annotation key size: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/#syntax-and-character-set

Annotations are key/value pairs. Valid annotation keys have two segments: an optional prefix and name, separated by a slash (/). The name segment is required and must be 63 characters or less, beginning and ending with an alphanumeric character ([a-z0-9A-Z]) with dashes (-), underscores (_), dots (.), and alphanumerics between. The prefix is optional. If specified, the prefix must be a DNS subdomain: a series of DNS labels separated by dots (.), not longer than 253 characters in total, followed by a slash (/).

But in the annotation key (<prefix>/<name>), only the name segment needs to be 63 characters or less where as the prefix can be upto 253 chars.

In our case, we have <prefix>=cdi.k8s.io, <name>=pluginID+deviceID which maybe it can just be <prefix>=<pluginID>, <name>=deviceID

@bart0sh
Copy link
Contributor

bart0sh commented May 28, 2024

@pohly
Copy link
Contributor Author

pohly commented May 29, 2024

/priority important-soon

We are finalizing the DRA API and this has implications for it.

@k8s-ci-robot k8s-ci-robot added the priority/important-soon Must be staffed and worked on either currently, or very soon, ideally in time for the next release. label May 29, 2024
@elezar
Copy link
Contributor

elezar commented May 29, 2024

As @bart0sh points out, the 63 character limit is due to the use of the name section of the annotation key. Note that the cdi.k8s.io prefix is assumed by downstream consumers (containerd and cri-o) to determine whether CDI devices are requested if the dedicated CRI fields are not available.

Note that the name serves no practical purpose other than preventing colissions in keys. Furthermore, it is unrelated to the fully-qualified CDI device names which are passed as a comma-separated list in the corresponding annotation value.

The original thinking behind allowing a user to specify the plugin name is to allow some human-readability as to the source of the annotations, but maybe this flexibility is not required. We could also replace getAnnotations(string, string) (string, error) with an implementation that unconditionally returns a uuid instead.

@varunrsekar when you mention vGPUs and mediated devices, where are the UUIDs used? In the CDI device name, or in the annotation keys that are generated?

@bart0sh
Copy link
Contributor

bart0sh commented May 29, 2024

We are finalizing the DRA API and this has implications for it.

Are we still going to use annotations in the DRA API ? I thought that usage of annotations should be deprecated in favour of using CRI field.

@elezar
Copy link
Contributor

elezar commented May 29, 2024

We are finalizing the DRA API and this has implications for it.

@pohly which implications does this have? If we remove the logic for cleaning and prepending the driver name, we can construct the name section ourselves and leave it opague to the user. This may make some things more difficult to debug, but the annotation creation is opague to a DRA driver implementer in any case.

We already do this for the device plugins and call:

annotations, err := cdi.GenerateAnnotations(types.UID(resourceID), "devicemanager", sortedCDIDevices)

where devicemanager could be replaced by dra globally if we assume a unique claim ID.

@pohly
Copy link
Contributor Author

pohly commented May 29, 2024

This may limit the length of strings exchanged between Kubernetes and DRA drivers (device ID) and/or of the driver name.

We currently have a limit on the driver name as part of the Kubernetes API (DNS subdomain, max 63 characters), but not for the device ID:

message NodePrepareResourceResponse {
// These are the additional devices that kubelet must
// make available via the container runtime. A resource
// may have zero or more devices.
repeated string cdi_devices = 1 [(gogoproto.customname) = "CDIDevices"];

@elezar
Copy link
Contributor

elezar commented May 29, 2024

In the context of DRA the claim ID is used at present. My question was how we wish to expose this to driver authors? We could make this an implementation detail on the kubelet side and always generate a uuid.

Also to clarify, the name that is being discussed here is NOT the CDI device name which I assume that your are referring to as "device ID". For the relevant annotations, these are generated with the form:

map[string]string{
"cdi.k8s.io/{{ .DriverName }}_{{ .ClaimID }}": "vendor1.com/example1=device1,vendor2.com/example2=device2"
}

(note that I have used devices from two different vendors here, but in practice these will probably be the same vendor.)

My suggesion is that we change this so that we have:

map[string]string{
"cdi.k8s.io/dra_{{ .UUID }}": "vendor1.com/example1=device1,vendor2.com/example2=device2"
}

where we would generate .UUID for each call to GetAnnotations.

As a follow-up question: What are the uniqueness guarantees for the Claim ID? If this is guaranteed to be unique for a given container, then we could use the Claim UID as the unique identifier. Looking at the implementation it seems that this is always set from the UID for the claim object.

@pohly
Copy link
Contributor Author

pohly commented May 29, 2024

In the context of DRA the claim ID is used at present.

Indeed:

annotations, err := updateAnnotations(map[string]string{}, driverName, string(claimUID), cdiDevices)

I'm trying to find out how long a UID can be at most. Surprisingly, I found no validation of it.

Regardless of that, embedding the driver name is a problem because it may be 63 characters long, which leaves nothing for the "device ID" = "claim ID".

@varunrsekar: I suppose the claim UID is what you saw in your failure case, not the UID you use in your driver. Is that correct?

@bart0sh
Copy link
Contributor

bart0sh commented May 29, 2024

Passing CDI devices as annotations should be deprecated soon and removed from the Kubelet. To my understanding it should happen after EOL of the Kubernetes 1.28.

Kubernetes 1.29 supports passing CDIDevices with CRI field and has Device plugin CDI support enabled by default.

@pohly
Copy link
Contributor Author

pohly commented May 29, 2024

Do we have a tracking issue for this? If not, can you create one?

@varunrsekar
Copy link

@varunrsekar: I suppose the claim UID is what you saw in your failure case, not the UID you use in your driver. Is that correct?

@pohly Sorry for the confusion! What I saw in the CDI annotations was indeed the claim UID.

@bart0sh
Copy link
Contributor

bart0sh commented May 30, 2024

Created an issue as requested: #125210

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/feature Categorizes issue or PR as related to a new feature. priority/important-longterm Important over the long term, but may not be staffed and/or may need multiple releases to complete. priority/important-soon Must be staffed and worked on either currently, or very soon, ideally in time for the next release. sig/node Categorizes an issue or PR as relevant to SIG Node. triage/accepted Indicates an issue or PR is ready to be actively worked on.
Projects
Development

No branches or pull requests

6 participants