Gateway API
The Kubernetes Gateway API aims to model service networking in Kubernetes with a role-oriented API. It provides three primary APIs, on top of Kubernetes' existing Service
:
GatewayClass
defines a type of load balancing implementation, and allows deployment-specific templates (e.g. to configure all Envoys of that class to request more RAM by default)- A
Gateway
defines a Deployment of Envoys that listen on a specific set ofports
Route
resources define how traffic is routed to KubernetesServices
. Envoy Gateway supports the full suite of routes that are defined by the Gateway API today:HTTPRoute
,GRPCRoute
,TCPRoute
,UDPRoute
andTLSRoute
.
See the Gateway API primer on k8s.io for a detailed overview of the API as well as reference docs. In this article we're hoping to pull the most relevant parts for a practitioner together into one page.
GatewayClass
The GatewayClass
allows for marking kinds of Envoy deployments. For example, you might create two GatewayClasses
, public
and private
, for load balancers that are allowed to accept traffic from the public internet or only private networks. (Actually implementing that policy is outside the scope of the GatewayClass itself.) Another example is using GatewayClasses
k8s
and ec2
to represent load balancers deployed on Kubernetes or AWS EC2. It's typically a resource owned by the infrastructure provider.
Envoy Gateway defines an EnvoyProxy
resource to configure how Envoys should be deployed at runtime (e.g. how many replicas, what memory requests, etc). GatewayClass
is where we point to an EnvoyProxy
configuration; all Envoys that are members of the GatewayClass
are instantiated with that config.
A typical GatewayClass
that references looks like:
apiVersion: gateway.networking.k8s.io/v1beta1
kind: GatewayClass
metadata:
name: envoy-gateway
spec:
controllerName: gateway.envoyproxy.io/gatewayclass-controller
Envoy Gateway only supports a single GatewayClass
today. To support multiple GatewayClasses
you should deploy multiple Envoy Gateway instances partitioned by namespace.
Gateway
A Gateway
does three things:
- Defines how a set of Envoys will serve traffic: what ports, protocols, and certificates they'll serve.
- References a
GatewayClass
so the system knows what type ofGateway
this is intended to be. - Instructs Envoy Gateway to deploy a set of Envoys configured to serve the ports and protocols defined in the
Gateway
.
Shared vs Dedicated Gateways
Gateways
are usually owned and managed by the platform team in an organization. In a shared Gateway
model, it's expected that the platform team would have ultimate approval for any app-team changes to configuration attached to a Gateway
. An ingress-per-team model — with a Gateway
resource for each team — removes this review bottleneck, at the expense of managing more independent deployments of Envoy.
A deployment of a set of Envoys in the infrastructure is one-to-one with a Gateway
definition. If you want an ingress deployment shared by all applications in your cluster, you should define a single Gateway
resource. If you want an independent ingress per team, you should expect to define many Gateway
resources.
For more detail see the official Envoy Gateway documentation on its deployment model.
A typical Gateway
serving HTTP and HTTPS traffic looks like:
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
name: basic-gateway
spec:
gatewayClassName: envoy-gateway
listeners:
- name: https
protocol: HTTPS
port: 443
hostname: "first.example.com"
tls:
mode: Terminate
certificateRefs:
kind: Secret
name: example-cert
- name: https
protocol: HTTPS
port: 443
hostname: "*.example.com"
tls:
mode: Terminate
certificateRefs:
kind: Secret
name: wildcard-cert
- name: http
protocol: HTTP
port: 80
Envoy Gateway supports more advanced cases like certificate per hostname, serving certificates for wildcard hostnames, TLS SNI passthrough, and routing non-HTTP protocols as well.
Routes
The Gateway API defines a Route
object per protocol type; today Envoy Gateway supports HTTPRoute
, GRPCRoute
, TCPRoute
, UDPRoute
and TLSRoute
.
A typical route for a simple case like performing an HTTPS redirect and serving the backend
application:
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: https-redirect-to-backend
spec:
parentRefs:
- name: basic-gateway
hostnames:
- "*.example.com"
rules:
- filters:
- type: RequestRedirect
requestRedirect:
scheme: https
statusCode: 301
port: 443
backendRefs:
- name: backend
port: 3000
Envoy Gateway supports the full range of Envoy's routing functionality, which means that you can do things like:
- Rewrite URL hosts and paths
- Add, remove, and modify request or response headers
- Make routing decisions per request, based on IP 5-tuple, request headers, or percentage
- Route gRPC, TCP, UDP, and TLS traffic in addition to HTTP
The example HTTPRoute
above used the RequestRedirect
filter to perform an HTTP 301
redirect to enforce HTTPS. See the How To topics on HTTP routing for an overview of several filters.
Filters
Functionality beyond basic matching is configured via Filters
. Filters are the Gateway API's extensibility point for incorporating functionality not covered by the basic API. You can see a list of the basic Core
and Extended
filters on k8s.io. Some filters must be implemented for conformance to the Gateway API, like the RequestHeaderModifier
and RequestRedirect
filters, while others are entirely at the discretion of the Gateway API implementation. Today Envoy Gateway implements all of the Core
and Extended
filters.
Envoy Gateway goes further and implements a few custom APIs, today for JWT authentication and rate limiting.
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: RateLimitFilter
metadata:
name: ratelimit-x-user-id
spec:
type: Global
global:
rules:
- clientSelectors:
- headers:
- name: x-user-id
type: distinct
limit:
requests: 10
unit: Minute
---
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: example-com-ratelimit-rewrite
spec:
parentRefs:
- name: basic-gateway
hostnames:
- "*.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /v2beta1
filters:
- type: URLRewrite
urlRewrite:
path:
type: ReplacePrefixMatch
replacePrefixMatch: /v2
- type: ExtensionRef
extensionRef:
group: gateway.envoyproxy.io
kind: RateLimitFilter
name: ratelimit-x-user-id
backendRefs:
- name: backend
port: 3000
Multiple filters can attached to any rule
. The example above uses the core URLRewrite
filter to rewrite requests from v2beta1
to v2
, as well as configuring global rate limiting per user. See the rate limiting or request authentication How To's for more involved examples of using filters, including Envoy Gateway's extended filters.