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

Add server-side apply mode #651

Merged
merged 10 commits into from
Apr 27, 2022
Merged

Add server-side apply mode #651

merged 10 commits into from
Apr 27, 2022

Conversation

smuth4
Copy link
Contributor

@smuth4 smuth4 commented Nov 29, 2021

Aside from all the benefits listed elsewhere, this would fix issues like prometheus-operator/kube-prometheus#1511.

While testing I did find that it's not entirely a clean conversion when working with objects that have already been applied client-side. Non-functional formatting differences (e.g. "1024Mi" vs "1Gi") or missing default fields will cause the apply to fail and report that it has a field management conflict with "kubectl-client-side-apply". Once a server-side apply succeeds (either by recreating the object or by using --force-conflicts) everything works as expected, just wanted to mention it since it was a bit surprising.

I also kept the code simple as a POC, if desired I can make it a flag similar to --diff-strategy.

Copy link
Member

@Duologic Duologic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the server-side the default in kubectl (from 1.22)? If not, can we make it optional on Tanka too?

@smuth4
Copy link
Contributor Author

smuth4 commented Dec 14, 2021

It's intended to be a general replacement for any client-side apply, but I don't know of any active plans to make it the default for kubectl in particular. I've moved it to be an optional field in spec.json, still defaulting to the normal apply.

Comment on lines 28 to 33
many can be found before an apply with the `validate`
[diff strategy](/diff-strategy).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR already looks great.

It may be a little out-of-scope but I was wondering whether we should make this consistent for both diff and apply.
tk diff could also honor the applyStrategy option if set in spec.json and it could have a CLI flag (replacing diff-strategy=validate): tk diff --diff-strategy=native --server-side (native is the default strategy)

@julienduchesne do you think this makes sense?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think --diff-strategy=validate should be renamed (or aliased) to --diff-strategy=server, that would be consistent enough IMO. Having both a --server-side and a --(diff|apply)-strategy might get confusing.

Also, the diffStrategy and applyStrategy settings are nice since you can toggle them independently in the spec (someone may wish to apply server-side but do a simple diff, or vice-versa, server-side sometimes has a weird behavior)

@julienduchesne julienduchesne self-requested a review January 3, 2022 01:43
Copy link
Member

@julienduchesne julienduchesne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add the --apply-strategy flag for consistency between apply and diff. Other than that, this PR looks great!

Comment on lines 28 to 33
many can be found before an apply with the `validate`
[diff strategy](/diff-strategy).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think --diff-strategy=validate should be renamed (or aliased) to --diff-strategy=server, that would be consistent enough IMO. Having both a --server-side and a --(diff|apply)-strategy might get confusing.

Also, the diffStrategy and applyStrategy settings are nice since you can toggle them independently in the spec (someone may wish to apply server-side but do a simple diff, or vice-versa, server-side sometimes has a weird behavior)

@smuth4 smuth4 changed the title Apply changes server-side starting in v1.22 Add server-side apply mode Jan 10, 2022
@smuth4
Copy link
Contributor Author

smuth4 commented Jan 10, 2022

@julienduchesne @Duologic I ended up adding a 4th distinct diff mode called server, which displays the server-side diff in all it's glory, and is the new default whenever server-side apply is enabled (still override-able by CLI flags and spec.json). I figured being truer to what the apply would actually do was worth having the cruft being shown. I'm not stuck on this behavior though, if you want me to change it back to a simple alias or something, that's not an issue.

I also added the --diff-strategy flag to the apply command since the code seemed to already be set up for that.

@fculpo
Copy link

fculpo commented Jan 15, 2022

Hi, this MR would solve a lot of issue for us too, when can we expect it to land in master ?

@julienduchesne
Copy link
Member

julienduchesne commented Jan 20, 2022

Hi, this MR would solve a lot of issue for us too, when can we expect it to land in master ?

