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

extensions: add http bandwidth limit filter #16358

Merged
merged 42 commits into from
May 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
4f21be4
add bandwidth limit filter core functionality and UTs
nitgoy May 6, 2021
e2e9ff3
docs and format fix
nitgoy May 6, 2021
42ad169
try fix docs precheck error
nitgoy May 6, 2021
bcb06b3
fix format
nitgoy May 7, 2021
efc4d21
fix spelling
nitgoy May 7, 2021
0e3ae50
use duration type for fill_interval proto field
nitgoy May 8, 2021
cab2a33
revert token bucket changes
nitgoy May 8, 2021
5059bc2
format fix
nitgoy May 8, 2021
f4cb248
try format fix again
nitgoy May 8, 2021
e038f7d
fix format pre
nitgoy May 10, 2021
7052748
try fix clang tidy
nitgoy May 10, 2021
d128ac8
fix build errors
nitgoy May 10, 2021
e6d805b
Merge from upstream
nitgoy May 12, 2021
eb74ffc
add more test assertions
nitgoy May 13, 2021
7cf3f4f
fix docs
nitgoy May 14, 2021
ea77fde
test coverage fixes
nitgoy May 15, 2021
fafa873
format fix
nitgoy May 15, 2021
d92b8d4
merge from upstream
nitgoy May 17, 2021
7d21500
minor: version history
nitgoy May 17, 2021
573f2da
readd deleted method
nitgoy May 17, 2021
75e8874
format fix
nitgoy May 17, 2021
530c569
update owners
nitgoy May 18, 2021
68c5c24
minor: comment
nitgoy May 18, 2021
85642de
Merge branch 'main' of https://github.com/envoyproxy/envoy into bwlfi…
nitgoy May 18, 2021
2dae1e8
Merge branch 'main' into bwlfilter
nitgoy May 18, 2021
6371854
Merge branch 'bwlfilter' of github.com:nitgoy/envoy into bwlfilter
nitgoy May 18, 2021
c3b8ef0
Merge branch 'main' into bwlfilter
nitgoy May 19, 2021
f942789
fix format
nitgoy May 19, 2021
e999e75
fix typo
nitgoy May 19, 2021
40af12a
Merge branch 'main' into bwlfilter
nitgoy May 19, 2021
ecc7dec
move example config to separate yaml
nitgoy May 20, 2021
99458ed
Merge branch 'bwlfilter' of github.com:nitgoy/envoy into bwlfilter
nitgoy May 20, 2021
d6c7d41
revert merge typo
nitgoy May 20, 2021
9356621
fix
nitgoy May 20, 2021
62ca7fe
try fix build
nitgoy May 21, 2021
9c08bf5
more doc improvements
nitgoy May 21, 2021
cdb60a0
fix format
nitgoy May 21, 2021
ce53ad6
address comment
nitgoy May 21, 2021
f7e39d9
address doc comments
nitgoy May 24, 2021
4fc4837
rename proto enum values
nitgoy May 24, 2021
54302e9
make getConfig return ref
nitgoy May 25, 2021
2a70c24
rename enum and stats values
nitgoy May 25, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,8 @@ extensions/filters/http/oauth2 @rgs1 @derekargueta @snowp
/*/extensions/filters/common/ext_authz @esmet @gsagula @dio
/*/extensions/filters/http/ext_authz @esmet @gsagula @dio
/*/extensions/filters/network/ext_authz @esmet @gsagula @dio
# HTTP Bandwidth Limit
/*/extensions/filters/http/bandwidth_limit @nitgoy @mattklein123 @yanavlasov @tonya11en
# Original IP detection
/*/extensions/http/original_ip_detection/custom_header @rgs1 @alyssawilk @antoniovicente
/*/extensions/http/original_ip_detection/xff @rgs1 @alyssawilk @antoniovicente
1 change: 1 addition & 0 deletions api/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ proto_library(
"//envoy/extensions/filters/http/admission_control/v3alpha:pkg",
"//envoy/extensions/filters/http/aws_lambda/v3:pkg",
"//envoy/extensions/filters/http/aws_request_signing/v3:pkg",
"//envoy/extensions/filters/http/bandwidth_limit/v3alpha:pkg",
"//envoy/extensions/filters/http/buffer/v3:pkg",
"//envoy/extensions/filters/http/cache/v3alpha:pkg",
"//envoy/extensions/filters/http/cdn_loop/v3alpha:pkg",
Expand Down
6 changes: 3 additions & 3 deletions api/STYLE.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,11 @@ organization](#package-organization) above.
To add an extension config to the API, the steps below should be followed:

1. If this is still WiP and subject to breaking changes, use `vNalpha` instead of `vN` in steps
below. Refer to the [Cache filter config](envoy/extensions/filter/http/cache/v3alpha/cache.proto)
below. Refer to the [Cache filter config](envoy/extensions/filters/http/cache/v3alpha/cache.proto)
as an example of `v3alpha`, and the
[Buffer filter config](envoy/extensions/filter/http/buffer/v3/buffer.proto) as an example of `v3`.
[Buffer filter config](envoy/extensions/filters/http/buffer/v3/buffer.proto) as an example of `v3`.
1. Place the v3 extension configuration `.proto` in `api/envoy/extensions`, e.g.
`api/envoy/extensions/filter/http/foobar/v3/foobar.proto` together with an initial BUILD file:
`api/envoy/extensions/filters/http/foobar/v3/foobar.proto` together with an initial BUILD file:
```bazel
load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package")

Expand Down
12 changes: 12 additions & 0 deletions api/envoy/extensions/filters/http/bandwidth_limit/v3alpha/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# DO NOT EDIT. This file is generated by tools/proto_format/proto_sync.py.

load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package")

licenses(["notice"]) # Apache 2

api_proto_package(
deps = [
"//envoy/config/core/v3:pkg",
"@com_github_cncf_udpa//udpa/annotations:pkg",
],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
syntax = "proto3";

package envoy.extensions.filters.http.bandwidth_limit.v3alpha;

import "envoy/config/core/v3/base.proto";

import "google/protobuf/duration.proto";
import "google/protobuf/wrappers.proto";

import "udpa/annotations/status.proto";
import "validate/validate.proto";

option java_package = "io.envoyproxy.envoy.extensions.filters.http.bandwidth_limit.v3alpha";
option java_outer_classname = "BandwidthLimitProto";
option java_multiple_files = true;
option (udpa.annotations.file_status).work_in_progress = true;
option (udpa.annotations.file_status).package_version_status = ACTIVE;

// [#protodoc-title: Bandwidth limit]
// Bandwidth limit :ref:`configuration overview <config_http_filters_bandwidth_limit>`.
// [#extension: envoy.filters.http.bandwidth_limit]

// [#next-free-field: 6]
message BandwidthLimit {
// Defines the mode for the bandwidth limit filter.
// Values represent bitmask.
enum EnableMode {
// Filter is disabled.
DISABLED = 0;

// Filter enabled only for incoming traffic.
REQUEST = 1;

// Filter enabled only for outgoing traffic.
RESPONSE = 2;

// Filter enabled for both incoming and outgoing traffic.
REQUEST_AND_RESPONSE = 3;
}

// The human readable prefix to use when emitting stats.
string stat_prefix = 1 [(validate.rules).string = {min_len: 1}];

// The enable mode for the bandwidth limit filter.
// Default is Disabled.
EnableMode enable_mode = 2 [(validate.rules).enum = {defined_only: true}];

// The limit supplied in KiB/s.
//
// .. note::
// It's fine for the limit to be unset for the global configuration since the bandwidth limit
// can be applied at a the virtual host or route level. Thus, the limit must be set for the
// per route configuration otherwise the config will be rejected.
//
// .. note::
// When using per route configuration, the limit becomes unique to that route.
//
google.protobuf.UInt64Value limit_kbps = 3 [(validate.rules).uint64 = {gte: 1}];

// Optional Fill interval in milliseconds for the token refills. Defaults to 50ms.
// It must be at least 20ms to avoid too aggressive refills.
google.protobuf.Duration fill_interval = 4 [(validate.rules).duration = {
lte {seconds: 1}
gte {nanos: 20000000}
}];

// Runtime flag that controls whether the filter is enabled or not. If not specified, defaults
// to enabled.
config.core.v3.RuntimeFeatureFlag runtime_enabled = 5;
}
1 change: 1 addition & 0 deletions api/versioning/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ proto_library(
"//envoy/extensions/filters/http/admission_control/v3alpha:pkg",
"//envoy/extensions/filters/http/aws_lambda/v3:pkg",
"//envoy/extensions/filters/http/aws_request_signing/v3:pkg",
"//envoy/extensions/filters/http/bandwidth_limit/v3alpha:pkg",
"//envoy/extensions/filters/http/buffer/v3:pkg",
"//envoy/extensions/filters/http/cache/v3alpha:pkg",
"//envoy/extensions/filters/http/cdn_loop/v3alpha:pkg",
Expand Down
2 changes: 1 addition & 1 deletion docs/root/api-v3/config/filter/http/http.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ HTTP filters
:maxdepth: 2

*/empty/*
../../../extensions/filters/http/*/v3/*
../../../extensions/filters/http/*/v3*/*
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
static_resources:
listeners:
- address:
socket_address:
address: 0.0.0.0
port_value: 8000
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
codec_type: AUTO
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ["*"]
routes:
- match: { prefix: "/path/with/bandwidth/limit" }
route: { cluster: service_protected_by_bandwidth_limit }
typed_per_filter_config:
envoy.filters.http.bandwidth_limit:
"@type": type.googleapis.com/envoy.extensions.filters.http.bandwidth_limit.v3alpha.BandwidthLimit
stat_prefix: bandwidth_limiter_custom_route
enable_mode: REQUEST_AND_RESPONSE
limit_kbps: 500
fill_interval: 0.1s
- match: { prefix: "/" }
route: { cluster: web_service }
http_filters:
- name: envoy.filters.http.bandwidth_limit
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.bandwidth_limit.v3alpha.BandwidthLimit
stat_prefix: bandwidth_limiter_default
- name: envoy.filters.http.router
typed_config: {}

clusters:
- name: service_protected_by_bandwidth_limit
connect_timeout: 0.25s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: service1
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: web_service
port_value: 9000
- name: web_service
connect_timeout: 0.25s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: service1
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: web_service
port_value: 9000
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
.. _config_http_filters_bandwidth_limit:

Bandwidth limit
====================

* Bandwidth limiting :ref:`architecture overview <arch_overview_bandwidth_limit>`
* :ref:`v3 API reference <envoy_v3_api_msg_extensions.filters.http.bandwidth_limit.v3alpha.BandwidthLimit>`
* This filter should be configured with the name ``envoy.filters.http.bandwidth_limit``.

The HTTP Bandwidth limit filter limits the size of data flow to the max bandwidth set in the ``limit_kbps``
when the request's route, virtual host or filter chain has a
:ref:`bandwidth limit configuration <envoy_v3_api_msg_extensions.filters.http.bandwidth_limit.v3alpha.BandwidthLimit>`.

If the bandwidth limit has been exhausted the filter stops further transfer until more bandwidth gets allocated
according to the ``fill_interval`` (default is 50 milliseconds). If the connection buffer fills up with accumulated
data then the source of data will have ``readDisable(true)`` set as described in the :repo:`flow control doc<source/docs/flow_control.md>`.

.. note::
The token bucket is shared across all workers, thus the limits are applied per Envoy process.

Example configuration
---------------------

Example filter configuration for a globally disabled bandwidth limiter but enabled for a specific route:

.. literalinclude:: _include/bandwidth-limit-filter.yaml
:language: yaml
:lines: 11-53
:emphasize-lines: 9-25
:caption: :download:`bandwidth-limit-filter.yaml <_include/bandwidth-limit-filter.yaml>`

Note that if this filter is configured as globally disabled and there are no virtual host or route level
token buckets, no bandwidth limiting will be applied.

Statistics
----------

The HTTP bandwidth limit filter outputs statistics in the ``<stat_prefix>.http_bandwidth_limit.`` namespace.

.. csv-table::
:header: Name, Type, Description
:widths: 1, 1, 2

request_enabled, Counter, Total number of request streams for which the bandwidth limiter was consulted
request_pending, GAUGE, Number of request streams which are currently pending transfer in bandwidth limiter
request_incoming_size, GAUGE, Size in bytes of incoming request data to bandwidth limiter
request_allowed_size, GAUGE, Size in bytes of outgoing request data from bandwidth limiter
request_transfer_duration, HISTOGRAM, Total time (including added delay) it took for the request stream transfer
response_enabled, Counter, Total number of response streams for which the bandwidth limiter was consulted
response_pending, GAUGE, Number of response streams which are currently pending transfer in bandwidth limiter
response_incoming_size, GAUGE, Size in bytes of incoming response data to bandwidth limiter
response_allowed_size, GAUGE, Size in bytes of outgoing response data from bandwidth limiter
response_transfer_duration, HISTOGRAM, Total time (including added delay) it took for the response stream transfer

.. _config_http_filters_bandwidth_limit_runtime:

Runtime
-------

The HTTP bandwidth limit filter supports the following runtime settings:

The bandwidth limit filter can be runtime feature flagged via the :ref:`enabled
<envoy_v3_api_field_extensions.filters.http.bandwidth_limit.v3alpha.BandwidthLimit.runtime_enabled>`
configuration field.
1 change: 1 addition & 0 deletions docs/root/configuration/http/http_filters/http_filters.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ HTTP filters
admission_control_filter
aws_lambda_filter
aws_request_signing_filter
bandwidth_limit_filter
buffer_filter
cdn_loop_filter
compressor_filter
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.. _arch_overview_bandwidth_limit:

Bandwidth limiting
===================

Envoy supports local (non-distributed) bandwidth limiting of HTTP requests and response via the
:ref:`HTTP bandwidth limit filter <config_http_filters_bandwidth_limit>`. This can be activated
globally at the listener level or at a more specific level (e.g.: the virtual host or route level).

Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Other features

local_rate_limiting
global_rate_limiting
bandwidth_limiting
scripting
ip_transparency
compression/libraries
3 changes: 2 additions & 1 deletion docs/root/version_history/current.rst
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ Removed Config or Runtime

New Features
------------
* crash support: restore crash context when continuing to processing requests or responses as a result of an asynchronous callback that invokes a filter directly. This is unlike the call stacks that go through the various network layers, to eventually reach the filter. For a concrete example see: ``Envoy::Extensions::HttpFilters::Cache::CacheFilter::getHeaders`` which posts a callback on the dispatcher that will invoke the filter directly.
* bandwidth_limit: added new :ref:`HTTP bandwidth limit filter <config_http_filters_bandwidth_limit>`.
* crash support: restore crash context when continuing to processing requests or responses as a result of an asynchronous callback that invokes a filter directly. This is unlike the call stacks that go through the various network layers, to eventually reach the filter. For a concrete example see: ``Envoy::Extensions::HttpFilters::Cache::CacheFilter::getHeaders`` which posts a callback on the dispatcher that will invoke the filter directly.
* http: a new field `is_optional` is added to `extensions.filters.network.http_connection_manager.v3.HttpFilter`. When
value is `true`, the unsupported http filter will be ignored by envoy. This is also same with unsupported http filter
in the typed per filter config. For more information, please reference
Expand Down
1 change: 1 addition & 0 deletions generated_api_shadow/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ proto_library(
"//envoy/extensions/filters/http/admission_control/v3alpha:pkg",
"//envoy/extensions/filters/http/aws_lambda/v3:pkg",
"//envoy/extensions/filters/http/aws_request_signing/v3:pkg",
"//envoy/extensions/filters/http/bandwidth_limit/v3alpha:pkg",
"//envoy/extensions/filters/http/buffer/v3:pkg",
"//envoy/extensions/filters/http/cache/v3alpha:pkg",
"//envoy/extensions/filters/http/cdn_loop/v3alpha:pkg",
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions source/extensions/extensions_build_config.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ EXTENSIONS = {
"envoy.filters.http.admission_control": "//source/extensions/filters/http/admission_control:config",
"envoy.filters.http.aws_lambda": "//source/extensions/filters/http/aws_lambda:config",
"envoy.filters.http.aws_request_signing": "//source/extensions/filters/http/aws_request_signing:config",
"envoy.filters.http.bandwidth_limit": "//source/extensions/filters/http/bandwidth_limit:config",
"envoy.filters.http.buffer": "//source/extensions/filters/http/buffer:config",
"envoy.filters.http.cache": "//source/extensions/filters/http/cache:config",
"envoy.filters.http.cdn_loop": "//source/extensions/filters/http/cdn_loop:config",
Expand Down
Loading