Skip to content

Commit 267f994

Browse files
Adding GEP 3171: Percentage-based Request Mirroring (#3178)
* Create index.md * Create metadata.yaml * Update index.md * Update metadata.yaml * Remove 'omitempty' from Fraction fields * Split MirrorPercent into two fields: MirrorPercent and MirrorFraction. * Update index.md * Add config examples. * Add Existing Support Table * Update field names to avoid 'stuttering' in names. * Update geps/gep-3171/index.md Co-authored-by: Rob Scott <rob.scott87@gmail.com> --------- Co-authored-by: Rob Scott <rob.scott87@gmail.com>
1 parent 89996b5 commit 267f994

File tree

2 files changed

+185
-0
lines changed

2 files changed

+185
-0
lines changed

geps/gep-3171/index.md

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
# GEP-3171: Percentage-based Request Mirroring
2+
3+
* Issue: [#3171](https://github.com/kubernetes-sigs/gateway-api/issues/3171)
4+
* Status: **Implementable**
5+
6+
(See status definitions [here](/geps/overview/#gep-states).)
7+
8+
## TLDR
9+
10+
Enhance the existing [Request Mirroring](https://gateway-api.sigs.k8s.io/guides/http-request-mirroring/) feature by allowing users to specify a percentage of requests they'd like mirrored.
11+
12+
## Goals
13+
14+
Successfully implement the feature.
15+
16+
## Introduction
17+
18+
[Request Mirroring](https://gateway-api.sigs.k8s.io/guides/http-request-mirroring/) is a feature that allows a user to mirror requests going to some backend A along to some other specified backend B. Right now Request Mirroring is an all or nothing feature – either 100% of request are mirrored, or 0% are. Percentage-based Request Mirroring will allow users to specify a percentage of requests they'd like mirrored as opposed to every single request.
19+
20+
This feature is already [supported by Envoy](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-msg-config-route-v3-routeaction-requestmirrorpolicy), so adding it for the Gateway API would enable better integration between the two products. There's also an existing user desire for this feature on the [HAProxy side](https://www.haproxy.com/blog/haproxy-traffic-mirroring-for-real-world-testing) and [NGINX side](https://alex.dzyoba.com/blog/nginx-mirror/). Since Request Mirroring is already supported by the Gateway API, Percentage-based Request Mirroring would a clear improvement on this pre-existing feature.
21+
22+
## Existing Support in Implementations
23+
24+
| Implementation | Support |
25+
|----------------|------------|
26+
| Envoy | [config.route.v3.RouteAction.RequestMirrorPolicy](config.route.v3.RouteAction.RequestMirrorPolicy) |
27+
| HAProxy | [HAProxy SPOP](https://github.com/haproxytech/spoa-mirror) |
28+
| NGINX | [ngx_http_mirror_module](https://nginx.org/en/docs/http/ngx_http_mirror_module.html) |
29+
| gCloud | [RequestMirrorPolicy](https://cloud.google.com/python/docs/reference/compute/latest/google.cloud.compute_v1.types.RequestMirrorPolicy) |
30+
31+
## API
32+
33+
This GEP proposes the following API changes:
34+
35+
* Add utility type `Fraction` to [v1/shared_types.go](https://github.com/kubernetes-sigs/gateway-api/blob/cb5bf1541fa70f0692aebde8c64bba434cf331b6/apis/v1/shared_types.go):
36+
37+
38+
```go
39+
type Fraction struct {
40+
// +optional
41+
// +kubebuilder:default=100
42+
// +kubebuilder:validation:Minimum=0
43+
Numerator int32 `json:"numerator"`
44+
45+
// +optional
46+
// +kubebuilder:default=100
47+
// +kubebuilder:validation:Minimum=1
48+
Denominator int32 `json:"denominator"`
49+
}
50+
```
51+
52+
53+
* Update the `HTTPRequestMirrorFilter` struct to include a `Percent` field of type `int32`, and a `Fraction` field of type `Fraction`:
54+
55+
56+
```go
57+
// HTTPRequestMirrorFilter defines configuration for the RequestMirror filter.
58+
type HTTPRequestMirrorFilter struct {
59+
// BackendRef references a resource where mirrored requests are sent.
60+
//
61+
// Mirrored requests must be sent only to a single destination endpoint
62+
// within this BackendRef, irrespective of how many endpoints are present
63+
// within this BackendRef.
64+
//
65+
// If the referent cannot be found, this BackendRef is invalid and must be
66+
// dropped from the Gateway. The controller must ensure the "ResolvedRefs"
67+
// condition on the Route status is set to `status: False` and not configure
68+
// this backend in the underlying implementation.
69+
//
70+
// If there is a cross-namespace reference to an *existing* object
71+
// that is not allowed by a ReferenceGrant, the controller must ensure the
72+
// "ResolvedRefs" condition on the Route is set to `status: False`,
73+
// with the "RefNotPermitted" reason and not configure this backend in the
74+
// underlying implementation.
75+
//
76+
// In either error case, the Message of the `ResolvedRefs` Condition
77+
// should be used to provide more detail about the problem.
78+
//
79+
// Support: Extended for Kubernetes Service
80+
//
81+
// Support: Implementation-specific for any other resource
82+
BackendRef BackendObjectReference `json:"backendRef"`
83+
84+
// Percent represents the percentage of requests that should be
85+
// mirrored to BackendRef. Its minimum value is 0 (indicating 0% of
86+
// requests) and its maximum value is 100 (indicating 100% of requests).
87+
//
88+
// If both Percent and Fraction are specified, Fraction will take
89+
// priority. If Percent is unspecified, it will have a default value of
90+
// 100. If Fraction is unspecified, it will have a default value of
91+
// 100/100. This means that if neither field is specified, 100% of
92+
// requests will be mirrored.
93+
//
94+
// +optional
95+
// +kubebuilder:default=100
96+
// +kubebuilder:validation:Minimum=0
97+
// +kubebuilder:validation:Maximum=100
98+
Percent int32 `json:"percent,omitempty"`
99+
100+
// Fraction represents the fraction of requests that should be
101+
// mirrored to BackendRef.
102+
//
103+
// If both Percent and Fraction are specified, Fraction will take
104+
// priority. If Percent is unspecified, it will have a default value of
105+
// 100. If Fraction is unspecified, it will have a default value of
106+
// 100/100. This means that if neither field is specified, 100% of
107+
// requests will be mirrored.
108+
//
109+
// +optional
110+
Fraction Fraction `json:"fraction,omitempty"`
111+
}
112+
```
113+
114+
## Example
115+
116+
An example with Percent:
117+
118+
119+
```
120+
apiVersion: gateway.networking.k8s.io/v1
121+
kind: HTTPRoute
122+
metadata:
123+
name: http-filter-mirror
124+
labels:
125+
gateway: mirror-gateway
126+
spec:
127+
parentRefs:
128+
- name: mirror-gateway
129+
hostnames:
130+
- mirror.example
131+
rules:
132+
- backendRefs:
133+
- name: foo-v1
134+
port: 8080
135+
filters:
136+
- type: RequestMirror
137+
requestMirror:
138+
backendRef:
139+
name: foo-v2
140+
port: 8080
141+
percent: 42
142+
```
143+
This would result in 42% of requests going to `foo-v1` to be mirrored to `foo-v2`.
144+
145+
An example with Fraction:
146+
147+
148+
```
149+
apiVersion: gateway.networking.k8s.io/v1
150+
kind: HTTPRoute
151+
metadata:
152+
name: http-filter-mirror
153+
labels:
154+
gateway: mirror-gateway
155+
spec:
156+
parentRefs:
157+
- name: mirror-gateway
158+
hostnames:
159+
- mirror.example
160+
rules:
161+
- backendRefs:
162+
- name: foo-v1
163+
port: 8080
164+
filters:
165+
- type: RequestMirror
166+
requestMirror:
167+
backendRef:
168+
name: foo-v2
169+
port: 8080
170+
fraction:
171+
numerator: 5
172+
denominator: 1000
173+
```
174+
This would result in 0.5% of requests going to `foo-v1` to be mirrored to `foo-v2`.

geps/gep-3171/metadata.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
apiVersion: internal.gateway.networking.k8s.io/v1alpha2
2+
kind: GEPDetails
3+
number: 3171
4+
name: Percentage-based Request Mirroring
5+
status: Provisional
6+
authors:
7+
- jakebennert
8+
references:
9+
- https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io%2fv1.HTTPRequestMirrorFilter
10+
featureNames:
11+
- Percentage-based Request Mirroring

0 commit comments

Comments
 (0)