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

Apiserver flowcontrol api models #83671

Merged
merged 5 commits into from Nov 2, 2019

Conversation

yue9944882
Copy link
Member

NONE

/sig api-machinery
/kind feature

@k8s-ci-robot k8s-ci-robot added release-note-none Denotes a PR that doesn't merit a release note. do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. kind/feature Categorizes issue or PR as related to a new feature. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. needs-priority Indicates a PR lacks a `priority/foo` label and requires one. labels Oct 9, 2019
@k8s-ci-robot k8s-ci-robot added kind/api-change Categorizes issue or PR as related to adding, removing, or otherwise changing an API do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. labels Oct 9, 2019
@yue9944882
Copy link
Member Author

/hold cancel

@k8s-ci-robot k8s-ci-robot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Oct 9, 2019
Subjects []Subject `json:"subjects,omitempty" protobuf:"bytes,1,opt,name=subjects"`
// `rule` is the target verb, resource or the subresource the rule cares about. APIGroups, Resources, etc.
// Required.
Rule PolicyRule `json:"rule" protobuf:"bytes,2,opt,name=rule"`
Copy link
Contributor

Choose a reason for hiding this comment

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

in RBAC we chose to use a slice of these because you want to make sure the group and resource tuple expansions are correct. You don't want to match deployments.rbac.authorization.k8s.io for instance.

Copy link
Member

Choose a reason for hiding this comment

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

We are keeping group and resource together, they are both in PolicyRule (copied from rbac).
What is different in this API is how rules are associated with subjects. In this API it is this struct (PolicyRuleWithSubjects) that does that binding. Where rbac has a slice of PolicyRule, this API has a slice of PolicyRuleWithSubjects.

Also, the field tag here is inconsistent between json and protobuf regarding optionality.

Copy link
Contributor

Choose a reason for hiding this comment

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

That structure will require that subjects be defined multiple times to be able to grant access to resources in different groups. That is overly onerous.

// Rules can either apply to API resources (such as "pods" or "secrets") or non-resource URL paths (such as "/api"), but not both.
// NonResourceAll represents all non-resource urls.
// +optional
NonResourceURLs []string `json:"nonResourceURLs,omitempty" protobuf:"bytes,6,rep,name=nonResourceURLs"`
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this indicates we should have a union type for representing the rule. Back when I first wrote these, we hadn't formalized best practices.

Copy link
Member

Choose a reason for hiding this comment

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

And if we do not make that change then my comment on Resources applies here too.

Copy link
Member

Choose a reason for hiding this comment

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

The comment asserts more flexible patterns than the code implements.
The field tag does not say this is optional in protobuf.

// `queues` is a number of queues that belong to a non-exempt PriorityLevelConfiguration object. The queues exist
// independently at each apiserver. The value must be positive for a non-exempt priority level and setting it to 1
// disables shufflesharding and makes the distinguisher method irrelevant.
// TODO: sugguest a default or a way of deciding on a value.
Copy link
Contributor

Choose a reason for hiding this comment

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

You must describe what happens if this is left at zero. What is a "good" value? People don't understand what this means, but my memory is that choosing 1 defeats the purpose of doing this.

Copy link
Member

Choose a reason for hiding this comment

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

@deads2k : You raise multiple points.

  1. "what happens if this is left at zero". I do not understand why you raise this question. The comment says "The value must be positive for a non-exempt priority level". Isn't it normally implied that when a constraint is stated in a comment, it is checked in validation?

  2. "What is a "good" value?" Do you mean what is a good default value (still thinking about the possiblity that this field can be omitted)? Or are you saying this comment should give the user guidance on how to choose a value for this field? If the former then this is moot since the field is not optional. If the latter then this makes some sense to me, but the question of guidance is not unique to this field and not even something that neatly divides among fields. The guidance we can give is the design discussion we have been having, and it is not small enough and final enough to put in an API file. I think we need to give guidance in the user-facing documentation and rely on people to look there. I think we have to settle for making the API define precisely what each field means.

  3. "People don't understand what this means, but my memory is that choosing 1 defeats the purpose of doing this". No, a value of 1 does not defeat the purpose of queuing or having a priority level, it merely says that everything of this priority level goes in the same queue. The comment already makes related points: "setting it to 1 disables shufflesharding and makes the distinguisher method irrelevant", relying on the reader to figure out that a value of 1 means one queue for the priority level. I do not understand what is difficult about that. Would the following rewording help?

Setting this field to 1 means that all requests of this priority level go in the same queue,
and this means there is no shuffle-sharding and the flow distinguisher method is moot.

Copy link
Contributor

Choose a reason for hiding this comment

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

It's optional in your spec here, which means zero is allowed and you have to decide how to interpret it.

I don't think that a queue size of one by default is a good value.

Queues int32 `json:"queues,omitempty" protobuf:"varint,2,opt,name=queues"`
// `handSize` is a small positive number for applying shuffle sharding. When a request arrives at an apiserver the
// request flow identifier’s string pair is hashed and the hash value is used to shuffle the queue indices and deal
// a hand of the size specified here. If empty, the hand size will the be set to 1.
Copy link
Contributor

Choose a reason for hiding this comment

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

With hand size one, don't I defeat the purpose of the shuffle? It seems like you'd want a percentage of the queues.

Copy link
Member

Choose a reason for hiding this comment

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

