Skip to main content
logoTetrate Enterprise Gateway for Envoy (TEG)Version: v0.1.0

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 of ports
  • Route resources define how traffic is routed to Kubernetes Services. Envoy Gateway supports the full suite of routes that are defined by the Gateway API today: HTTPRoute, GRPCRoute, TCPRoute, UDPRoute and TLSRoute.
A Deep Dive on the K8s Gateway API

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 of Gateway 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.

Gateway is One-to-One with a set of Envoys

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.