The changes look good to me overall (I'd like to look more in-depth though)
I'll give it a test drive this week and I think I'd like to do a release around end of next week to integrate jsonnet 0.18, so I'll see if I can integrate this one as well

@sh0rez
Copy link
Member

sh0rez commented Jan 28, 2022

Hi!

Aside from all the benefits listed elsewhere, this would fix issues like prometheus-operator/kube-prometheus#1511.

OMG yes, finally!


Before doing an in-depth code review, I got some general questions.

  1. From https://kubernetes.io/blog/2019/01/14/apiserver-dry-run-and-kubectl-diff/:

    APIServer dry-run [...]. kubectl diff does exactly what you want by showing the
    differences between the current "live" object and the new "dry-run" object.

    To me, that reads as if bare kubectl diff already runs server-side. This PR appears to be introducing a new server diff strategy. What is the difference in behavior? And how does it compare to validate?

  2. Currently, this seems to be hidden away after a flag. Given the relevance of described above issue, it sounds to me as if it should be the default behavior, falling back to client side apply depending on version number. Let's enable it from 1.16+, keeping the flag as an override.

@julienduchesne
Copy link
Member

I think I can answer those

  1. To me, that reads as if bare kubectl diff already runs server-side. This PR appears to be introducing a new server diff strategy. What is the difference in behavior? And how does it compare to validate?

The output is very different between a bare diff and --server-side diff. The server-side diff will show lots of additional fields being modified
validate was added to fix #332. It does a server-side diff to check for errors but then shows the normal non-server-side diff for readability. So the options are essentially:

  • native: Only diff non server-side
  • validate: diff server-side to check for errors then diff non-server-side
  • server Only diff server-side

Currently, this seems to be hidden away after a flag. Given the relevance of described above issue, it sounds to me as if it should be the default behavior, falling back to client side apply depending on version number. Let's enable it from 1.16+, keeping the flag as an override.

That would be kind of breaking. For our own workflows, we'd have to explicitely disable it to get more readable diffs. Also, server-side diff will break on certain manifests that diff and apply just fine in non server-side mode

@fculpo
Copy link

fculpo commented Feb 24, 2022

Hi, any progress on this ?

@smuth4
Copy link
Contributor Author

smuth4 commented Mar 26, 2022

I've been using this for a while without issue and would still like to see it get merged. If that last commit to fix pruning complicates things, I can split it out into a separate PR.

@tomasfreund
Copy link

Hi, is there any progress on this? it would be quite useful for us to have this feature

@smuth4
Copy link
Contributor Author

smuth4 commented Apr 18, 2022

I see #695 was merged in with a different approach to server-side support, is this PR still useful? CC @jjo

@julienduchesne
Copy link
Member

Sorry for the lack of communication on this @smuth4. The other PR sneaked by due it being much smaller. If you still need the config attributes, feel free to rebase and @ me, I'll be sure to take a look this time

1 similar comment
@julienduchesne
Copy link
Member

Sorry for the lack of communication on this @smuth4. The other PR sneaked by due it being much smaller. If you still need the config attributes, feel free to rebase and @ me, I'll be sure to take a look this time

@jjo
Copy link
Contributor

jjo commented Apr 25, 2022

Sorry for the lack of communication on this @smuth4. The other PR sneaked by due it being much smaller. If you still need the config attributes, feel free to rebase and @ me, I'll be sure to take a look this time

I much prefer @smuth4 approach, as it's much more sustainable re: future kubectl apply/diff args, totally fine to rollback #695 (the sooner the better).

@smuth4
Copy link
Contributor Author

smuth4 commented Apr 27, 2022

Thanks for the responses, I've rebased it with the flag rolled back, and if it gets rolled back separately I don't mind rebasing again.

@julienduchesne I think this is pretty much ready for review. There might be room for improvement in cases where a apply --force will fail on the diff but apply perfectly fine (typically on fields that something else tried to manage), but I don't think that's a must-solve issue.

Edit: Immediately after typing that, I realized that I'm incorrect, it would be a problem for anyone who wants to use validate. In the interest of maintain existing workflows first and foremost, I've added --force-conflicts to all server-side diffs, but it could probably stand to be made more dynamic.

Copy link
Member

@julienduchesne julienduchesne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright! Let's try this out! Thanks for your work @smuth4!

@julienduchesne julienduchesne merged commit e3922f8 into grafana:main Apr 27, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants