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
Issues with server side apply and Services #118725
Comments
This issue is currently awaiting triage. If a SIG or subproject determines this is a relevant issue, they will accept it by applying the The Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
I think we have some issue to track all of these problems with service ports and SSA, @thockin you are more familiar than me with this, do you remember which? |
A few things going on here:
Let's look a little more closely:
You can see that SSA knows one key of TCP 80.
You can see not that the SSA managed fields info has been updated to UDP 80. So when you send a new SSA with TCP 80, it's a different key and tries to merge them. That produces two ports without names, which is an error. @apelisse correct me if I got that wrong. So what could have been better? Frankly, it's a little surprising that @shawkins If you want to assert complete state, you should probably use |
I had made the wrong assumption that the client side apply behavior was correct. Ideally then providing both name and port should make the entry unique, but the following:
Won't work either. After the protocol modification re-applying gives you:
It still appears to be creating another port entry. Here as well the same scenario works with client side apply, or with a strategic merge patch (with or without a port name).
Ideally what we're looking to do is have the JOSDK https://github.com/java-operator-sdk/java-operator-sdk use server side apply to apply the desired state of resources. It's not necessarily that we're trying to assert the complete spec, just the part of it that we're managing. If there are corner cases that require |
Trying to recreate your test, I get:
This is a correct error (unfortunately) - adding a second port requires naming the first. We don't treat "" as a valid name (maybe we could but it would require some deep thinking). If I make the port+proto be the same:
So I am not sure where the duplicate is coming in.
And that involves modifying service ports? That's a little surprising to me. Unfortunately the port naming semantic is a little wonky when going from 1 to 2, in that name becomes required. I've had it on my low-prio backlog for a long time to investigate allowing one unnamed port and the REST require names, but it's not done. Help me understand exactly what things you think you need to co-own in Service? |
Sorry I wasn't descriptive enough with the next reproducer, I'm saying start with the port name and number, then modify and try to re-apply:
My understanding from what you were saying is that having both the port number and the name should be sufficient for server side apply to understand it is modifying the existing port. But it instead fails.
No this isn't a real world scenario (yet). What we'd like to understand for the JOSDK, and for the kubernetes fabric8 client, are what situations won't work well with server side apply. It will be surprising for users if their resource starts to reject modifications from a controller with a 422, when it used to work because effectively a replace was being performed. Based upon what I'm seeing here I'd like to more broadly understand how server side apply handles anything where a merge key should be used. Just checked that it's also a problem with deployment container env variables - if an existing value is modified by something else, then running a server side apply to change the value back will fail. |
When you do the 2nd apply, you are adding a new port, but using the same name as the UDP one.
No, the
Understood. I think the case you have devised is both confusing (it seems like one port being managed, but it's 2) and powerful (it demonstrates how SSA allows multiple controllers to act independently, even when operating on the same list field).
Man, you're hitting all of the awkward cases :)
|
Ok, sorry I see you did previously say protocol+port, and then I swapped in name instead. I see for service ports the merging behavior has an open discussion #105610 and previous issues.
Actually I missed that forcing conflicts is good enough to resolve that, so that seems fine. So it seems like the confusion will be with fields that are similar to ports, such as topologySpreadConstraints (with multiple +listMapKey's):
Then modify to whenUnsatisfiable: ScheduleAnyway If you try to do the server side apply again, you'll end up with 2 topologySpreadConstraints:
But do the same thing with a strategic merge and you'll end up with just a single topologySpreadConstraint reverted back to the original. If I'm understanding you correctly server side apply is working as desired. That is if the patching entry does not have the same complex key, then add a new entry? It does seem like to be server side apply friendly these complex keys situations should be able to consider a simple key (name) instead. Sorry to tack another thing on, but is it correct to say that you should not rely on defaults with server side apply as no management is considered over the default values? |
We have a doc somewhere, but I just can't find it this mornign, wherein we started accumulating fields that suffer this. When I find it, I will post the list to #118261
Well, it's CORRECT but not helpful given that we have these problematic fields. We are working on how to best address them - almost certainly that will be some changes to SSA.
Not sure what you mean here - clarify for me? |
Let's say I create a deployment via server side apply and it doesn't specify an imagePullPolicy for one of the containers - I'm just relying on the default of IfNotPresent
Then something else modifies the imagePullPolicy to Always. If I simply re-apply the original server side apply without the imagePullPolicy - that will not revert back the Always setting. Meaning effective defaults should be considered unmanaged, and you must include them explicitly to be managed. I'm asking this to clearly set expectations for fabric8 users so that they don't implicitly expect the same behavior as replace. |
@apelisse Can you answer this last part? It's very subtle :)
Defaulted fields are NOT considered in managed-fields, but I can't speak to why. |
We very specifically decided that defaults are not part of your "intent". I can see both sides of the argument (what if you wanted that value but just left it out because you know it will default to the right value). If you have a strong opinion about the field, include it in your manifest. For port/protocol types of key, we need to know the default to index the item in the list, so that's more of an exception. |
Here's some notes on the SSA issue (which is not the same as this one): xref kubernetes-sigs/structured-merge-diff#234 For this issue, I am not sure if there's actually any action to be taken. The @shawkins does that feel wrong? In hindsight, I wonder if "apply" was the right name for this. Perhaps we really wanted 2 operations - "set" (simple create-or-replace) and "merge" (what we call apply). I suspect that vast majority of issues reported with |
Thank you I'll review and probably link to that as well.
There's not, I just need to make sure what the expected behavior and gotchas are.
Not necessarily. It's just going to take some effort to explain the key differences. I think we can boil this down to a few examples of important differences with replace (or the createOrReplace in fabric8) that users will need to keep in mind. We need to be also make sure that users understand that while it will mostly act like apply or a strategic merge patch if the resource exists - it isn't the same.
Yes and the merging aspect can be hard to understand - with the validation issues raised here and on kubernetes-sigs/structured-merge-diff#234 it does seem like there's room for a lot of mismatch between user intent and what the merging resolves to. It was surprising to me for example that port+protocol is a key, but name is not.
set is clear and merge with sufficient guidance is clear. From the perspective of the java operator sdk I'm a little fuzzy on though on what should be done with situations where a server side apply is invalid, or you want to assert ownship over more than just what appears in your patch (manipulate the managedFields and issue PUTs as needed?). |
Can you give an example of that? |
We're working on painting ourselves out of that corner, to the extent that it should never be "invalid" but it might trigger a corner-case path. |
This is coming from the perspective or current java operator sdk handling. The current state of a resource is provided to the reconciliation method, and the developer chooses what of that is meaning to preserve. Typically this has been things like labels, annotations, secret/configmap data. From there they throw away the rest of the existing state when they overlay their desired state. In a more complex scenario using that stategy one could maintain "full control" over the main container of a deployment and let something else manage any other containers. If users want to do something similar with server side apply, I think we are going to say that they must give up control over anything that isn't explicitly set on the main container.
That would be great. Having to know ahead of time all of the possible ways something could alter a resource in such a way as to make it invalid for additional server side applys seems daunting. Another example, again related to validation, is mentioned in #118519 (comment) - if you have an ingress:
Then edit the defaultBackend to use a port name instead, and re-apply the original server side apply you'll get an error:
Interestingly you don't get an error when the same thing is done with the port under the rules. |
I would say that's definitely not a use-case for server-side apply in general. With Server-Side Apply, you typically have an opinion about some fields that doesn't depend on the current state of the object itself. Anytime you need to "change" the object based on its current value, you should use a patch or an update (PUT). It's ok to not use server-side apply everywhere, there are use-cases where it fits and some where it doesn't. |
Indeed. We just need some guidance on what those situations are and how that could be presented to a developer working with fabric8 or the java operator sdk. Thank you both for following up on all of these issues / questions. cc @csviri |
WRT Ingress - Someone needs to make up their mind - is it number or name? SSA doesn't have a mutual-exclusion concept, so it's trying to "apply" the fields which are specified onto the existing state, so the error message is, again, correct. You've given conflicting information. We could manually make it so that setting one clears the other, but that's perilous for other reasons - e.g. "is that really what the user meat to do?" |
I accept that the error is correct, it just seems odd that the handling is inconsistent between the defaultBackend port and the rules port. |
I agree - I'd have to go spelunking to figure out why, and I won't have time this week. |
/sig network |
The Kubernetes project currently lacks enough contributors to adequately respond to all issues. This bot triages un-triaged issues according to the following rules:
You can:
Please send feedback to sig-contributor-experience at kubernetes/community. /lifecycle stale |
The Kubernetes project currently lacks enough active contributors to adequately respond to all issues. This bot triages un-triaged issues according to the following rules:
You can:
Please send feedback to sig-contributor-experience at kubernetes/community. /lifecycle rotten |
The Kubernetes project currently lacks enough active contributors to adequately respond to all issues and PRs. This bot triages issues according to the following rules:
You can:
Please send feedback to sig-contributor-experience at kubernetes/community. /close not-planned |
@k8s-triage-robot: Closing this issue, marking it as "Not Planned". In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
What happened?
After creating a Service with server side apply, modifications to that service may prevent additional attempts at server side apply.
What did you expect to happen?
Ideally the additional server side apply's would be successful at asserting the desired state.
How can we reproduce it (as minimally and precisely as possible)?
Change the protocol via a mechanism other than server side apply
Then reapply:
The error will be
Implying that the merge key is being ignored and that apply is attempting to add another port, rather than modify the existing one.
Anything else we need to know?
The final step works as expected if using client side apply.
Kubernetes version
Cloud provider
OS version
Install tools
Container runtime (CRI) and version (if applicable)
Related plugins (CNI, CSI, ...) and versions (if applicable)
The text was updated successfully, but these errors were encountered: