-
Notifications
You must be signed in to change notification settings - Fork 5.1k
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
Proposal of selector generation #256
Conversation
The controllerRef proposal already claims to solve the "selector overlap" problem, and it was chosen over generated labels for that purpose because of the points discussed here: kubernetes/kubernetes#36859 (comment). I'm working on finishing the implementation of controllerRef. If that works to solve selector overlap, is there an additional benefit to expanding selector generation to all the workload controllers? |
Owner references don't fully solve selector overlap. Between two overlapping deployments A and B (assuming A is older thus works as expected), B cannot adopt the replica sets owned by A but B is still blocked. A unique selector key would address that issue. |
And even if this worked, we could end up in weird situations: Deployment A is deleted. EDIT Nevermind this example, if Deployment A gets deleted (cascade=true), Deployment B will not be able to adopt the replica sets. |
|
||
`extension/v1beta1 Deployment|ReplicaSet|DaemonSet`, `apps/v1beta1 StatefulSet` and `v1 ReplicationController` change as follows. | ||
|
||
Add field `spec.manualSelector`. It controls if using automatic generated selectors. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure I like the additional field. I suggest we always default a key - is there a backwards-compatibility concern here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Users already hardly understand how to use selectors, adding one more field to work-around that will probably cause more confusion than less.
Thinking about it more, if we change our listers to take into account owner references, we may not need selector generation. Haven't looked closely at that but it sounds plausible. |
I had originally thought this was included in the controllerRef proposal, but upon re-reading I see that it's not quite clear what the intention was. The question specifically is what the implications of "ownership" are in this passage:
If the controller ignores an object because its controllerRef points to someone else, I thought that means it will create its own object, so no controller will get stuck. I'll try to get clarification from the reviewer of that proposal. |
That's not how it works :) B is not blocked-- if A wants 10 pod and B wants 10 pods, you'll get total 20 pods. A and B will each construct their pods with the correct controllerRef already specified, so there will never be any un-adopted pods and no opportunity for the two controllers to fight over anything. |
============= | ||
|
||
# Goals | ||
Make selector easy to use and less error-prone for Deployments, ReplicaSet, DaemonSet, StatefulSet and ReplicationController. Make `kubectl apply` work well with selector. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we remove all wording in this doc that's about correctness? controllerRef
should take care of the existing problems. I think there is something that needs to be done to fix kubectl apply
, but this is a really invasive change and we should think about whether anything else can be done.
# Problem Description | ||
The field `spec.selector` of Deployments, ReplicaSet, DaemonSet are defaulted from `spec.template.metadata.labels`, if it is unspecified. | ||
And there is validation to make sure `spec.selector` always selects the pod template. | ||
The defaulting of selector may prevent from `kubectl apply` from working when updating the `spec.selector` field. e.g. [kubernetes/kubernetes#26202 (comment)](https://github.com/kubernetes/kubernetes/issues/26202#issuecomment-221421254) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add an "alternatives considered" section to this doc? I would at least like to see what it would look like to fix this problem by e.g. modifying kubectl apply
instead of every other component :)
|
||
## Garbage collector | ||
|
||
Garbage collector is responsible for cleaning up the extra generated labels when orphaning. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why would this be necessary? I would prefer for GC to not have to do this.
|
||
## Controllers | ||
|
||
Controller managers are responsible to set generated labels when adopting. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't make a lot of sense to me, controllers wouldn't adopt anything that didn't already have the generated label set, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there are some good ideas here, and generally I do like how they permit hiding some controller implementation details from the user. I fear introducing these sorts of changes to the API in a backwards compatible way may be challenging, and create confusion for existing users that already understand how the current implementation functions.
I can think of a couple different problems trying to be solved here.
- Simplify specification of controller objects.
- I imagine the most common case users want is for Pods created by a controller (and only Pods created by that controller) to be managed / owned by it.
- Adopting and Orphaning Pods should be the exception, and the details of how to do such need not be part of the spec
- Generally Simplify updating labels on Pods created by a controller
- Changing labels on Pods contained in the controller selector is a bit of a nightmare. Pod controller references help, but it is confusing what is going on behind the scenes. IIUC they also make querying which Pods are owned by a controller and orphaning more complicated.
- Do controller references solve the case where the PodTemplate labels are updated, but the controller selectors are not? I guess this is caught in Validation instead?
- Reduce the number of (user) errors caused by changing PodTemplate labels with kubectl apply
- If we just focus on this case, we can probably do a lot in the client.
### Automatic Mode | ||
|
||
- User does not specify `spec.selector`. | ||
- User does not specify `spec.manualSelector` field or set it to `false`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like it changes the api in a manner that is not backwards compatible. Is that correct?
|
||
## Garbage collector | ||
|
||
Garbage collector is responsible for cleaning up the extra generated labels when orphaning. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't the process of orphaning itself what cleans up the labels? I guess a Pod could be orphaned by deleting only 1 of the labels.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I really really don't want to build knowledge of various labels into the GC's orphaning process.
### Rationale | ||
|
||
Label combination of `resource name` and `resource kind` is unique across all kind of resources. | ||
They are more predictable and human-friendly than UID. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if this is a good thing. Having the labels that tie controller-to-pods be scary looking might not be terrible :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not actually unique unless you include the group... I would really recommend against doing this.
…ternatives considered section
Updated the proposal:
|
63c66b4
to
80db270
Compare
Updated the proposal:
|
Please do not merge this without my approval. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Counterproposal:
- Warn about selector changes that could orphan pods, for all updates, not just apply
- Warn about label changes in the case of an empty selector in apply
|
||
# Goals | ||
|
||
Make `kubectl apply` work well with selector. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This goal isn't achievable with only client-side changes. In general, changing the selector requires orchestration to ensure that pods aren't accidentally orphaned.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The selector generation has to be done on server, and that should be the goal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed with @soltysh. Also I believe selector generation is going to be useful for more than just making kubectl apply
work. For example, in Deployments we already need to generate a label for making the underlying ReplicaSets non-overlapping.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm inclined to say that everything should be using generated selectors, by default. With the ability to turn it off by a user, when needed. Selectors are for controllers to work with underlying resources, usually. There's nothing stooping users from adding additional labels, if needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I skimmed through the proposal and it seems to target the apply
use case in the client. It will most likely be superseded if apply
is moved server-side. I need to read the selector generation proposal for Jobs.
|
||
### Rationale | ||
|
||
Label combination of `resource group`, `resource kind` and `resource name` is unique across all kind of resources. They are predictable, human-friendly and self-documenting, but we need all of them to assure uniqueness. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem with resource name is that it's a single attribute. In practice, in order to make it unique, users will concatenate several attributes. However, if they don't plan for all attributes they'll eventually need in advance, they'll need to delete the resource and recreate it in order to add more attributes. Labels representing individual attributes, OTOH, could be added later. Or, in the case that a new controller needed new distinguishing attributes, the selector(s) of the original controller(s) could be updated to select the absence of the new label key.
I think we'd be better off providing conventions and tools to set a number (3-5) of common attributes by default.
|
||
Label combination of `resource group`, `resource kind` and `resource name` is unique across all kind of resources. They are predictable, human-friendly and self-documenting, but we need all of them to assure uniqueness. | ||
|
||
Label `UID` itself is unique. It is simple but unpredictable. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be made clearer that because uid is unpredictable, it's not part of this proposal.
|
||
# Proposed changes | ||
|
||
We can let `kubectl` do something similar to [Selector Generation](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/selector-generation.md) on creation. We can let `kubectl` add a set of labels to assure non-overlapping. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can't change default behavior.
The second set of labels is: | ||
|
||
- Add 1 more label, which concatenates all the three in the first set, to `spec.selector` | ||
- `matchLabels["controllers.k8s.io/selector"]="$GROUP/$KIND/$NAME"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this needed if we have the other 3 labels?
Also, I try to avoid label keys with prefixes.
- Add 1 more label to `spec.selector` | ||
- `matchLabels["resource-uid"]="$UIDOFRESOURCE"` | ||
- Append 1 label to `spec.template.metadata.labels` | ||
- `resource-uid=$UIDOFRESOURCE` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't see why uid is needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should rather go in the direction Jobs has implemented, iow. using uuid as a selector, although this will make the selectors hard to read and use by regular users.
|
||
# Goals | ||
|
||
Make `kubectl apply` work well with selector. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The selector generation has to be done on server, and that should be the goal.
This approach isn't aligned with the intent of labels, so I'm closing this proposal. cc @kow3ns |
* Fix peribolos config * Add readme and makefile * Grab dep * Remove sync command
Selector generation for Deployments, ReplicaSet, DaemonSet, StatefulSet and ReplicationController.
Originally discussed in #187.
cc: @pwittrock @erictune