Change:
<!-- Please use this template while reporting a bug and provide as much info as possible. Not doing so may result in your bug not being addressed in a timely manner. Thanks! If the matter is security related, please disclose it privately via --is defined as For , both and are valid and they will be serialized to and in Json respectively. However in openapi-, is marked as required so is not allowed. This cause a mismatch when doing deserialization based on openapi spec. should not be marked as required because is a valid value. Kubernetes version (use ): v1.19 Cloud provider or hardware configuration: OS (e.g: ): Kernel (e.g. ): Install tools: Network plugin and version (if this is a network-related bug): Others:
/sig node api-machinery
/triage accepted /assign
Hello, is there any update for this issue?
Possibly related to and This bug can prevent a controller we're working on from enumerating nodes in a cluster, as we hit deserialization errors if any node in the cluster exposes an image with . It seems like proposed to address this by using the image ID instead of its name. I imagine that making this field optional would require a KEP, as it's an API change; but perhaps this could be fixed by ensuring that the field is always initialized (i.e. to an empty list) to prevent deserialization errors? This would not require an API change and would make the implementation conform with the API spec.
Looking at the sources, it looks like the image list is constructed here: It's not clear to me how it's even possible for to be uninitialized? I'll try to figure out how we got into this state...
I was just able to trigger this with though I imagine this can be replicated in other environments (at least in ) with a similar workflow: To get into this state, I first built my app with and then imported it into the local k3d cluster with . Then, I made some changes to my application and built it again with the same tag, and imported into the cluster with the same command. It's not clear whether the instance represents the first version of the application image and the named instance refers to the second build on the same tag, or vice versa.
Sorry for the late reply. That's interesting. I agree with you it seems impossible for to be nil. <- doesn't seem to be the case. Looking
I can reproduce it by changing to . Either I missed something basic or there is a bug in the (kubelet uses v1 types directly) serialization pipeline.
I think I understand what happened: If an image has neither nor , kubelet sets to . However, when the object gets persisted to etcd in protobuf, the data is stored as -- protobuff doesn't distinguish and : Although we ask JSON API clients to tolerate values for such fields, openapi-generated clients (e.g. the ) treat as an invalid value for a required field during deserialization. It's hard to tell what the right fix is: it's a data lost in kube-apiserver serialization/deserialization IMO, but it may be hard to fix, since was the rollback of an attempt to fix the field as optional is an option, but it needs to be approved by someone from SIG Node (and for other APIs that may have similar issue, it would depend on the implementation details of each API). On the plus side, there seems to be no server-side validation that requires to be not . kubelet is the only writer of the field, and the fact is sometimes the field is written as the JSON API client tolerate value (as suggested by ) is an option, but it has to be done in a client-by-client basis. For , I think we can maintain a patch (namely treating as ) in the Python client to fix this. I'm not sure what client you're using though Please note that this could also be fixed if the node API takes a different approach when an image has neither nor , e.g. using the image ID as the name (could be a breaking change to existing clients that tolerates ) assigning a dummy name like <none(which could be confusing if there are multiple such images / an image that is literally called <none)
I'm not familiar enough with the internals of k8s' etcd protobuf serialization to know whether this is feasible in this context, but in other applications I've used wrapper messages to avoid this ambiguity. For example: This lets the value-ness of the names field be encoded distinctly from the list itself.
Another instance of this issue discussed here
Kubernetes python client fix is tracked in contains some API change suggestions for SIG node to consider, which could benefit JSON API clients: /unassign /remove-sig api-machinery /remove-triage accepted let's see if someone from SIG node can pick this up
This issue is currently awaiting triage. If a SIG or subproject determines this is a relevant issue, they will accept it by applying the label and provide further guidance. The label can be by org members by writing in a comment. <detailsInstructions for interacting with me using PR comments are available . If you have questions or suggestions related to my behavior, please file an issue against the repository. </details
thanks! But isn't that a breaking change if an old client talks to a new server? ah awesome! Probably we should just send a PR to SIG node to mark the field as optional /help
This request has been marked as needing help from a contributor. Please ensure the request meets the requirements listed . If this request no longer meets these requirements, the label can be removed by commenting with the command. <detailsIn response to : thanks! But isn't that a breaking change if an old client talks to a new server? Instructions for interacting with me using PR comments are available . If you have questions or suggestions related to my behavior, please file an issue against the repository. </details
/assign actually let me open one real quick
As I said, I'm not really clear on where etcd protobuf clients are implemented or how public that API is. Generally, though, it could be done gracefully via a deprecation cycle. A new field is introduced and the prior field is considered deprecated; Writers write both the deprecated field and the new type field; The API server continues to read the deprecated field for one major version. Once a major version has passed, change the API server to read the new typed field and stop writing the deprecated version... But this is all way more complicated than marking the field as optional. If it's acceptable to make it optional, that sounds fine to me! Thanks for your help looking into this
that makes sense. Our proto definitions and clients are generated from the files, so supporting the deprecation logic in the clients does sound like more work
Thanks for the fix I am using .
it turns out that already has a fix on master ( -- not yet on ) and I've put up a PR to make it usable from kube-rs ()

Discussion:
"type": "integer" } }, <del> "required": [ "names" ], </del> "type": "object" }, "io.k8s.api.core.v1.ContainerPort": {

// ContainerImage describe a container image type ContainerImage struct { // Names by which this image is known. <ins> // +optional </ins> Names []string // The size of the image in bytes. // +optional

message ContainerImage { // Names by which this image is known. // e.g. ["k8s.gcr.io/hyperkube:v1.0.7", "dockerhub.io/google_containers/hyperkube:v1.0.7"] <ins> // +optional </ins> repeated string names = 1; // The size of the image in bytes.

type ContainerImage struct { // Names by which this image is known. // e.g. ["k8s.gcr.io/hyperkube:v1.0.7", "dockerhub.io/google_containers/hyperkube:v1.0.7"] <ins> // +optional </ins> Names []string `json:"names" protobuf:"bytes,1,rep,name=names"` // The size of the image in bytes. // +optional