Yes, a hand size of one means there is no shuffle sharding. I think it is a poor default value. In fact, I think there is no good default value. Have a look at #76846 (comment) and propose a specific default value or formula for computing one, if you think there is a good way to compute a default value.

@yue9944882 yue9944882 force-pushed the flow-control-api-model branch 3 times, most recently from 3cfbe13 to 4118bc8 Compare October 25, 2019 16:02
Copy link
Member

@MikeSpreitzer MikeSpreitzer left a comment

Choose a reason for hiding this comment

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

Some comments in-line.

// +listType=associative
// +listMapKey=type
// +optional
Conditions []FlowSchemaCondition `json:"conditions,omitempty" protobuf:"bytes,1,rep,name=conditions"`
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't there be list metadata in the field tag too?

Copy link
Member Author

Choose a reason for hiding this comment

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

can you elaborate what you mean by "list metadata"?

Copy link
Member

Choose a reason for hiding this comment

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

If you look at Pods, for example, you see stuff like this:

type PodSpec struct {
	// List of volumes that can be mounted by containers belonging to the pod.
	// More info: https://kubernetes.io/docs/concepts/storage/volumes
	// +optional
	// +patchMergeKey=name
	// +patchStrategy=merge,retainKeys
	Volumes []Volume `json:"volumes,omitempty" patchStrategy:"merge,retainKeys" patchMergeKey:"name" protobuf:"bytes,1,rep,name=volumes"`
...

(1) the comments use a different convention than we use, I do not understand what's up with that.

(2) the field tags include some of the same information as the comments about how the list is to be interpreted.

Copy link
Member

Choose a reason for hiding this comment

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

for _, msg := range apimachineryvalidation.ValidateNamespaceName(subject.Namespace, false) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("namespace"), subject.Namespace, msg))
}
} else {
Copy link
Member

Choose a reason for hiding this comment

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

It could be more uniform: test len(...) == 0 for both fields, or test len(...) > 0 for both fields. Also, I see the error produced in the zero length case is a little different.

}

// ValidateFlowSchemaNonResourcePolicyRule validates non-resource policy-rule in the flow-schema.
func ValidateFlowSchemaNonResourcePolicyRule(rule *flowcontrol.NonResourcePolicyRule, fldPath *field.Path) field.ErrorList {
Copy link
Member

Choose a reason for hiding this comment

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

Are there difficult issues in enforcing the comments?

We can leave some non-interface-changing work for later PRs, but I think we will not be done until the comments match the validation logic and the handling by the implementation.

pkg/apis/flowcontrol/validation/validation.go Outdated Show resolved Hide resolved
@yue9944882 yue9944882 force-pushed the flow-control-api-model branch 4 times, most recently from 8f4967b to a736b66 Compare October 28, 2019 16:23
allErrs = append(allErrs, field.NotSupported(fldPath.Child("distinguisherMethod").Child("type"), spec.DistinguisherMethod, supportedDistinguisherMethods.List()))
}
}
if len(spec.PriorityLevelConfiguration.Name) > 0 {
Copy link
Member

Choose a reason for hiding this comment

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

Don't we have to check for spec.PriorityLevelConfiguration != nil before dereferencing it?

Copy link
Member Author

Choose a reason for hiding this comment

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

the field PriorityLevelConfiguration is a composed struct instead of a pointer. there wont be nil panic here.

Copy link
Member

Choose a reason for hiding this comment

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

Oh, right!

versioned

external

external

external

external
rule list

rule

rule 2
internal

internal

internal

internal

internal
@yue9944882 yue9944882 force-pushed the flow-control-api-model branch 2 times, most recently from d8a9bbb to 4613941 Compare October 29, 2019 04:44
string(flowcontrol.FlowDistinguisherMethodByUserType),
)

var priorityLevelConfigurationQueuingMaxQueues int32 = 10 * 1000 * 1000 // 10^7
Copy link
Member

Choose a reason for hiding this comment

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

I suggest a comment along the lines of

// priorityLevelConfigurationQueuingMaxQueues is a limit that we impose
// so that shufflesharding.RequiredEntropyBits does not suffer overflow.
// The value here is the largest power of 10 that does this.

validation test

validation test

validation

adding validation for fs/pl status

validation

validation

validation

replace < with <=

validation test
generated

generated

generated

rule

generated

generated
Copy link
Member

@MikeSpreitzer MikeSpreitzer left a comment

Choose a reason for hiding this comment

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

I think this is good enough to merge and unblock dependent work.
There are a few things remaining to clean up.

  • list metadata in field tags in the external types
  • English language nits in the comments
  • Full validation of non-resource URL patterns

/LGTM

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Oct 29, 2019
@lavalamp
Copy link
Member

lavalamp commented Nov 1, 2019

Spoke offline, both @deads2k and I agree the best way forward is to merge this and take some followups.

/approve

@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: lavalamp, yue9944882

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Nov 1, 2019
@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to fejta).

Review the full test history for this PR.

Silence the bot with an /lgtm cancel or /hold comment for consistent failures.

@yue9944882
Copy link
Member Author

/retest

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. area/apiserver area/code-generation area/test cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. kind/api-change Categorizes issue or PR as related to adding, removing, or otherwise changing an API kind/feature Categorizes issue or PR as related to a new feature. lgtm "Looks good to me", indicates that a PR is ready to be merged. needs-priority Indicates a PR lacks a `priority/foo` label and requires one. release-note-none Denotes a PR that doesn't merit a release note. sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. sig/testing Categorizes an issue or PR as relevant to SIG Testing. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants