Skip to content

Commit

Permalink
Documenting Route attachment for v1alpha2
Browse files Browse the repository at this point in the history
  • Loading branch information
robscott committed Aug 10, 2021
1 parent e09be1c commit 143cfaf
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 132 deletions.
193 changes: 68 additions & 125 deletions site-src/v1alpha2/concepts/api-overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ section in the Security model for details.

## Resource model

> Note: Resources will initially live in the `gateway.networking.k8s.io` API group as
> Custom Resource Definitions (CRDs). Unqualified resource names will implicitly
> be in this API group.
!!! note
Gateway API Resources live in the `gateway.networking.k8s.io` API group as
Custom Resource Definitions (CRDs). Unqualified resource names will
implicitly be in this API group.

There are three main types of objects in our resource model:

Expand Down Expand Up @@ -67,44 +68,32 @@ GatewayClass.

As the Gateway spec captures user intent, it may not contain a complete
specification for all attributes in the spec. For example, the user may omit
fields such as addresses, TLS settings. This allows the controller
managing the GatewayClass to provide these settings for the user, resulting in a
more portable spec. This behaviour will be made clear using the GatewayClass
Status object.
fields such as addresses, TLS settings. This allows the controller managing the
GatewayClass to provide these settings for the user, resulting in a more
portable spec. This behaviour will be made clear using the GatewayClass Status
object.

A Gateway MAY contain one or more *Route references which serve to direct
traffic for a subset of traffic to a specific service.*

### {HTTP,TCP,Foo}Route
### Routes

Route objects define protocol-specific rules for mapping requests from a Gateway
to Kubernetes Services.

`HTTPRoute` and `TCPRoute` are currently the only defined Route objects.
Additional protocol-specific Route objects may be added in the future.

### Route binding

When a Route binds to a Gateway it represents configuration that is applied on
the Gateway that configures the underlying load balancer or proxy. How and which
Routes bind to Gateways is controlled by the resources themselves. Route and
Gateway resources have built-in controls to permit or constrain how they select
each other. This is useful for enforcing organizational policies for how Routes
are exposed and on which Gateways. Consider the following example:

> A Kubernetes cluster admin has deployed a Gateway “shared-gw” in the “Infra”
> Namespace to be used by different application teams for exposing their
> applications outside the cluster. Teams A and B (in Namespaces “A” and “B”
> respectively) bind their Routes to this Gateway. They are unaware of each other
> and as long as their Route rules do not conflict with each other they can
> continue operating in isolation. Team C has special networking needs (perhaps
> performance, security, or criticality) and they need a dedicated Gateway to
> proxy their application to the outside world. Team C deploys their own Gateway
> “dedicated-gw” in the “C” Namespace that can only be used by apps in the "C"
> Namespace.
to Kubernetes Services. There are 4 Route resources included with the Gateway
API:

<!-- source: https://docs.google.com/presentation/d/1neBkFDTZ__vRoDXIWvAcxk2Pb7-evdBT6ykw_frf9QQ/edit?usp=sharing -->
![route binding](/images/gateway-route-binding.png)
* HTTPRoute
* TCPRoute
* TLSRoute
* UDPRoute

Additional Route resources may be added in the future.

## Attaching Routes to Gateways

When a Route attaches to a Gateway it represents configuration that is applied
on the Gateway that configures the underlying load balancer or proxy. How and
which Routes bind to Gateways is controlled by the resources themselves. Route
and Gateway resources have built-in controls to permit or constrain how they are
attached. This is useful for enforcing organizational policies for how Routes
are exposed and on which Gateways.

There is a lot of flexibility in how Routes can bind to Gateways to achieve
different organizational policies and scopes of responsibility. These are
Expand All @@ -119,96 +108,50 @@ different relationships that Gateways and Routes can have:
a single Route to control application exposure simultaneously across different
IPs, load balancers, or networks.

*In summary, Gateways select Routes and Routes control their exposure. When a
Gateway selects a Route that allows itself to be exposed, then the Route will
bind to the Gateway. When Routes are bound to a Gateway it means their
collective routing rules are configured on the underlying load balancers or
proxies that are managed by that Gateway. Thus, a Gateway is a logical
representation of a networking data plane that can be configured through
Routes.*

#### Route Selection

A Gateway selects routes based on the Route metadata, specifically the kind,
namespace, and labels of Route resources. Routes are actually bound to specific
listeners within the Gateway so each listener has a `listener.routes` field
which selects Routes by one or more of the following criterea:

- **Label** - A Gateway can select Routes via labels that exist on the
resource (similar to how Services select Pods via Pod labels).
- **Kind** - A Gateway listener can only select a single type of Route
resource. This could be an HTTPRoute, TCPRoute, or a custom Route type.
- **Namespace** - A Gateway can also control from which Namespaces Routes can be
selected via the `namespaces.from` field. It supports three possible values:
- `SameNamespace` is the default option. Only Routes in the same namespace
as this Gateway will be selected.
- `All` will select Routes from all Namespaces.
- `Selector` means that Routes from a subset of Namespaces selected by a
Namespace label selector will be selected by this Gateway. When `Selector`
is used then the `listeners.routes.namespaces.selector` field can be used
to specify label selectors. This field is not supported with `All` or
### Example

A Kubernetes cluster admin has deployed a Gateway `shared-gw` in the `Infra`
Namespace to be used by different application teams for exposing their
applications outside the cluster. Teams A and B (in Namespaces `A` and `B`
respectively) bind their Routes to this Gateway. They are unaware of each
other and as long as their Route rules do not conflict with each other they
can continue operating in isolation. Team C has special networking needs
(perhaps performance, security, or criticality) and they need a dedicated
Gateway to proxy their application to the outside world. Team C deploys their
own Gateway `dedicated-gw` in the `C` Namespace that can only be used by apps
in the `C` Namespace.

<!-- source: https://docs.google.com/presentation/d/1neBkFDTZ__vRoDXIWvAcxk2Pb7-evdBT6ykw_frf9QQ/edit?usp=sharing -->
![route binding](/images/gateway-route-binding.png)

### How it Works

The following is required for a Route to be attached to a Gateway:

1. The Route needs an entry in its `parentRefs` field referencing the Gateway.
2. At least one listener on the Gateway needs to allow this attachment.

Each Gateway listener can restrict which Routes can be attached with the
following mechanisms:

1. **Hostname:** When the `hostname` field on a listener is set, attached Routes
that specify a `hostnames` field must have at least one overlapping value.
2. **Namespaces:** The `namespaces` field on a listener can be used to restrict
where Routes may be attached from. The `namespaces.from` field supports the
following values:
* `SameNamespace` is the default option. Only Routes in the same namespace
as this Gateway may be attached.
* `All` will allow Routes from all Namespaces to be attached.
* `Selector` means that Routes from a subset of Namespaces selected by a
Namespace label selector may be attached to this Gateway. When `Selector`
is used, the `listeners.routes.namespaces.selector` field must be used to
specify label selectors. This field is not supported with `All` or
`SameNamespace`.
3. **Kinds:** The `kinds` field on a listener can be used to restrict the kinds
of Routes that may be attached.

The below Gateway will select all HTTPRoute resources with the `expose:
prod-web-gw` across all Namespaces in the cluster.

```
kind: Gateway
...
spec:
listeners:
- routes:
kind: HTTPRoute
selector:
matchLabels:
expose: prod-web-gw
namespaces:
from: All
```

#### Route Exposure

Routes can determine how they are exposed through Gateways. The `gateways.allow`
field supports three values:

- `All` is the default value if none is specified. This leaves all binding
to the Route label and Namespace selectors on the Gateway.
- `SameNamespace` only allows this Route to bind with Gateways from the
same Namespace.
- `FromList` allows an explicit list of Gateways to be specifiied that a
Route will bind with. `gateways.gatewayRefs` is only supported with this option.

The following `my-route` Route selects only the `foo-gateway` in the
`foo-namespace` and will not be able to bind with any other Gateways. Note that
`foo-gateway` is in a different Namespace. If the `foo-gateway` allows
cross-Namespace binding and also selects this Route then `my-route` will bind to
it.

```yaml
kind: HTTPRoute
metadata:
name: my-route
namespace: bar-namespace
spec:
gateways:
allow: FromList
gatewayRefs:
- name: foo-gateway
namespace: foo-namespace
```
Note that Gateway and Route binding is bi-directional. This means that both
resources must select each other for them to bind. If a Gateway has Route label
selectors that do not match any existing Route then nothing will bind to it even
if a Route's `spec.gateways.allow = All`. Similarly, if a Route references a
specific Gateway, but that Gateway is not selecting the Route's Namespace, then
they will not bind. A binding will only take place if both resources select each
other.

It may not always be apparent from the resource specifications which Gateways
and Routes are bound, but binding can be determined from the resource status.
The [Route status](/api-types/httproute#routestatus) will list all of the Gateways that
a Route is bound to and any relevant conditions for the binding.
If none of the above are specified, a Gateway listener will trust Routes
attached from the same namespace that support the listener protocol.

### Combined types

Expand Down
11 changes: 4 additions & 7 deletions site-src/v1alpha2/concepts/security-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,14 +96,11 @@ configuration](https://github.com/open-policy-agent/gatekeeper-library/pull/24)
that could be used for this.

## Route Namespaces
Gateway API allow Gateways to select Routes across multiple Namespaces.
Gateway API enables Routes to be attached to Gateways from different Namespaces.
Although this can be remarkably powerful, this capability needs to be used
carefully. Gateways include a `RouteNamespaces` field that allows selecting
multiple namespaces with a label selector. By default, this is limited to Routes
in the same namespace as the Gateway. Additionally, Routes include a `Gateways`
field that allows them to restrict which Gateways use them. If the Gateways
field is not specified (i.e. its empty), then the Route will default to allowing
selection by Gateways in the same namespace.
carefully. Gateway Listeners include a `namespaces` field that can allow Routes
to be attached from additional namespaces. By default, this is limited to Routes
in the same namespace as the Gateway.

## Controller Requirements
To be considered conformant with the Gateway API spec, controllers need to:
Expand Down

0 comments on commit 143cfaf

Please sign in to comment.