-
Notifications
You must be signed in to change notification settings - Fork 40k
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
Reuse nodePort on kubectl apply service #23551
Comments
@kubernetes/goog-cluster |
I think what's happening is that you are PUTing a yaml blob that has no NodePort value, which defaults to 0, which means "allocate one for me". This has come up a number of times specifically wrt services. The canned answer is "you have to read it, mutate it, and write it back if you want to preserve fields with defaulted values". This is principally sound but it is unsatisfying in cases such as this ( In fact, you SHOULD get an error here saying:
Are you explicitly setting I want to offer again that we bend the principles here. What if we allowed for PUTs of fields that are auto-allocated by default to assume that if the value is not provided on the PUT we should retain the value from the old version. I'm not sure if we can tell "unset" from "set to 0" for nodePort, but even allowing 0 to mean "retain" is OK to me. Strictly speaking, we ARE allocating a value, it just happens to be the exact same as the value that we just released. The only 2 fields I know of for which this applies would be service.spec.ports[*].nodePort and service.spec.clusterIP. What think, Brian? |
This problem is caused by 2 things:
|
I am opposed to changing PUT semantics. PUT is expected to be used in read-modify-write situations. |
cc @kubernetes/kubectl |
Unless we handle this gracefully O(soon) then apply is effectively useless On Wed, Mar 30, 2016 at 9:23 PM, Brian Grant notifications@github.com
|
I will look into this this weekend. |
The svc-test.yaml file I posted is the actual file I used for the test, I didn't include the clusterIP or the nodePort. |
It's not obvious to me that this is caused by the kubectl round-tripping, but if so, @krousey is working on that. |
@bgrant0607 @lavalamp I spent a little time on this, and took a deep look. As @lavalamp said, I believe this is not caused by the kubectl round-tripping, the patch in this example would be: |
Alright, we'll let @krousey close this when he removes the round tripping. |
@lavalamp so remove the round tripping will fix this issue? am I right? |
In order for apply to work properly, we need to be able to distinguish unset from Go default. targetPort should not be 0.
We'll need to change all optional fields to pointers. In this case, could we make IntOrString default to empty string instead? However, it not clear why nodePort should be reallocated on patch: kubernetes/pkg/registry/service/rest.go Line 244 in dae5ac4
|
@bgrant0607 in this simple example, after apply patch, the service nodePort kubernetes/pkg/registry/service/rest.go Line 243 in dae5ac4
|
Also the define of nodePort is:
it's impossible to distinguish unset from Go default for nodePort. |
That's easy enough to change, though. Will that fix this issue? On Wed, Apr 6, 2016 at 8:42 PM, TonyAdo notifications@github.com wrote:
|
for now in kubectl, we just replace spec.nodePort with modified map(which comes from input), in the api-server when we get the patch, we do replace too, if we can do some merge in kubectl, I think we can keep the nodePort in the final patch. |
How many other fields are broken like this? Server allocated fields that On Thu, Apr 7, 2016 at 5:27 AM, TonyAdo notifications@github.com wrote:
|
@bgrant0607 I just meet some problems when I try to update the
I did try to run above scripts to update generated code, but just failed. could you tell me what I have to do after I update |
@adohe We don't want to change nodePort to IntOrString. In this case, we could probably interpret 0 as unset. In general, we'd need to change such a field to a pointer. The field would need to be changed in both api/types.go and in api/v1/types.go. However, the patch really shouldn't have trashed nodePort. Regardless, I don't think we want to reallocate nodePort if one had already been allocated for a given service port. |
@bgrant0607 I take a deep look at this issue, and just found the root cause of nodePort cannot reuse is that we do simple replace for |
@adohe Good catch! We need to specify that this field should be merged: by adding |
@bgrant0607 I did try to do this, add this |
As for now I think it is really hard to change the |
@adohe The patchMergeKey should be port, not nodePort. |
If you still find you need to update nodePort to a pointer and the compilation errors are in generated code, comment out that code and then try to regenerate it: |
@bgrant0607 thanks very much. :) I will try that. |
Any update on this? |
I see the PR, sorry. Thanks!! |
Automatic merge from submit-queue Fix unintended change of Service.spec.ports[].nodePort during kubectl apply Please refer #23551 for more detail. @bgrant0607 I think this simple fix should be ok to reuse nodePort. @thockin ptal. Release note: Fix unintended change of `Service.spec.ports[].nodePort` during `kubectl apply`.
we can close this now. |
can someone explain who understands the tags patchStrategy:"merge" patchMergeKey:"port"` and acts on then and where is this happening in the code? |
@krmayankk This is telling |
In release 1.2 the NodePort of a service changes every time the service get's applied:
Example service svc-test.yaml:
First apply, service doesn't exist:
Second apply:
The nodePort changed form 31585 to 32124.
It would be nice if the port stayed the same:
The text was updated successfully, but these errors were encountered: