-
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
Add PriorityClass API object under new "scheduling" API group #48377
Conversation
@kubernetes/api-approvers |
pkg/apis/scheduling/types.go
Outdated
// integer value. The value can be any valid integer. | ||
type PriorityClass struct { | ||
metav1.TypeMeta | ||
// +optional |
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.
How about adding more comments here?
// Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata.
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.
Thanks, @gyliu513 ! Done.
pkg/apis/scheduling/types.go
Outdated
// PriorityClassList is a collection of priority classes. | ||
type PriorityClassList struct { | ||
metav1.TypeMeta | ||
// +optional |
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.
// Standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds
// +optional
allErrs := apivalidation.ValidateObjectMetaUpdate(&pc.ObjectMeta, &oldPc.ObjectMeta, field.NewPath("metadata")) | ||
// Name is immutable and is checked by the ObjectMeta validator. | ||
if pc.Value != oldPc.Value { | ||
allErrs = append(allErrs, field.Forbidden(field.NewPath("Value"), "may not be changed in an update.")) |
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.
How about putting the Value
in the error message?
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 putting the value in the error message is a bit misleading and may make users think that there is an issue with the value itself. We don't allow changing value
regardless of its content.
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.
Make sense, thanks @bsalamat
if pc.Value != oldPc.Value { | ||
allErrs = append(allErrs, field.Forbidden(field.NewPath("Value"), "may not be changed in an update.")) | ||
} | ||
if pc.GlobalDefault != oldPc.GlobalDefault { |
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 cannot change GlobalDefault
? It not, the comments for this fn also need some update.
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 has a similar problem to changing value
, i.e., if the GlobalDefault changes, the integer value of pods without any priority class which were resolved before the change of GlobalDefault
may confuse users. Besides, there is a risk of having multiple priority classes with GlobalDefault
set. I updated the comment.
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 revisited the idea of letting GlobalDefault be updatable today. I can prevent users from setting multiple priority classes as default in the admission controller. So, the main risk can be mitigated. The confusion problem of updating GlobalDefault stills remain, but the flexibility that allowing the update provides may justify it. WDYT?
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 always good idea to mitigate the risk even though it cannot fully resolve the issue, +1 on this, thanks @bsalamat ;-)
allErrs = append(allErrs, field.Forbidden(field.NewPath("Value"), "may not be changed in an update.")) | ||
} | ||
if pc.GlobalDefault != oldPc.GlobalDefault { | ||
allErrs = append(allErrs, field.Forbidden(field.NewPath("GlobalDefault"), "may not be changed in an update.")) |
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.
How about adding the GlobalDefault
to the error message?
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.
Similar to my comment about putting value
in the error message, I think it may be misleading.
41fd2a1
to
e9cea8b
Compare
/lgtm This is probably api-machinery for approval though. |
func ValidatePriorityClassUpdate(pc, oldPc *scheduling.PriorityClass) field.ErrorList { | ||
allErrs := apivalidation.ValidateObjectMetaUpdate(&pc.ObjectMeta, &oldPc.ObjectMeta, field.NewPath("metadata")) | ||
// Name is immutable and is checked by the ObjectMeta validator. | ||
if pc.Value != oldPc.Value { |
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 comments say that Name and Value are immutable, but you check Value & GlobalDefault.
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.
+1
btw, do we allow update Default?
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 fixed the comment to say that Name, Value, and GlobalDefault are immutable. Name is checked by the default validation of metadata.
@k82cn no, we don't.
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.
Got it; and there'll be only one default priority in the cluster, right? and we'll check it in admission controller.
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.
yes, and yes!
old := scheduling.PriorityClass{ | ||
ObjectMeta: metav1.ObjectMeta{Name: "tier1", Namespace: "", ResourceVersion: "1", | ||
Annotations: map[string]string{ | ||
"kbernetes.io/description": "Used for the highest priority pods.", |
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.
typo: kbernetes
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.
Actually, I removed the whole annotation. I learned that we should not use annotations for information which should be discoverable by users. So, I changed description from an annotation to a field and this was a remnant of the initial code. Thanks for pointing it out!
) | ||
|
||
// GroupName is the group name use in this package | ||
const GroupName = "scheduling.k8s.io" |
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.
scheduling
? seems others are without k8s.io
.
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.
Our document says that we should use xyz.k8s.io. Some of the other groups use the k8s.io suffix and some don't. I think the suffix is preferred.
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 you share the doc link? if xxx.k8s.io
is preferred, I think we need to open a PR/Issue to correct others.
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.
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.
Opened #48527 to align the GroupName. lgtm for this PR.
func ValidatePriorityClassUpdate(pc, oldPc *scheduling.PriorityClass) field.ErrorList { | ||
allErrs := apivalidation.ValidateObjectMetaUpdate(&pc.ObjectMeta, &oldPc.ObjectMeta, field.NewPath("metadata")) | ||
// Name is immutable and is checked by the ObjectMeta validator. | ||
if pc.Value != oldPc.Value { |
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.
+1
btw, do we allow update Default?
}, | ||
} | ||
|
||
for k, v := range errorCases { |
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.
suggest merge errorCases & successCases like others.
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.
Some of the other groups, such as autoscaling, storage, rbac, ... follow this pattern of separate error and success cases.
// set correctly. | ||
func ValidatePriorityClass(pc *scheduling.PriorityClass) field.ErrorList { | ||
allErrs := field.ErrorList{} | ||
allErrs = append(allErrs, apivalidation.ValidateObjectMeta(&pc.ObjectMeta, false, ValidatePriorityClassName, field.NewPath("metadata"))...) |
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.
PriorityClass is global by default, so the namespace should be empty.
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 API object is defined as "nonNamespaced" in staging/src/k8s.io/api/scheduling/v1alpha1/types.go. My understanding is that the system enforces the rule of not having a namespace for "nonNamespaced" resources.
We have tests that verify it does not take any namespace.
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.
Great to know !
BTW, do you know which component handled nonNamespaced
? just want to learn :).
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 don't know. I wonder if the // +nonNamespaced=true
annotation in the types.go file causes some validation code to be generated that checks this.
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.
ok, np.
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.
/lgtm
/assign @smarterclayton |
@justinsb SIG API Machinery doesn't own the contents of the API. |
cross-build is currently broken: #48887 |
@smarterclayton Fixed the comments. PTAL. |
/test pull-kubernetes-cross |
pkg/apis/scheduling/types.go
Outdated
|
||
// PriorityClass defines the mapping from a priority class name to the priority | ||
// integer value. The value can be any valid integer. | ||
type PriorityClass struct { |
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.
Sorry that I'm behind on reviews... trying pretty frantically to catch up.
Why exactly do we create our own api group, and won't this need to be referenced by the main pod objects? B/c we don't typically cross groups, they are self contained.
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 tried to see if we can place the PriorityClass
in any of the existing API groups, but it didn't really fit nicely in any of them. So, I spoke with @thockin and the conclusion was to create a new API group for scheduling.
The priority class is not being referenced by pod objects. Pod API can have a PriorityClass name which is resolved to its integer value by an admission controller. The integer value is set in the pod object and all the components of the system will work with this integer value.
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.
That is wonky to me, what other api constructs split across groups like this?
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.
PV.Spec.StorageClassName and storage.k8s.io/StorageClass. I agree it's weird.
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.
Yes, storage class is similar to this as well. Why are the API groups should be self contained? What is the concern with referencing an API group from another one?
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's just a UX issue and consistency thing. Operators already have a tough time rationalizing the system. We should be sure to document this accordingly.
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.
There is no doubt about documenting it, but my understanding is that API groups are not exposed to operators. In other words, when one adds a PriorityClass, for example, she adds it the same way no matter which API group the PriorityClass is located in.
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.
my understanding is that API groups are not exposed to operators. In other words, when one adds a PriorityClass, for example, she adds it the same way no matter which API group the PriorityClass is located in.
That is definitely not correct. The API group is included in the object definition, and is required to fully-qualify the object kind.
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.
That is definitely not correct. The API group is included in the object definition, and is required to fully-qualify the object kind.
True. I guess you are referring to apiVersion
in object definition where API group is mentioned.
30c9f6c
to
036f93d
Compare
Add PriorityClass to pkg/registry Add PriorityClass to pkg/master/master.go Add PriorityClass to import_know_versions.go Update linted packages minor fix
ping @smarterclayton |
/approve |
/lgtm As well |
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: bsalamat, davidopp, gyliu513, justinsb, smarterclayton No associated issue. Update pull-request body to add a reference to an issue, or get approval with The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these OWNERS Files:
You can indicate your approval by writing |
Automatic merge from submit-queue |
What this PR does / why we need it: This PR is a part of a series of PRs to add pod priority to Kubernetes. This PR adds a new API group called "scheduling" with a new API object called "PriorityClass". PriorityClass maps the string value of priority to its integer value.
Which issue this PR fixes (optional, in
fixes #<issue number>(, fixes #<issue_number>, ...)
format, will close that issue when PR gets merged): fixes #Special notes for your reviewer: Given the size of this PR, I will add the admission controller for the PriorityClass in a separate PR.
Release note:
ref/ #47604
ref/ #48646