generated from kubernetes/kubernetes-template-project
-
Notifications
You must be signed in to change notification settings - Fork 511
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
202 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,202 @@ | ||
# GEP-735: TCP and UDP addresses and port matching | ||
|
||
* Issue: [#735](https://github.com/kubernetes-sigs/gateway-api/issues/735) | ||
* Status: Provisional | ||
|
||
## TLDR | ||
|
||
Spec for matching source and destination addresses & ports on L4 APIs. | ||
|
||
## Goals | ||
|
||
- add matching rules for address/port to `TCPRoute` | ||
- add matching rules for address/port to `UDPRoute` | ||
- intentionally avoid type definitions that would make it hard to expand later | ||
|
||
## Non-Goals | ||
|
||
- defining match rules for source ports | ||
|
||
## Introduction | ||
|
||
While `TCPRoute` and `UDPRoute` currently support custom matching extensions, | ||
there is desire among the community to include some "fundamental" matching | ||
options in the spec that cover the most common requirements. In this GEP we | ||
request address and port matching for these APIs in order to support a standard | ||
for some of the commonplace setups of gateway implementations. Matching is | ||
intended to be covered for both _source_ and _destination_ to enable a finer | ||
level of tuning options for L4 traffic routing at a level below the `Gateway`. | ||
|
||
When this GEP was started the intention was to cover source port matching but | ||
the use cases for such were significantly less obvious than matching for other | ||
types, and it seemed likely that a port _range_ would be wanted in that case. | ||
Given the lack of strong requirements source ports were left out for this | ||
iteration with the intention that it can be very easily added later to the | ||
`TrafficMatches` type there's stronger requirements established. | ||
|
||
## API | ||
|
||
The API changes include the following new types: | ||
|
||
- `NetworkMatch` to indicate the IP for address matching | ||
- `TrafficMatches` to configure matching according to network address and ports | ||
|
||
These types enable the port and address matching required, with some | ||
active considerations about how to leave these open ended for later expansion. | ||
|
||
### NetworkMatch Type | ||
|
||
A new `NetworkMatch` type provides the targeting mechanism for match inclusion | ||
of a given network address: | ||
|
||
```go | ||
type NetworkMatch struct { | ||
// Address is an IP address which refers to either an IPv4 or IPv6 address. | ||
// | ||
// Examples: `127.0.0.1`, `::1` | ||
// | ||
// +kubebuilder:validation:MinLength=1 | ||
// +kubebuilder:validation:MaxLength=45 | ||
Address string `json:"address"` | ||
} | ||
``` | ||
|
||
The purpose of calling this `NetworkMatch` and wrapping the single `IP` attribute in | ||
a structure is to enable forward expansion in case later we're interested in | ||
adding more specificity, such as perhaps the network mask or `/<int>` CIDR to | ||
allow matching within a network range, instead of a specific IP address: | ||
|
||
```go | ||
type NetworkMatch struct { | ||
Address string `json:"address"` | ||
Mask *string `json:"mask"` | ||
} | ||
``` | ||
|
||
However for this iteration the goal is to keep the initial spec simple and to | ||
the immediate goals so only `Address` is intended for inclusion until further | ||
requirements develop. | ||
|
||
### PortMatch Type | ||
|
||
a new `PortMatch` type provides the targeting mechanism for match inclusion of | ||
a given network port: | ||
|
||
```go | ||
type PortMatch struct { | ||
// Port is a network port. | ||
// | ||
// Examples: `80`, `443` | ||
// | ||
// +kubebuilder:validation:MinLength=1 | ||
// +kubebuilder:validation:MaxLength=5 | ||
Port PortNumber `json:"port"` | ||
} | ||
``` | ||
|
||
Similar to the `NetworkMatch` above, the purpose of wrapping the port in a | ||
struct is to help make it easier to add functionality later without having | ||
to publish a new API and conversions. | ||
|
||
### TrafficMatches Type | ||
|
||
Using the new `NetworkMatch` and `PortMatch` type, matches can be expressed in | ||
topical lists on `TCPRoute` and `UDPRoute` using the new `TrafficMatches` type: | ||
|
||
```go | ||
type TrafficMatches struct { | ||
// SourceAddresses indicates the originating (source) network | ||
// addresses which are valid for routing traffic. | ||
SourceAddresses []NetworkMatch `json:"sourceAddresses"` | ||
|
||
// DestinationAddresses indicates the destination network addresses | ||
// which are valid for routing traffic. | ||
DestinationAddresses []NetworkMatch `json:"destinationAddresses"` | ||
|
||
// DestinationPorts indicates the destination network ports that are | ||
// valid for routing traffic. | ||
DestinationPorts []PortMatch `json:"destinationPorts"` | ||
``` | ||
This type becomes an optional field and shared by both `TCPRouteRule` and | ||
`UDPRouteRule`: | ||
```go | ||
type TCPRouteRule struct { | ||
// Matches add rules for filtering traffic to backends based on addresses | ||
// and ports. | ||
// | ||
// +optional | ||
Matches *TrafficMatches `json:"matches"` | ||
|
||
// BackendRefs defines the backend(s) where matching requests should be | ||
// sent. If unspecified or invalid (refers to a non-existent resource or a | ||
// Service with no endpoints), the underlying implementation MUST actively | ||
// reject connection attempts to this backend. Connection rejections must | ||
// respect weight; if an invalid backend is requested to have 80% of | ||
// connections, then 80% of connections must be rejected instead. | ||
// | ||
// Support: Core for Kubernetes Service | ||
// Support: Custom for any other resource | ||
// | ||
// Support for weight: Extended | ||
// | ||
// +kubebuilder:validation:MinItems=1 | ||
// +kubebuilder:validation:MaxItems=16 | ||
BackendRefs []BackendRef `json:"backendRefs,omitempty"` | ||
} | ||
``` | ||
The above would make the following YAML examples possible: | ||
```yaml | ||
apiVersion: gateway.networking.k8s.io/v1alpha2 | ||
kind: TCPRoute | ||
metadata: | ||
name: matching | ||
spec: | ||
rules: | ||
- matches: | ||
sourceAddresses: | ||
- address: "192.168.1.1" | ||
- address: "FE80::0202:B3FF:FE1E:8329" | ||
destinationAddresses: | ||
- address: "10.96.0.1" | ||
destinationPorts: | ||
- port: 8080 | ||
backendRefs: | ||
- name: my-service | ||
port: 8080 | ||
``` | ||
## Alternatives | ||
### Pure Gateway Mode | ||
Technically the existing specification supported this kind of matching through | ||
`Gateway` object `Listeners` and it was considered to simply document that | ||
further and expand upon it, but in a desire to better support more complex | ||
setups that are becoming commonplace in the ecosystem (e.g. service mesh) there | ||
was sufficient cause to add this functionality at the route level. | ||
### Copying NetworkPolicy | ||
After the first draft of this document we consulted the `NetworkPolicy` API to | ||
determine if there were enough similarities to copy some of the semantics there | ||
to here. Both the [existing API][k8s-net] and (at the time of writing) the | ||
[upcoming API][pol-new] were reviewed. Ultimately some influence was taken from | ||
`NetworkPolicyPort` to define the `PolicyMatch` structure here, but some ideas | ||
such as binding ports and network addresses together in a single struct did not | ||
seem necessary as the `RuleAction` present in policy did not seem applicable | ||
for this work at the time. We may want to revisit this as the new policy work | ||
merges and matures. | ||
[k8s-net]:https://github.com/kubernetes/kubernetes/blob/1e6f3b5cd68049a3501782af8ff3ddd647d0b408/pkg/apis/networking/types.go#L95 | ||
[pol-new]:https://github.com/kubernetes/enhancements/pull/2522 | ||
## References | ||
A related conversation in [#727][issue-727] ultimately instigated these | ||
new requirements and may be helpful to review. | ||
[issue-727]:https://github.com/kubernetes-sigs/gateway-api/issues/727 |