-
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
v2 API proposal "desired vs actual" #17333
Comments
I have been thinking for a while that a "one writer" policy (at some TBD level of granularity) would be a good thing. For comparison, why not annotate (comment/struct tag) every field that the system writes and forbid the user from setting it. This seems less invasive. (If the user is allowed to make a request, add a "BlahRequest" block or some such.) With the system in the OP, it looks to me like there is a big new class of bugs when the user updates the spec.
Additionally, doesn't this still have the original problem that caused us to split the types? There'd be fields in 'spec' that the user shouldn't set. kubectl apply already stores the original request in an annotation. You can never unapply defaults with this system (also with our current system). It's unclear to me if this is a bug or a feature. |
See also #1178 |
This is basically what we do with spec and status. There should be I much prefer to have a source of "combined desired truth" in a single
Writes to
Correct. I also do not like this. This is why we should consider
Without fully analyzing EVERY field of every struct: No, everything in
It's not very usable, and it is becoming a problem, as I understand it.
This was my last point. My feeling is that it's not that important to |
I think it requires an entirely new process? User writes an update to That mystery code will involve a bunch of boilerplate (probably under-tested and bug ridden), or it will involve another invocation of the conversion stuff (complex, still under-tested, but probably fewer bugs).
That's not really what I had in mind at all. I was saying, individually per-field in spec, have a comment marker/struct field tag called e.g. |
User POSTs to User PUTs to I'm hand-waving, obviously it's a little tricky and we'll need to
yeah, we can code-gen a lot of this.
I think it's a little gross, but I guess it could work. We could e.g. User POSTs System writes GET of /api/v2/.../name yields GET of /api/v2/.../name/orig yields Internally |
I'm in favor of this, at the risk of having even larger API objects than we If you think about what most automated elements of the cluster are doing, user POST {spec: {something: bar}} Both admission control and initializers could set overrides. On Mon, Nov 16, 2015 at 8:22 PM, Tim Hockin notifications@github.com
|
@lavalamp @thockin This cannot work and I'm opposed to it on principle. There is deliberately no hard line between what can be set by the user and what can be set automatically. One example of many: vertical auto-scaling. For more examples, see #17097. |
@smarterclayton My original proposal in #1178 was that automated components set "underrides" -- everything the user specifies takes precedence over automatically set values. |
@bgrant0607 sounds like you just don't buy my "one-writer" policy idea at all. I mention it because it's much simpler and less invasive. I guess I am not in favor of this at the moment. We're already struggling with the amount of complexity in the API system and this makes it worse. |
cc @jackgr |
In this proposal, what would be the behavior for fields set by the user initially and then overridden by the system in actual? Presumably Is |
It looks like this issue has new life based on some recent discussions. I think that it is important to look at this from the end user experience. Right now the best we have is I wrote up some of the thoughts on viewing driving the system as declarative vs. imperative and the confusing aspects of |
On Wed, Jan 11, 2017 at 9:46 AM, Phillip Wittrock ***@***.***> wrote:
In this proposal, what would be the behavior for fields set by the user initially and then overridden by the system in actual? Presumably actual would take priority. If the user updates the field in spec, does it then overwrite the field in actual set by the system?
I don't have all the answers, but your presumption seems correct at a
glance. Iguess that end-user changes to `spec` would flow into
`actual`, as if the user changed `spec` today. Auto-scalers and
whatnot would change `actual` the same way they change `spec` today.
It's unclear what a subresource like /scale should change...
Is actual meant to be written by any actor that is not the "owner" / creator of the object? e.g. a 3rd party CICD system that would continuously update the image for a Deployment?
That's what I was thinking. It *feels* like some scheme like this
would make automation, patching, etc easier. I am very likely off in
the details, and this is perhaps too big a change to ever do short of
a major API overhaul...
|
I always had the assumption that - as @thockin says - actual will end up to have the same value as spec, if not then there must be an issue somewhere. Just my 2ct |
Declarative defaulting is relevant: #25460 The current open-coded version-specific defaults are a problem when converting the configured state, since defaults are deliberately not set in the configured state. |
Issues go stale after 90d of inactivity. Prevent issues from auto-closing with an If this issue is safe to close now please do so with Send feedback to sig-testing, kubernetes/test-infra and/or |
/remove-lifecycle stale |
For those who want to watch @lavalamp talking through the presentation posted above, there is a recording of SIG Architecture meeting https://www.youtube.com/watch?v=6HfntQM757M |
/wg apply |
/remove-kind design
|
Should we open a KEP / start a pre-KEP discussion about this change? |
We should close this as it will never happen. |
Maybe we can enhance server-side apply to better capture the specified vs. actual differences. I can see that being both useful and compatible. |
This has come up a bunch in a lot of small ways, and my mind keeps coming back to this idea, so I want to write it down.
In early early kube API we had
desired
andactual
(or something like that) structs. Since they were the same struct there were a bunch of things in the struct that were things we didn't want users to set (which eventually became status) and other problems. As we changed tospec
+status
, we lost the concept of "actual" and just folded it intospec
.This conflates a couple of ideas and makes it hard to distinguish what the user actually asked for from what was assigned to them. I am proposing we reinstate that distinction.
I propose that every top-level object (all of them, not just the ones that make sense RIGHT NOW) holds 4 fields (plus ObjectMeta):
metadata
- same meaning as todayspec
- what the user asked for, with API-defined defaults applied AND NOTHING ELSE. Every field is available to users.actual
- the exact same structure asspec
, but with other fields populated by the system (e.g. nodeName when scheduled, clusterIP when auto-assigned, and so on)status
- same meaning as todayIf a user wants to save a pod and move it to another cluster,
spec
is what they want. If a piece of software wants to know how a pod is operating,actual
andstatus
are what they want.I chose this layout (which changes the meaning of
spec
because I figured it makes it easier on users to change over, while making it harder for system components (change toactual
). This may be wrong, but it's not obvious. An alternative would be thatspec
means "actual" andrequest
means "what the user asked for"; users writerequest
and the system writesspec
. This has the advantage of software that observes state being easier to change over, but means that users have more pain. But it is perhaps better to break users, who actually SEE error messages. Sometimes bigger changes are better because the need to something is obvious (see the bugs people hit with some really subtle v1beta1 -> v1 changes).It would be nice to make one field writable ONLY by users (create/update) and one field writable only by the system. We've used binding for scheduling, but there are other things (like clusterIP) that are written directly in-process.
We could make this round-trippable by embedding
request
understatus
in v1 or even as a new top-level object + sub-resources.Lastly, there's some question about preserving exactly what the user asked for WITHOUT defaults applied, but I am less sure that is needed or particularly useful.
@bgrant0607 @smarterclayton @lavalamp
The text was updated successfully, but these errors were encountered: