Skip to content

Commit

Permalink
Merge pull request #1926 from keithmattix/gep-1924
Browse files Browse the repository at this point in the history
Clarify parentRef binding for Mesh
  • Loading branch information
k8s-ci-robot authored May 12, 2023
2 parents b692c69 + 10e70d1 commit 6fee7b5
Showing 1 changed file with 59 additions and 6 deletions.
65 changes: 59 additions & 6 deletions geps/gep-1426.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
## Overview

Similar to how `xRoutes` bind to `Gateways` and manage North/South traffic flows in Gateway API’s ingress use-case, it would be natural to adopt a similar model for traffic routing concerns in service mesh deployments. The purpose of this GEP is to add a mechanism to the Gateway API spec for the purpose of associating the various `xRoute` types to a service mesh and offering a model for service owners to manage traffic splitting configurations.

This GEP is intended to establish an implementable, but experimental, baseline for supporting basic service mesh traffic routing functionality through the Gateway API spec.

## Personas
Expand Down Expand Up @@ -43,11 +43,15 @@ This GEP uses the [roles and personas](https://gateway-api.sigs.k8s.io/concepts/

It is proposed that an application owner should configure traffic rules for a mesh service by configuring an `xRoute` with a Kubernetes `Service` resource as a `parentRef`.

This approach is dependent on both the "frontend" role of the Kubernetes `Service` resource as defined in [GEP-1324: Service Mesh in Gateway API](https://gateway-api.sigs.k8s.io/geps/gep-1324/#service) when used as a `parentRef` and the "backend" role of `Service` when used as a `backendRef`. It would use the Kubernetes service name to match traffic for meshes implementing "transparent proxy" functionality, but the `backendRef` endpoints would ultimately be used for the canonical IP address(es) to which traffic should be redirected by rules defined in this `xRoute`. This approach leverages the existing points of extensibility within the Gateway API spec, and would not require introducing any API changes or new resources, only defining expected behavior.
This approach is dependent on both the "frontend" role of the Kubernetes `Service` resource as defined in [GEP-1324: Service Mesh in Gateway API](https://gateway-api.sigs.k8s.io/geps/gep-1324/#service) when used as a `parentRef` and the "backend" role of `Service` when used as a `backendRef`. The conformant implementation would use the Kubernetes `Service` name to match traffic for meshes, but the `backendRef` endpoints would ultimately be used for the canonical IP address(es) to which traffic should be redirected by rules defined in this `xRoute`. This approach leverages the existing points of extensibility within the Gateway API spec, and would not require introducing any API changes or new resources, only defining expected behavior.

### Why Service?

The GAMMA initiative has been working to bring service mesh use-cases to the Gateway API spec, taking the best practices and learnings from mesh implementations and codifying them in a spec. Most mesh users are familiar with using the Kubernetes `Service` resource as the foundation for traffic routing. Generaly, this architecture makes perfect sense; unfortunately, `Service` is far too coupled of a resource. It orchestrates IP address allocation, DNS, endpoint collection and propagation, load balancing, etc. For this reason, it **cannot** be the right long-term answer for `parentRef` binding; however, it is the only feasible option that Kubernetes has for mesh implementations today. We expect this to change (indeed, we hope to be a part of that change), but in the interest of developing a spec now, we must once again lean on the `Service` resource. However, we will provide provisions to support additional resources as a `parentRef`.

## API

```
```yaml
metadata:
name: foo-route
namespace: store
Expand Down Expand Up @@ -109,11 +113,60 @@ Services supported as `backendRefs` SHOULD be consistent with expectations for N

An alternate pattern additionally supported by this approach would be to target a `Service` without selectors as the `parentRef`. This could be a clean way to create a pure routing construct and abstract a logical frontend, as traffic would resolve to a `backendRef` `Service` with selectors defined on the `HTTPRoute`, or receive a 4xx/5xx error response if no matching path or valid backend was found.

#### Multicluster support with `ServiceImport`
### `parentRef` Conformance Levels

Currently (v0.7.0), this spec only considers the `Service` resource to be under Core conformance as a `parentRef`. However, Service is not the only resource that can fulfill the frontend role. While the Gateway API spec couldn’t possibly enumerate every existing (and future) frontend-like resource, it can specify a subset of resources that implementations MUST support as parentRefs under as a part of core conformance. Meshes MAY support other implementation-specific resources as parentRefs. The spec maintainers also reserve the right to add additional resources to core conformance as the spec evolves.

#### Extended Conformance

In addition to Service, there are other optional parentRef resources that, if used by implementations, MUST adhere to the spec’s prescriptions. At the time of writing (v0.7.0), there is one resource in extended conformance: `ServiceImport` (part of the [MCS API](https://github.com/kubernetes-sigs/mcs-api), currently in alpha). The semantics of `ServiceImport` `parentRef` binding can be found in [GEP-1748](https://gateway-api.sigs.k8s.io/geps/gep-1748/) (Note: Headless `ServiceImport` is out of scope and not currently a part of the spec).

##### Why not `IPAddress`

In Kubernetes 1.27, there will be a new IPAddress resource added to networking.k8s.io/v1alpha1 as part of [KEP 1880](https://github.com/kubernetes/enhancements/tree/master/keps/sig-network/1880-multiple-service-cidrs#proposal). Naturally, it makes sense to examine whether or not this new resource makes sense as a GAMMA aware parentRef. At first glance, IPAddress seems to be an appropriate abstraction for the “frontend” role we’ve been discussing; every Kubernetes Service is accessed over the network via one of its ip addresses. Furthermore, the fact that the Service resource auto-creates an IPAddress is encouraging. However, the fact that the name of the IPAddress is simply the decimal/hex ip address and not a human-readable Service name makes the UX untenable as a spec-supported parentRef. However, `IPAddress` is NOT disallowed; implementations may use it if they wish.

#### Implementation-specific `parentRef`s

If mesh implementations wish to enable an implementation-specific resource as a parentRef, they may do so as long as that resource meets certain conditions. Recall that the frontend role of a (generic) service is how one calls the service. In the service mesh transparent proxy context, the frontend role (and parentRef by extension) is effectively the matching mechanism for the specified route. For the Service parentRef, this means that the mesh should apply a particular xRoute’s configuration if the destination ip address for a given connection is the ClusterIP of that parentRef Service. If a mesh wishes to use an implementation-specific resource for parentRef, that resource MUST contain layer-appropriate information suitable for traffic matching (e.g. no Host header capture in TCPRoute). For example, the following HTTPRoute with an Istio `ServiceEntry` as a parentRef would be a valid implementation-specific reference:

```yaml
apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
name: internal-svc-httpbin
namespace : egress
spec:
hosts:
- example.com
exportTo:
- "."
location: MESH_INTERNAL
ports:
- number: 80
name: http
protocol: HTTP
resolution: DNS
---
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: mongo-internal
spec:
parentRefs:
- kind: ServiceEntry
group: networking.istio.io/v1beta1
name: internal-svc-httpbin
namespace: egress
sectionName: http # referencing the port name
rules:
- backendRefs:
- name: internal-example
port: 80
```

`ServiceImport` resources allocate a virtual IP in the cluster, so MAY be allowed as a `parentRef`.
##### `Gateways`

`ServiceImport` would remain a valid backend option for `xRoute` resources (but _not_ currently a requirement for core conformance), and could be specified alongside a `Service` `backendRef` to split traffic across clusters within a `ClusterSet` (as defined in the [Multi-cluster Service (MCS) APIs project](https://github.com/kubernetes-sigs/mcs-api)). This could be a way to solve the need described in [A use case for using Gateway APIs in Multi-Cluster](https://docs.google.com/document/d/1bjr0uAVMmEtTX4mpU_aGXXapQFsEz_Qt0OnDoVswEEI/edit).
There has been much discussion around cluster local Gateways (i.e. Gateways not associated with a traditional load balancer). While there are various potential UX impairments (e.g. what’s the difference between a GAMMA HTTPRoute with a Gateway parentRef and an ingress implementation’s HTTPRoute?), there is no technical reason why a Gateway cannot be a valid GAMMA parentRef if an implementation wishes to do so.

### Route types

Expand Down

0 comments on commit 6fee7b5

Please sign in to comment.