Added MatchFields to NodeSelectorTerm#62002
Added MatchFields to NodeSelectorTerm#62002k8s-github-robot merged 2 commits intokubernetes:masterfrom
Conversation
|
/retest |
|
/retest |
pkg/apis/core/types.go
Outdated
There was a problem hiding this comment.
does this change MatchExpressions to be optional (at least one of MatchExpressions and MatchFields must be specified?), or would you expect this to be paired with a MatchExpression that selected everything (is that even possible)?
There was a problem hiding this comment.
at least one of MatchExpressions and MatchFields must be specified
This one :) And the requirements are ANDed; if both are not empty, they also are ANDed.
There was a problem hiding this comment.
Done; updated comments and added validation. Does not check the key of MatchFields, will handle it when adding related logic in scheduler.
|
ping for comments :) /retest |
|
/sig scheduling |
|
/retest |
There was a problem hiding this comment.
I think this loosening of validation makes sense, but can cause grief for a 1.10-level apiserver (during rolling upgrade or downgrade from running 1.11):
- an object with a podspec is submitted with MatchFields set and MatchExpressions unset, 1.11 apiserver validates and persists it
- during rolling HA upgrade or after downgrade to 1.10, a 1.10 apiserver will not know about the MatchFields field, and would consider the object invalid and disallow updates to it (and possibly disallow deleting it)
The doc on the NodeSelectorTerm type says // A null or empty node selector term matches no objects. which would be acceptable for the 1.10 scheduler to do (would fail safe with "unscheduleable" error), but the actual API validation code in 1.10 prevents an empty node selector term from being allowed.
There was a problem hiding this comment.
The doc on the NodeSelectorTerm type says
// A null or empty node selector term matches no objects. which would be acceptable for the 1.10 scheduler to do (would fail safe with "unscheduleable" error), but the actual API validation code in 1.10 prevents an empty node selector term from being allowed.
Good point; the implementation of schedule match this doc/comment. Scheduler will let pod pending with 'unscheduleable' error. I think we should remove this validation in 1.11; for 1.10, not sure, cherry-pick??
I'm a little confused about this; another meaning maybe: the NodeSelectorTerms []NodeSelectorTerm in NodeSelector; for each single term, the MatchExpressions can not be nil or empty.
But both cases (NodeSelectorTerms is nill and MatchExpressions is nill ) are handled by scheduler (nodeMatchesNodeSelectorTerms and NodeSelectorRequirementsAsSelector); so that's safe to remove it in 1.11, for 1.10, not sure, cherry-pick it?
There was a problem hiding this comment.
I'm a little confused about this; another meaning maybe: the NodeSelectorTerms []NodeSelectorTerm in NodeSelector; for each single term, the MatchExpressions can not be nil or empty.
the documentation is pretty clear, and the implementation actually behaves as documented if it is given a NodeSelectorTerm that is empty (v1helper.NodeSelectorRequirementsAsSelector(req.MatchExpressions) returns labels.Nothing() if there are no match expressions)
I would pick a fix to validation in 1.10 to tolerate missing MatchExpressions:
func ValidateNodeSelectorTerm(term core.NodeSelectorTerm, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
- if len(term.MatchExpressions) == 0 {
- return append(allErrs, field.Required(fldPath.Child("matchExpressions"), "must have at least one node selector requirement"))
- }
for j, req := range term.MatchExpressions {
allErrs = append(allErrs, ValidateNodeSelectorRequirement(req, fldPath.Child("matchExpressions").Index(j))...)
}cc @msau42 since this is called from validateStorageNodeAffinityAnnotation as well
There was a problem hiding this comment.
this isn't a valid field path... what we typically do in situations like this is put the required error on the parent struct with a message. for example:
if numVolumes == 0 {
allErrs = append(allErrs, field.Required(fldPath, "must specify a volume type"))
}
There was a problem hiding this comment.
is the plan to allow the API to be expressive, and just result in errors by the scheduler or the kubelet if unsupported keys or operations are expressed?
There was a problem hiding this comment.
prefer to let scheduler/kubelet the handle the specific key; as fields are supported by k8s version, e.g. metadata.name in 1.11 :)
There was a problem hiding this comment.
Is the validation done in ValidateNodeSelectorRequirement valid for keys/values that are not limited to valid label keys/values (given these MatchField terms are referencing non-label field names and values)
There was a problem hiding this comment.
Other field references in the API (like the downward API) validate specific field reference names. Are we sure we want to allow arbitrarily complex expressions here, when the intent is just to support metadata.name=foo? We can't reasonably tighten validation on this field in the future, so just calling it out here.
pkg/apis/core/types.go
Outdated
There was a problem hiding this comment.
remove At least one of 'MatchExpressions' and 'MatchFields' must be specified, since that conflicts with A null or empty node selector term matches no objects., and we want a 1.10 server to tolerate a NodeSelectorTerm containing no MatchExpressions field.
There was a problem hiding this comment.
I would actually remove this requirement completely... an empty term matches no objects, as documented. Stick to validating MatchExpressions or MatchFields if they provide them
Automatic merge from submit-queue (batch tested with PRs 62448, 59317, 59947, 62418, 62352). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. Removed no-empty validation of nodeSelectorTerm.matchExpressions. Signed-off-by: Da K. Ma <klaus1982.cn@gmail.com> **Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*: part of #62002 **Release note**: ```release-note Pod affinity `nodeSelectorTerm.matchExpressions` may now be empty, and works as previously documented: nil or empty `matchExpressions` matches no objects in scheduler. ```
There was a problem hiding this comment.
Please add // +optional to both fields.
pkg/apis/core/v1/helper/helpers.go
Outdated
There was a problem hiding this comment.
Why do we continue here? Shouldn't we return false instead?
There was a problem hiding this comment.
because the terms are ORed, a failure in one should not short circuit
There was a problem hiding this comment.
It should be ORed between terms, and ANDed within a terms (matchExpressions and matchFields).
pkg/apis/core/v1/helper/helpers.go
Outdated
There was a problem hiding this comment.
Same as above. Shouldn't we return false?
pkg/apis/core/v1/helper/helpers.go
Outdated
There was a problem hiding this comment.
In most of our code base (or maybe all of it), we AND terms when there are multiple of them. Why are we ORing here?
There was a problem hiding this comment.
that was what was designed and documented previously, so for compatibility.
the reason that design makes sense is that each NodeSelectorTerm can already express everything that ANDing together multiple terms could.
the only reason to have a list of multiple terms is to let you select distinct sets of nodes matching non-overlapping selectors, which requires ORing the terms together.
There was a problem hiding this comment.
pkg/fields/selector.go contains field-selector related things... I didn't really expect this added to the labels package
There was a problem hiding this comment.
Moved to fields/selector.go; but for now, we only support equals and not equals for matchFields which is enough for scheduling DaemoSet pods by default scheduler. For the other advance features, e.g. IN/NotIN for a set, will be handled in a separate issue. If any comments/suggestion please let me know.
586bb2b to
2cc53dc
Compare
There was a problem hiding this comment.
+1. Let's not add unnecessary changes to the PR.
There was a problem hiding this comment.
is the expectation that ParseSelector(s.String()) would return a selector with equivalent behavior? If so, this doesn't hold
There was a problem hiding this comment.
I guess labels.Nothing() has the same issue... worth noting that the Nothing() selector is not appropriate for serializing to string for persistence and later parsing
|
a couple nits, lgtm otherwise will leave to @kubernetes/sig-scheduling-api-reviews for final LGTM /approve |
There was a problem hiding this comment.
+1. Let's not add unnecessary changes to the PR.
Signed-off-by: Da K. Ma <klaus1982.cn@gmail.com>
Signed-off-by: Da K. Ma <klaus1982.cn@gmail.com>
|
/lgtm |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: k82cn, liggitt The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
|
Automatic merge from submit-queue (batch tested with PRs 62495, 63003, 62829, 62151, 62002). If you want to cherry-pick this change to another branch, please follow the instructions here. |
|
This seems different from what's discussed in #61410 (just having a specific term for |
|
here's suggestion: #61410 (comment) . And current term are label based: 1.) the validation for field maybe different with label's, 2.) the name of 'specific term' maybe conflict with existed label. |
| MatchFields: []v1.NodeSelectorRequirement{{ | ||
| Key: "metadata.name", | ||
| Operator: v1.NodeSelectorOpIn, | ||
| Values: []string{"host_1, host_2"}, |
There was a problem hiding this comment.
that test confused me a bit as I guess its still an array with only 1 element ? (guess the test is supposed to check that only one element is allowed by providing something like []string{"host1", "host2"} instead.
Sorry, to be picky, but I ended up here as I found no other real documentation for the "machtFields" selector (and I think the official documentation at https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.11/#nodeselectorterm-v1-core is a bit misleading as it does not mention that only 'In' and 'NotIn' are allowed, with only one value allowed in the list of terms.
There was a problem hiding this comment.
@rhuss This PR was merged in April 2018. It is too late to leave review comments. If you have ideas to improve or fix the code, please go ahead and send a PR.
| "must be only one value when `operator` is 'In' or 'NotIn' for node field selector")) | ||
| } | ||
| default: | ||
| allErrs = append(allErrs, field.Invalid(fldPath.Child("operator"), req.Operator, "not a valid selector operator")) |
There was a problem hiding this comment.
would change to 'not a valid node field selector operator' to make clear which kind of selector is meant.
| } | ||
|
|
||
| if vf, found := nodeFieldSelectorValidators[req.Key]; !found { | ||
| allErrs = append(allErrs, field.Invalid(fldPath.Child("key"), req.Key, "not a valid field selector key")) |
There was a problem hiding this comment.
"node field selector" to harmonize with the other error messages.
What this PR does / why we need it:
Which issue(s) this PR fixes (optional, in
fixes #<issue number>(, fixes #<issue_number>, ...)format, will close the issue(s) when PR gets merged):part of #61410
Special notes for your reviewer:
According to the discussion at #61410 , we'd like to introduce a new selector term for node's field.
Release note: