diff --git a/api/aperture/common/labelmatcher/v1/labelmatcher.proto b/api/aperture/common/labelmatcher/v1/labelmatcher.proto index 9c573c7139..b8b376bb64 100644 --- a/api/aperture/common/labelmatcher/v1/labelmatcher.proto +++ b/api/aperture/common/labelmatcher/v1/labelmatcher.proto @@ -4,7 +4,9 @@ package aperture.common.labelmatcher.v1; import "protoc-gen-openapiv2/options/annotations.proto"; -// Allows to define rules whether a map of labels should be considered a match or not +// Allows to define rules whether a map of +// [labels](/concepts/flow-control/label/label.md) +// should be considered a match or not // // It provides three ways to define requirements: // - matchLabels diff --git a/api/aperture/common/selector/v1/selector.proto b/api/aperture/common/selector/v1/selector.proto index e7cf3b906b..ab95fbd301 100644 --- a/api/aperture/common/selector/v1/selector.proto +++ b/api/aperture/common/selector/v1/selector.proto @@ -52,24 +52,20 @@ message Selector { } }]; // @gotags: validate:"required" - // Label matcher allows to add _additional_ condition on labels that must - // also be satisfied (in addition to service+control point matching) + // Label matcher allows to add _additional_ condition on + // [flow labels](/concepts/flow-control/label/label.md) + // must also be satisfied (in addition to service+control point matching) // - // This matcher allows to match on flow labels and request labels. - // (Note: For classification we can only match flow labels that were created at - // some **previous** control point). + // :::note + // [Classifiers](#-v1classifier) _can_ use flow labels created by some other + // classifier, but only if they were created at some previous control point + // (and propagated in baggage). // - // Flow labels are available with the same label key as defined in - // classification rule. - // - // Request labels are always prefixed with `request_`. Available request - // labels are `id` (available as `request_id`), `method`, `path`, `host`, - // `scheme`, `size`, `protocol` (mapped from fields of - // [HttpRequest](https://github.com/envoyproxy/envoy/blob/637a92a56e2739b5f78441c337171968f18b46ee/api/envoy/service/auth/v3/attribute_context.proto#L102)). - // Also, (non-pseudo) headers are available as `request_header_`, where - // `` is a headername normalised to lowercase, eg. `request_header_user-agent`. - // - // Note: Request headers are only available for `traffic` control points. + // This limitation doesn't apply to selectors of other entities, like + // FluxMeters or actuators. It's valid to create a flow label on a control + // point using classifier, and immediately use it for matching on the same + // control point. + // ::: common.labelmatcher.v1.LabelMatcher label_matcher = 4; } diff --git a/api/aperture/policy/language/v1/classifier.proto b/api/aperture/policy/language/v1/classifier.proto index 770b1c6621..b4f6b32218 100644 --- a/api/aperture/policy/language/v1/classifier.proto +++ b/api/aperture/policy/language/v1/classifier.proto @@ -8,6 +8,10 @@ import "protoc-gen-openapiv2/options/annotations.proto"; // Set of classification rules sharing a common selector // +// :::info +// See also [Classifier overview](/concepts/flow-control/label/classifier.md). +// ::: +// // Example: // ```yaml // selector: @@ -23,7 +27,9 @@ message Classifier { // Defines where to apply the flow classification rule. common.selector.v1.Selector selector = 1; - // A map of {key, value} pairs mapping from flow label names to rules that define how to extract and propagate them. + // A map of {key, value} pairs mapping from + // [flow label](/concepts/flow-control/label/label.md) keys to rules that define + // how to extract and propagate flow labels with that key. map rules = 2; } @@ -87,7 +93,8 @@ message Rule { } // Decides if the created label should be applied to the whole request chain - // (propagated in baggage) (default=true). + // (propagated in [baggage](/concepts/flow-control/label/label.md#baggage)) + // (default=true). google.protobuf.BoolValue propagate = 3; // Decides if the created flow label should be hidden from the telemetry. @@ -104,7 +111,7 @@ message Rule { bool hidden = 4; } -// Defines a high-level way to specify how to extract a flow label given http request metadata, without a need to write rego code +// Defines a high-level way to specify how to extract a flow label value given http request metadata, without a need to write rego code // // There are multiple variants of extractor, specify exactly one. message Extractor { diff --git a/api/aperture/policy/language/v1/policy.proto b/api/aperture/policy/language/v1/policy.proto index 134e5caf0a..6ad0459af3 100644 --- a/api/aperture/policy/language/v1/policy.proto +++ b/api/aperture/policy/language/v1/policy.proto @@ -608,9 +608,10 @@ message RateLimiter { // Specifies which label the ratelimiter should be keyed by. // - // Rate limiting is done independently for each value of the label with given - // key. Eg., to give each user a separate limit, assuming you have a _user_ - // flow label set up, set `label_key: "user"`. + // Rate limiting is done independently for each value of the + // [label](/concepts/flow-control/label/label.md) with given key. + // Eg., to give each user a separate limit, assuming you have a _user_ flow + // label set up, set `label_key: "user"`. // // TODO make it possible for this field to be optional – to achieve global ratelimit. string label_key = 4 [(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { @@ -696,19 +697,19 @@ message Scheduler { } }]; // @gotags: default:"1" - // Fairness key is a label key that can be used to provide fairness within a workload - // - // Any label that could be used in label matcher can be used here. Eg. if + // Fairness key is a label key that can be used to provide fairness within a workload. + // Any [flow label](/concepts/flow-control/label/label.md) can be used here. Eg. if // you have a classifier that sets `user` flow label, you might want to set // `fairness_key = "user"`. string fairness_key = 3; } message WorkloadAndLabelMatcher { - // Workload associated with requests matching the label matcher. + // Workload associated with flows matching the label matcher. Workload workload = 1; - // Label Matcher to select a Workload. + // Label Matcher to select a Workload based on + // [flow labels](/concepts/flow-control/label/label.md). common.labelmatcher.v1.LabelMatcher label_matcher = 2; } @@ -718,7 +719,7 @@ message Scheduler { // // :::info // **Accepted tokens** are tokens associated with - // [flows](/concepts/flow-control/flow-control.md#what-is-a-flow) that were accepted by + // [flows](/concepts/flow-control/flow-control.md#flow) that were accepted by // this scheduler. Number of tokens for a flow is determined by a // [workload](#-schedulerworkload) that the flow was assigned to (either // via `auto_tokens` or explicitly by `Workload.tokens`). @@ -741,7 +742,7 @@ message Scheduler { // List of workloads to be used in scheduler. // - // Categorizing [flows](/concepts/flow-control/flow-control.md#what-is-a-flow) into workloads + // Categorizing [flows](/concepts/flow-control/flow-control.md#flow) into workloads // allows for load-shedding to be "smarter" than just "randomly deny 50% of // requests". There are two aspects of this "smartness": // * Scheduler can more precisely calculate concurrency if it understands diff --git a/api/gen/openapiv2/aperture.swagger.yaml b/api/gen/openapiv2/aperture.swagger.yaml index c601d69437..0156441850 100644 --- a/api/gen/openapiv2/aperture.swagger.yaml +++ b/api/gen/openapiv2/aperture.swagger.yaml @@ -232,10 +232,10 @@ definitions: fairness_key: type: string description: |- - Any label that could be used in label matcher can be used here. Eg. if + Fairness key is a label key that can be used to provide fairness within a workload. + Any [flow label](/concepts/flow-control/label/label.md) can be used here. Eg. if you have a classifier that sets `user` flow label, you might want to set `fairness_key = "user"`. - title: Fairness key is a label key that can be used to provide fairness within a workload priority: type: integer format: int64 @@ -257,10 +257,12 @@ definitions: properties: label_matcher: $ref: '#/definitions/v1LabelMatcher' - description: Label Matcher to select a Workload. + description: |- + Label Matcher to select a Workload based on + [flow labels](/concepts/flow-control/label/label.md). workload: $ref: '#/definitions/SchedulerWorkload' - description: Workload associated with requests matching the label matcher. + description: Workload associated with flows matching the label matcher. apertureflowcontrolv1FluxMeter: type: object properties: @@ -318,9 +320,10 @@ definitions: description: |- Specifies which label the ratelimiter should be keyed by. - Rate limiting is done independently for each value of the label with given - key. Eg., to give each user a separate limit, assuming you have a _user_ - flow label set up, set `label_key: "user"`. + Rate limiting is done independently for each value of the + [label](/concepts/flow-control/label/label.md) with given key. + Eg., to give each user a separate limit, assuming you have a _user_ flow + label set up, set `label_key: "user"`. TODO make it possible for this field to be optional – to achieve global ratelimit. x-go-validate: required @@ -654,11 +657,18 @@ definitions: type: object additionalProperties: $ref: '#/definitions/v1Rule' - description: A map of {key, value} pairs mapping from flow label names to rules that define how to extract and propagate them. + description: |- + A map of {key, value} pairs mapping from + [flow label](/concepts/flow-control/label/label.md) keys to rules that define + how to extract and propagate flow labels with that key. selector: $ref: '#/definitions/v1Selector' description: Defines where to apply the flow classification rule. description: |- + :::info + See also [Classifier overview](/concepts/flow-control/label/classifier.md). + ::: + Example: ```yaml selector: @@ -1010,7 +1020,7 @@ definitions: $ref: '#/definitions/v1PathTemplateMatcher' description: Match HTTP Path to given path templates. description: There are multiple variants of extractor, specify exactly one. - title: Defines a high-level way to specify how to extract a flow label given http request metadata, without a need to write rego code + title: Defines a high-level way to specify how to extract a flow label value given http request metadata, without a need to write rego code v1Extrapolator: type: object properties: @@ -1251,7 +1261,10 @@ definitions: If multiple requirements are set, they are all ANDed. An empty label matcher always matches. - title: Allows to define rules whether a map of labels should be considered a match or not + title: |- + Allows to define rules whether a map of + [labels](/concepts/flow-control/label/label.md) + should be considered a match or not v1LimiterDecision: type: object properties: @@ -1603,7 +1616,8 @@ definitions: type: boolean description: |- Decides if the created label should be applied to the whole request chain - (propagated in baggage) (default=true). + (propagated in [baggage](/concepts/flow-control/label/label.md#baggage)) + (default=true). rego: $ref: '#/definitions/RuleRego' description: Rego module to extract a value from the rego module. @@ -1700,7 +1714,7 @@ definitions: description: |- List of workloads to be used in scheduler. - Categorizing [flows](/concepts/flow-control/flow-control.md#what-is-a-flow) into workloads + Categorizing [flows](/concepts/flow-control/flow-control.md#flow) into workloads allows for load-shedding to be "smarter" than just "randomly deny 50% of requests". There are two aspects of this "smartness": * Scheduler can more precisely calculate concurrency if it understands @@ -1736,7 +1750,7 @@ definitions: :::info **Accepted tokens** are tokens associated with - [flows](/concepts/flow-control/flow-control.md#what-is-a-flow) that were accepted by + [flows](/concepts/flow-control/flow-control.md#flow) that were accepted by this scheduler. Number of tokens for a flow is determined by a [workload](#-schedulerworkload) that the flow was assigned to (either via `auto_tokens` or explicitly by `Workload.tokens`). @@ -1764,24 +1778,20 @@ definitions: label_matcher: $ref: '#/definitions/v1LabelMatcher' description: |- - This matcher allows to match on flow labels and request labels. - (Note: For classification we can only match flow labels that were created at - some **previous** control point). - - Flow labels are available with the same label key as defined in - classification rule. - - Request labels are always prefixed with `request_`. Available request - labels are `id` (available as `request_id`), `method`, `path`, `host`, - `scheme`, `size`, `protocol` (mapped from fields of - [HttpRequest](https://github.com/envoyproxy/envoy/blob/637a92a56e2739b5f78441c337171968f18b46ee/api/envoy/service/auth/v3/attribute_context.proto#L102)). - Also, (non-pseudo) headers are available as `request_header_`, where - `` is a headername normalised to lowercase, eg. `request_header_user-agent`. - - Note: Request headers are only available for `traffic` control points. + :::note + [Classifiers](#-v1classifier) _can_ use flow labels created by some other + classifier, but only if they were created at some previous control point + (and propagated in baggage). + + This limitation doesn't apply to selectors of other entities, like + FluxMeters or actuators. It's valid to create a flow label on a control + point using classifier, and immediately use it for matching on the same + control point. + ::: title: |- - Label matcher allows to add _additional_ condition on labels that must - also be satisfied (in addition to service+control point matching) + Label matcher allows to add _additional_ condition on + [flow labels](/concepts/flow-control/label/label.md) + must also be satisfied (in addition to service+control point matching) service: type: string description: |- diff --git a/api/gen/proto/go/aperture/common/labelmatcher/v1/labelmatcher.pb.go b/api/gen/proto/go/aperture/common/labelmatcher/v1/labelmatcher.pb.go index 76249bcd18..31c25cc8fc 100644 --- a/api/gen/proto/go/aperture/common/labelmatcher/v1/labelmatcher.pb.go +++ b/api/gen/proto/go/aperture/common/labelmatcher/v1/labelmatcher.pb.go @@ -21,7 +21,9 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -// Allows to define rules whether a map of labels should be considered a match or not +// Allows to define rules whether a map of +// [labels](/concepts/flow-control/label/label.md) +// should be considered a match or not // // It provides three ways to define requirements: // - matchLabels diff --git a/api/gen/proto/go/aperture/common/selector/v1/selector.pb.go b/api/gen/proto/go/aperture/common/selector/v1/selector.pb.go index 8ea6f83af0..1656b34c2b 100644 --- a/api/gen/proto/go/aperture/common/selector/v1/selector.pb.go +++ b/api/gen/proto/go/aperture/common/selector/v1/selector.pb.go @@ -56,24 +56,20 @@ type Selector struct { Service string `protobuf:"bytes,2,opt,name=service,proto3" json:"service,omitempty"` // Describes control point within the entity where the policy should apply to. ControlPoint *ControlPoint `protobuf:"bytes,3,opt,name=control_point,json=controlPoint,proto3" json:"control_point,omitempty" validate:"required"` // @gotags: validate:"required" - // Label matcher allows to add _additional_ condition on labels that must - // also be satisfied (in addition to service+control point matching) + // Label matcher allows to add _additional_ condition on + // [flow labels](/concepts/flow-control/label/label.md) + // must also be satisfied (in addition to service+control point matching) // - // This matcher allows to match on flow labels and request labels. - // (Note: For classification we can only match flow labels that were created at - // some **previous** control point). + // :::note + // [Classifiers](#-v1classifier) _can_ use flow labels created by some other + // classifier, but only if they were created at some previous control point + // (and propagated in baggage). // - // Flow labels are available with the same label key as defined in - // classification rule. - // - // Request labels are always prefixed with `request_`. Available request - // labels are `id` (available as `request_id`), `method`, `path`, `host`, - // `scheme`, `size`, `protocol` (mapped from fields of - // [HttpRequest](https://github.com/envoyproxy/envoy/blob/637a92a56e2739b5f78441c337171968f18b46ee/api/envoy/service/auth/v3/attribute_context.proto#L102)). - // Also, (non-pseudo) headers are available as `request_header_`, where - // `` is a headername normalised to lowercase, eg. `request_header_user-agent`. - // - // Note: Request headers are only available for `traffic` control points. + // This limitation doesn't apply to selectors of other entities, like + // FluxMeters or actuators. It's valid to create a flow label on a control + // point using classifier, and immediately use it for matching on the same + // control point. + // ::: LabelMatcher *v1.LabelMatcher `protobuf:"bytes,4,opt,name=label_matcher,json=labelMatcher,proto3" json:"label_matcher,omitempty"` } diff --git a/api/gen/proto/go/aperture/policy/language/v1/classifier.pb.go b/api/gen/proto/go/aperture/policy/language/v1/classifier.pb.go index 7d92c7d183..1fccd85728 100644 --- a/api/gen/proto/go/aperture/policy/language/v1/classifier.pb.go +++ b/api/gen/proto/go/aperture/policy/language/v1/classifier.pb.go @@ -25,6 +25,10 @@ const ( // Set of classification rules sharing a common selector // +// :::info +// See also [Classifier overview](/concepts/flow-control/label/classifier.md). +// ::: +// // Example: // ```yaml // selector: @@ -43,7 +47,9 @@ type Classifier struct { // Defines where to apply the flow classification rule. Selector *v1.Selector `protobuf:"bytes,1,opt,name=selector,proto3" json:"selector,omitempty"` - // A map of {key, value} pairs mapping from flow label names to rules that define how to extract and propagate them. + // A map of {key, value} pairs mapping from + // [flow label](/concepts/flow-control/label/label.md) keys to rules that define + // how to extract and propagate flow labels with that key. Rules map[string]*Rule `protobuf:"bytes,2,rep,name=rules,proto3" json:"rules,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } @@ -138,7 +144,8 @@ type Rule struct { // *Rule_Rego_ Source isRule_Source `protobuf_oneof:"source"` // Decides if the created label should be applied to the whole request chain - // (propagated in baggage) (default=true). + // (propagated in [baggage](/concepts/flow-control/label/label.md#baggage)) + // (default=true). Propagate *wrapperspb.BoolValue `protobuf:"bytes,3,opt,name=propagate,proto3" json:"propagate,omitempty"` // Decides if the created flow label should be hidden from the telemetry. // A hidden flow label is still accessible in policies and can be used as eg. @@ -239,7 +246,7 @@ func (*Rule_Extractor) isRule_Source() {} func (*Rule_Rego_) isRule_Source() {} -// Defines a high-level way to specify how to extract a flow label given http request metadata, without a need to write rego code +// Defines a high-level way to specify how to extract a flow label value given http request metadata, without a need to write rego code // // There are multiple variants of extractor, specify exactly one. type Extractor struct { diff --git a/api/gen/proto/go/aperture/policy/language/v1/policy.pb.go b/api/gen/proto/go/aperture/policy/language/v1/policy.pb.go index 7e9d5b357f..e69d18f505 100644 --- a/api/gen/proto/go/aperture/policy/language/v1/policy.pb.go +++ b/api/gen/proto/go/aperture/policy/language/v1/policy.pb.go @@ -1062,9 +1062,10 @@ type RateLimiter struct { LimitResetInterval *durationpb.Duration `protobuf:"bytes,3,opt,name=limit_reset_interval,json=limitResetInterval,proto3" json:"limit_reset_interval,omitempty" default:"60s"` // @gotags: default:"60s" // Specifies which label the ratelimiter should be keyed by. // - // Rate limiting is done independently for each value of the label with given - // key. Eg., to give each user a separate limit, assuming you have a _user_ - // flow label set up, set `label_key: "user"`. + // Rate limiting is done independently for each value of the + // [label](/concepts/flow-control/label/label.md) with given key. + // Eg., to give each user a separate limit, assuming you have a _user_ flow + // label set up, set `label_key: "user"`. // // TODO make it possible for this field to be optional – to achieve global ratelimit. LabelKey string `protobuf:"bytes,4,opt,name=label_key,json=labelKey,proto3" json:"label_key,omitempty" validate:"required"` // @gotags: validate:"required" @@ -1259,7 +1260,7 @@ type Scheduler struct { Selector *v1.Selector `protobuf:"bytes,2,opt,name=selector,proto3" json:"selector,omitempty"` // List of workloads to be used in scheduler. // - // Categorizing [flows](/concepts/flow-control/flow-control.md#what-is-a-flow) into workloads + // Categorizing [flows](/concepts/flow-control/flow-control.md#flow) into workloads // allows for load-shedding to be "smarter" than just "randomly deny 50% of // requests". There are two aspects of this "smartness": // * Scheduler can more precisely calculate concurrency if it understands @@ -2522,9 +2523,8 @@ type Scheduler_Workload struct { // Tokens determines the cost of admitting a single request the workload, which is typically defined as milliseconds of response latency. // This override is applicable only if `auto_tokens` is set to false. Tokens uint64 `protobuf:"varint,2,opt,name=tokens,proto3" json:"tokens,omitempty" default:"1"` // @gotags: default:"1" - // Fairness key is a label key that can be used to provide fairness within a workload - // - // Any label that could be used in label matcher can be used here. Eg. if + // Fairness key is a label key that can be used to provide fairness within a workload. + // Any [flow label](/concepts/flow-control/label/label.md) can be used here. Eg. if // you have a classifier that sets `user` flow label, you might want to set // `fairness_key = "user"`. FairnessKey string `protobuf:"bytes,3,opt,name=fairness_key,json=fairnessKey,proto3" json:"fairness_key,omitempty"` @@ -2588,9 +2588,10 @@ type Scheduler_WorkloadAndLabelMatcher struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // Workload associated with requests matching the label matcher. + // Workload associated with flows matching the label matcher. Workload *Scheduler_Workload `protobuf:"bytes,1,opt,name=workload,proto3" json:"workload,omitempty"` - // Label Matcher to select a Workload. + // Label Matcher to select a Workload based on + // [flow labels](/concepts/flow-control/label/label.md). LabelMatcher *v11.LabelMatcher `protobuf:"bytes,2,opt,name=label_matcher,json=labelMatcher,proto3" json:"label_matcher,omitempty"` } @@ -2650,7 +2651,7 @@ type Scheduler_Outs struct { // // :::info // **Accepted tokens** are tokens associated with - // [flows](/concepts/flow-control/flow-control.md#what-is-a-flow) that were accepted by + // [flows](/concepts/flow-control/flow-control.md#flow) that were accepted by // this scheduler. Number of tokens for a flow is determined by a // [workload](#-schedulerworkload) that the flow was assigned to (either // via `auto_tokens` or explicitly by `Workload.tokens`). diff --git a/docs/content/cloud/plugin.md b/docs/content/cloud/plugin.md index 32e703248b..81407cd082 100644 --- a/docs/content/cloud/plugin.md +++ b/docs/content/cloud/plugin.md @@ -53,3 +53,9 @@ For more details, see plugin configuration reference: - [Agent](/reference/configuration/agent#plugin-configuration) - [Controller](/reference/configuration/controller#plugin-configuration) + +## See also + +How various components interact with the plugin: + +- [Flow labels](/concepts/flow-control/label/label.md#plugin) diff --git a/docs/content/concepts/flow-control/flow-control.md b/docs/content/concepts/flow-control/flow-control.md index 25e773c8aa..b3561422dd 100644 --- a/docs/content/concepts/flow-control/flow-control.md +++ b/docs/content/concepts/flow-control/flow-control.md @@ -14,7 +14,7 @@ Reliable operations at web-scale are impossible without effective flow control. Aperture provides sophisticated flow control capabilities by locating agents next the services (sidecar). -## What is a flow? +## What is a flow? {#flow} A flow is the fundamental unit of work from the perspective of an Aperture Agent. It could be an API call, a feature, or even a database query. A flow in diff --git a/docs/content/concepts/flow-control/fluxmeter.md b/docs/content/concepts/flow-control/fluxmeter.md new file mode 100644 index 0000000000..91e9d63254 --- /dev/null +++ b/docs/content/concepts/flow-control/fluxmeter.md @@ -0,0 +1,4 @@ +--- +title: FluxMeter +position: 3 +--- diff --git a/docs/content/concepts/flow-control/label/classifier.md b/docs/content/concepts/flow-control/label/classifier.md new file mode 100644 index 0000000000..62af38f0b2 --- /dev/null +++ b/docs/content/concepts/flow-control/label/classifier.md @@ -0,0 +1,7 @@ +--- +title: Flow Classifier +--- + +:::info +See also [Classifier reference](/reference/configuration/policies.md#-v1classifier) +::: diff --git a/docs/content/concepts/flow-control/label/label.md b/docs/content/concepts/flow-control/label/label.md new file mode 100644 index 0000000000..e39f310a90 --- /dev/null +++ b/docs/content/concepts/flow-control/label/label.md @@ -0,0 +1,98 @@ +--- +title: Flow Label +sidebar_position: 0.75 +--- + +Every [flow][flow] is annotated with a set of **flow labels**. +Each flow label is a key:value pair. +Eg. if a flow is annotated with `user_tier:gold` label, `user_tier` is a label key +and `gold` is a label value. + +Flow labels are used used in different ways in Aperture: + +- [Flow selector][selector] can select flows based on flow labels + (thus flow labels can be used to narrow the scope + of [_actuators_][actuators] or [_FluxMeters_][fluxmeter]) +- Flow labels are used to classify a flow to [_workload_][workload]. +- Fairness within a scheduler's workload and [rate-limiting][ratelimiter] keys + are also based on flow labels. + +## Sources + +Flows are annotated with flow labels based on four sources: request labels, baggage, flow classifiers and explicit labels from aperture library call. + +### Request labels + +For each _traffic_ control point (where flows are http or grpc requests), some +basic metadata is available as _request labels_. +These are `request_id` , `request_method`, `request_path`, `request_host`, +`request_scheme`, `request_size`, `request_protocol` (mapped from fields of +[HttpRequest][authz-request-http]). +Also, (non-pseudo) headers are available as `request_header_`, where +`` is a headername normalised to lowercase, eg. `request_header_user-agent`. + +### Baggage + +Baggage propagation is a powerful concept that allows to attach metadata to a +whole request chain (or in other words – to a whole [trace][traces]). +If you already have baggage propagation configured in your system, +you can access the baggage as flow labels. +This is supported on both _traffic_ and _feature_ control points. + +- _traffic_: Baggage is pulled from the [_baggage_][baggage] header, +- _feature_: Baggage is automatically pulled from context on + each `Check()` call. This is assuming you're using OpenTelemetry library to + manage the baggage. + +Baggage members are mapped to flow labels 1:1 – +keys become label keys, values become label values (properties are ignored). + +Read more about baggage propagation on: +[Baggage | OpenTelemetry](https://opentelemetry.io/docs/concepts/signals/baggage/). + +### Flow classifiers + +When the labels you need are not already present in baggage, nor as request +labels, you can create a [classifier](classifier) to inject new labels into the +system. Since the classifier also injects the label into baggage by default, +this means you can set extract the label in different place that it's consumed +(assuming you have the baggage propagation configured +throughout your system). + +### Aperture library + +Aperture library, in addition to automatically pulling baggage from context, +also takes explicit `labels` map in the `Check()` call. + +## Interaction with FluxNinja Cloud plugin {#plugin} + +All the flow labels except the request labels are used as labels of flow +events. These events are rolled up and sent to the analytics database in the +cloud. This allows: + +- for the flow labels to be used as filters, +- to see analytics for each flow label, eg. distribution of its values. + +:::note +For classifier-created labels, you can disable this behaviour by setting +`propagate: false` +in [the classification rule](/reference/configuration/policies.md#-v1rule). +::: + +:::danger +This means that by default the already-present-in-baggage labels are sent to +the cloud. + +TODO perhaps we should invert the default? +::: + +[flow]: /concepts/flow-control/flow-control.md#flow +[selector]: /concepts/flow-control/selector.md +[actuators]: /concepts/flow-control/actuators/actuators.md +[scheduler]: /concepts/flow-control/actuators/scheduler.md +[workload]: /concepts/flow-control/actuators/scheduler.md#workload +[ratelimiter]: /concepts/flow-control/actuators/rate-limiter.md +[fluxmeter]: /concepts/flow-control/fluxmeter.md +[authz-request-http]: https://github.com/envoyproxy/envoy/blob/637a92a56e2739b5f78441c337171968f18b46ee/api/envoy/service/auth/v3/attribute_context.proto#L102 +[baggage]: https://www.w3.org/TR/baggage/#baggage-http-header-format +[traces]: https://opentelemetry.io/docs/concepts/observability-primer/#distributed-traces diff --git a/docs/content/concepts/flow-control/selector.md b/docs/content/concepts/flow-control/selector.md index 57fc973fa7..7e8bf23ad3 100644 --- a/docs/content/concepts/flow-control/selector.md +++ b/docs/content/concepts/flow-control/selector.md @@ -1,5 +1,5 @@ --- -title: Selector +title: Flow Selector sidebar_position: 1 keywords: - flows @@ -8,14 +8,16 @@ keywords: - labels --- -# Selector +:::info +See also [Selector reference](/reference/configuration/policies#-v1selector) +::: Flow observability and control components are instantiated on Aperture Agents and select flows based on scoping rules defined in the Selectors. A Selector consists of following fields: -## Agent Group +### Agent Group Agent Group is a flexible label that defines a collection of agents that operate as peers. For example, an Agent Group can be a Kubernetes cluster name in case @@ -28,7 +30,7 @@ Agents within an Agent Group form a peer-to-peer network. Agents synchronize fine-grained state such as per label global counters that are used for rate limiting purposes. -## Service +### Service Service in Aperture is similar to services tracked in Kubernetes, Consul etc. A Service is a collection of entities delivering a common functionality, such as, @@ -45,12 +47,12 @@ In addition, Aperture also has a concept of a `*` catch-all service. When the Selector contains a catch-all service, it matches for all discovered entities within a Agent Group. -## Control Point +### Control Point A policy or rule is configured for a given control point within a service. Control Point is either a library feature name or one of ingress/egress traffic points. -## Label Matcher +### Label Matcher Label Matcher is part of the classifier on whether a map of labels should be considered a match or not. If multiple requirements are set, they are all ANDed. An empty label diff --git a/docs/content/concepts/flow-control/service.md b/docs/content/concepts/flow-control/service.md new file mode 100644 index 0000000000..94938b1f1d --- /dev/null +++ b/docs/content/concepts/flow-control/service.md @@ -0,0 +1,9 @@ +--- +title: Service +sidebar_position: 0 +--- + +TODO extract info about services and agent-groups from [Selector](selector.md) +page, as these concepts are used a lot outside of context of selector. + +## Agent Group diff --git a/docs/gen/policies/gen.yaml b/docs/gen/policies/gen.yaml index 10ae7563fe..e8a3da8ebd 100644 --- a/docs/gen/policies/gen.yaml +++ b/docs/gen/policies/gen.yaml @@ -92,12 +92,11 @@ definitions: properties: fairness_key: description: |- - Any label that could be used in label matcher can be used here. Eg. if + Fairness key is a label key that can be used to provide fairness within a workload. + Any [flow label](/concepts/flow-control/label/label.md) can be used here. Eg. if you have a classifier that sets `user` flow label, you might want to set `fairness_key = "user"`. type: string - title: Fairness key is a label key that can be used to provide fairness within - a workload x-order: 0 priority: description: |- @@ -120,11 +119,13 @@ definitions: type: object properties: label_matcher: - description: Label Matcher to select a Workload. + description: |- + Label Matcher to select a Workload based on + [flow labels](/concepts/flow-control/label/label.md). x-order: 0 $ref: '#/definitions/v1LabelMatcher' workload: - description: Workload associated with requests matching the label matcher. + description: Workload associated with flows matching the label matcher. x-order: 1 $ref: '#/definitions/SchedulerWorkload' languagev1ConcurrencyLimiter: @@ -177,9 +178,10 @@ definitions: description: |- Specifies which label the ratelimiter should be keyed by. - Rate limiting is done independently for each value of the label with given - key. Eg., to give each user a separate limit, assuming you have a _user_ - flow label set up, set `label_key: "user"`. + Rate limiting is done independently for each value of the + [label](/concepts/flow-control/label/label.md) with given key. + Eg., to give each user a separate limit, assuming you have a _user_ flow + label set up, set `label_key: "user"`. TODO make it possible for this field to be optional – to achieve global ratelimit. type: string @@ -341,6 +343,10 @@ definitions: x-order: 1 v1Classifier: description: |- + :::info + See also [Classifier overview](/concepts/flow-control/label/classifier.md). + ::: + Example: ```yaml selector: @@ -356,8 +362,10 @@ definitions: title: Set of classification rules sharing a common selector properties: rules: - description: A map of {key, value} pairs mapping from flow label names to - rules that define how to extract and propagate them. + description: |- + A map of {key, value} pairs mapping from + [flow label](/concepts/flow-control/label/label.md) keys to rules that define + how to extract and propagate flow labels with that key. type: object additionalProperties: $ref: '#/definitions/v1Rule' @@ -700,8 +708,8 @@ definitions: v1Extractor: description: There are multiple variants of extractor, specify exactly one. type: object - title: Defines a high-level way to specify how to extract a flow label given http - request metadata, without a need to write rego code + title: Defines a high-level way to specify how to extract a flow label value given + http request metadata, without a need to write rego code properties: address: description: Display an address as a single string - `:`. @@ -970,8 +978,10 @@ definitions: If multiple requirements are set, they are all ANDed. An empty label matcher always matches. type: object - title: Allows to define rules whether a map of labels should be considered a match - or not + title: |- + Allows to define rules whether a map of + [labels](/concepts/flow-control/label/label.md) + should be considered a match or not properties: expression: description: An arbitrary expression to be evaluated on the labels. @@ -1324,7 +1334,8 @@ definitions: propagate: description: |- Decides if the created label should be applied to the whole request chain - (propagated in baggage) (default=true). + (propagated in [baggage](/concepts/flow-control/label/label.md#baggage)) + (default=true). type: boolean x-order: 2 rego: @@ -1403,7 +1414,7 @@ definitions: description: |- List of workloads to be used in scheduler. - Categorizing [flows](/concepts/flow-control/flow-control.md#what-is-a-flow) into workloads + Categorizing [flows](/concepts/flow-control/flow-control.md#flow) into workloads allows for load-shedding to be "smarter" than just "randomly deny 50% of requests". There are two aspects of this "smartness": * Scheduler can more precisely calculate concurrency if it understands @@ -1435,7 +1446,7 @@ definitions: :::info **Accepted tokens** are tokens associated with - [flows](/concepts/flow-control/flow-control.md#what-is-a-flow) that were accepted by + [flows](/concepts/flow-control/flow-control.md#flow) that were accepted by this scheduler. Number of tokens for a flow is determined by a [workload](#-schedulerworkload) that the flow was assigned to (either via `auto_tokens` or explicitly by `Workload.tokens`). @@ -1487,24 +1498,20 @@ definitions: $ref: '#/definitions/v1ControlPoint' label_matcher: description: |- - This matcher allows to match on flow labels and request labels. - (Note: For classification we can only match flow labels that were created at - some **previous** control point). - - Flow labels are available with the same label key as defined in - classification rule. - - Request labels are always prefixed with `request_`. Available request - labels are `id` (available as `request_id`), `method`, `path`, `host`, - `scheme`, `size`, `protocol` (mapped from fields of - [HttpRequest](https://github.com/envoyproxy/envoy/blob/637a92a56e2739b5f78441c337171968f18b46ee/api/envoy/service/auth/v3/attribute_context.proto#L102)). - Also, (non-pseudo) headers are available as `request_header_`, where - `` is a headername normalised to lowercase, eg. `request_header_user-agent`. - - Note: Request headers are only available for `traffic` control points. + :::note + [Classifiers](#-v1classifier) _can_ use flow labels created by some other + classifier, but only if they were created at some previous control point + (and propagated in baggage). + + This limitation doesn't apply to selectors of other entities, like + FluxMeters or actuators. It's valid to create a flow label on a control + point using classifier, and immediately use it for matching on the same + control point. + ::: title: |- - Label matcher allows to add _additional_ condition on labels that must - also be satisfied (in addition to service+control point matching) + Label matcher allows to add _additional_ condition on + [flow labels](/concepts/flow-control/label/label.md) + must also be satisfied (in addition to service+control point matching) x-order: 2 $ref: '#/definitions/v1LabelMatcher' service: diff --git a/docs/gen/policies/policy.md b/docs/gen/policies/policy.md index efbcca1739..cb0b764ef6 100644 --- a/docs/gen/policies/policy.md +++ b/docs/gen/policies/policy.md @@ -39,7 +39,7 @@ Example of… - [v1EMAIns](#v1-e-m-a-ins) – Inputs for the EMA component. - [v1EMAOuts](#v1-e-m-a-outs) – Outputs for the EMA component. - [v1EqualsMatchExpression](#v1-equals-match-expression) – Label selector expression of the equal form "label == value". -- [v1Extractor](#v1-extractor) – Defines a high-level way to specify how to extract a flow label given http request metadata, without a need to write rego code +- [v1Extractor](#v1-extractor) – Defines a high-level way to specify how to extract a flow label value given http request metadata, without a need to write rego code - [v1Extrapolator](#v1-extrapolator) – Extrapolates the input signal by repeating the last valid value during the period in which it is invalid - [v1ExtrapolatorIns](#v1-extrapolator-ins) – Inputs for the Extrapolator component. - [v1ExtrapolatorOuts](#v1-extrapolator-outs) – Outputs for the Extrapolator component. @@ -51,7 +51,9 @@ Example of… - [v1JSONExtractor](#v1-json-extractor) – Deserialize a json, and extract one of the fields - [v1JWTExtractor](#v1-j-w-t-extractor) – Parse the attribute as JWT and read the payload - [v1K8sLabelMatcherRequirement](#v1-k8s-label-matcher-requirement) – Label selector requirement which is a selector that contains values, a key, and … -- [v1LabelMatcher](#v1-label-matcher) – Allows to define rules whether a map of labels should be considered a match or not +- [v1LabelMatcher](#v1-label-matcher) – Allows to define rules whether a map of + [labels](/concepts/flow-control/label/label.md) + should be considered a match or not - [v1LoadShedActuator](#v1-load-shed-actuator) – Takes the load shed factor input signal and publishes it to the schedulers in the data-plane - [v1LoadShedActuatorIns](#v1-load-shed-actuator-ins) – Input for the Load Shed Actuator component. - [v1MatchExpression](#v1-match-expression) – Defines a [map → bool] expression to be evaluated on labels @@ -196,9 +198,8 @@ Workload defines a class of requests that preferably have similar properties suc
fairness_key
-(string) Fairness key is a label key that can be used to provide fairness within a workload - -Any label that could be used in label matcher can be used here. Eg. if +(string) Fairness key is a label key that can be used to provide fairness within a workload. +Any [flow label](/concepts/flow-control/label/label.md) can be used here. Eg. if you have a classifier that sets `user` flow label, you might want to set `fairness_key = "user"`. @@ -232,7 +233,8 @@ This override is applicable only if `auto_tokens` is set to false.
label_matcher
-([V1LabelMatcher](#v1-label-matcher)) Label Matcher to select a Workload. +([V1LabelMatcher](#v1-label-matcher)) Label Matcher to select a Workload based on +[flow labels](/concepts/flow-control/label/label.md).
@@ -240,7 +242,7 @@ This override is applicable only if `auto_tokens` is set to false.
workload
-([SchedulerWorkload](#scheduler-workload)) Workload associated with requests matching the label matcher. +([SchedulerWorkload](#scheduler-workload)) Workload associated with flows matching the label matcher.
@@ -310,9 +312,10 @@ to select which label should be used as key. (string, `required`) Specifies which label the ratelimiter should be keyed by. -Rate limiting is done independently for each value of the label with given -key. Eg., to give each user a separate limit, assuming you have a _user_ -flow label set up, set `label_key: "user"`. +Rate limiting is done independently for each value of the +[label](/concepts/flow-control/label/label.md) with given key. +Eg., to give each user a separate limit, assuming you have a _user_ flow +label set up, set `label_key: "user"`. TODO make it possible for this field to be optional – to achieve global ratelimit. @@ -539,6 +542,10 @@ This interval is typically aligned with how often the corrective action (actuati Set of classification rules sharing a common selector +:::info +See also [Classifier overview](/concepts/flow-control/label/classifier.md). +::: + Example: ```yaml @@ -558,7 +565,9 @@ rules:
rules
-(map of [V1Rule](#v1-rule)) A map of {key, value} pairs mapping from flow label names to rules that define how to extract and propagate them. +(map of [V1Rule](#v1-rule)) A map of {key, value} pairs mapping from +[flow label](/concepts/flow-control/label/label.md) keys to rules that define +how to extract and propagate flow labels with that key.
@@ -1057,7 +1066,7 @@ Label selector expression of the equal form "label == value". ### v1Extractor -Defines a high-level way to specify how to extract a flow label given http request metadata, without a need to write rego code +Defines a high-level way to specify how to extract a flow label value given http request metadata, without a need to write rego code There are multiple variants of extractor, specify exactly one. @@ -1446,7 +1455,9 @@ If the operator is Exists or DoesNotExist, the values array must be empty. ### v1LabelMatcher -Allows to define rules whether a map of labels should be considered a match or not +Allows to define rules whether a map of +[labels](/concepts/flow-control/label/label.md) +should be considered a match or not It provides three ways to define requirements: @@ -1974,7 +1985,8 @@ sensitive labels.
(bool) Decides if the created label should be applied to the whole request chain -(propagated in baggage) (default=true). +(propagated in [baggage](/concepts/flow-control/label/label.md#baggage)) +(default=true).
@@ -2079,7 +2091,7 @@ This value impacts the prioritization and fairness because the larger the timeou ([[]SchedulerWorkloadAndLabelMatcher](#scheduler-workload-and-label-matcher)) List of workloads to be used in scheduler. -Categorizing [flows](/concepts/flow-control/flow-control.md#what-is-a-flow) into workloads +Categorizing [flows](/concepts/flow-control/flow-control.md#flow) into workloads allows for load-shedding to be "smarter" than just "randomly deny 50% of requests". There are two aspects of this "smartness": @@ -2116,7 +2128,7 @@ Output for the Scheduler component. :::info **Accepted tokens** are tokens associated with -[flows](/concepts/flow-control/flow-control.md#what-is-a-flow) that were accepted by +[flows](/concepts/flow-control/flow-control.md#flow) that were accepted by this scheduler. Number of tokens for a flow is determined by a [workload](#-schedulerworkload) that the flow was assigned to (either via `auto_tokens` or explicitly by `Workload.tokens`). @@ -2183,24 +2195,20 @@ selector:
label_matcher
-([V1LabelMatcher](#v1-label-matcher)) Label matcher allows to add _additional_ condition on labels that must -also be satisfied (in addition to service+control point matching) - -This matcher allows to match on flow labels and request labels. -(Note: For classification we can only match flow labels that were created at -some **previous** control point). +([V1LabelMatcher](#v1-label-matcher)) Label matcher allows to add _additional_ condition on +[flow labels](/concepts/flow-control/label/label.md) +must also be satisfied (in addition to service+control point matching) -Flow labels are available with the same label key as defined in -classification rule. - -Request labels are always prefixed with `request_`. Available request -labels are `id` (available as `request_id`), `method`, `path`, `host`, -`scheme`, `size`, `protocol` (mapped from fields of -[HttpRequest](https://github.com/envoyproxy/envoy/blob/637a92a56e2739b5f78441c337171968f18b46ee/api/envoy/service/auth/v3/attribute_context.proto#L102)). -Also, (non-pseudo) headers are available as `request_header_`, where -`` is a headername normalised to lowercase, eg. `request_header_user-agent`. - -Note: Request headers are only available for `traffic` control points. +:::note +[Classifiers](#-v1classifier) _can_ use flow labels created by some other +classifier, but only if they were created at some previous control point +(and propagated in baggage). + +This limitation doesn't apply to selectors of other entities, like +FluxMeters or actuators. It's valid to create a flow label on a control +point using classifier, and immediately use it for matching on the same +control point. +:::