Envoy Gateway in Kubernetes: Complete Guide with Gateway API

In the modern cloud-native ecosystem, managing network traffic efficiently and securely is crucial. Technologies like Envoy Gateway and Gateway API have emerged to simplify and standardize traffic management in Kubernetes.

Envoy Gateway Thumbnail
Envoy Gateway Thumbnail

What is Envoy Gateway?

Envoy gateway is a high-performance, Kubernetes-native gateway built on top of the popular Envoy Proxy. Envoy is a powerful proxy designed for cloud-native applications, providing load balancing, traffic routing, security features and observability.

Envoy Gateway extends Envoy's capabilities to act as a modern gateway, allowing you to securely expose your Kubernetes services to the internet. It integrates heavily with Kubernetes APIs, making it easy to manage ingress traffic with Kubernetes configuration files.

Key benefits of Envoy Gateway:

  • High performance and scalability
  • Supports the Kubernetes Gateway API
  • Rich observability with metrics, logs and tracing
  • Advanced traffic control and security features
  • Extensible through Envoy filters and Plugins

What is the Kubernetes Gateway API

The Gateway API is designed to standardize ingress and routing across Kubernetes clusters. It offers a more expressive and extensible API than the traditional Ingress resource, designed to better support modern networking use cases.

Gateway API introduces several new resources such as:

  • GatewayClass: Declares which controller manages Gateways and how those Gateways are configured and deployed
  • Gateway: Declares where and how traffic enters the cluster (ports, hostnames...)
  • HTTPRoute/GRPCRoute/TCPRoute: Define how traffic should be routed to backends based on path, headers, host, etc

Compared to Ingress, the Gateway API supports advanced routing, richer protocol support and improved lifecycle management.


Why use Envoy Gateway and Gateway API

Combining Envoy Gateway and Gateway API brings the power of Envoy's high-performance proxy with the flexibility and expressiveness of Gateway API. This combination helps solve many limitations of Kubernetes Ingress, offering:

  • Better support for HTTP, HTTPS, TCP and UDP protocols
  • More granular traffic routing and policy enforcement
  • Native integration with Envoy features and filters
  • Easier evolution and extensibility as Gateway API develops

Setting up Envoy Gateway with Gateway API in Kubernetes

Prerequisites

  • A running Kubernetes cluster
  • kubectl CLI configured to access your Cluster
  • Helm installed

Installation

Install the Envoy Gateway and Gateway API CRDs

helm install eg oci://docker.io/envoyproxy/gateway-helm --version v1.4.1 -n envoy-gateway-system --create-namespace

Wait for the Envoy Gateway to become Available

kubectl wait --timeout=5m -n envoy-gateway-system deployment/envoy-gateway --for=condition=Available

Create the GatewayClass

Define a gateway class that tells Kubernetes to use Envoy Gateway as the Implementation

apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: envoy-gateway
spec:
  controllerName: gateway.envoyproxy.io/gatewayclass-controller

gatewayclass.yaml

Apply it

kubectl apply -f gatewayclass.yaml

Create the Gateway

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: example-gateway
  namespace: default
spec:
  # The gateway class name we created before
  gatewayClassName: envoy-gateway
  listeners:
    - name: http
      protocol: HTTP
      port: 80

gateway.yaml

Apply it

kubectl apply -f gateway.yaml

What this creates

A few moments after creating the Gateway, if you check the envoy-gateway-system namespace for it's deployments, pods and services you will notice that the example-gateway was created

kubectl get all -n envoy-gateway-system
NAME                                                          READY   STATUS    RESTARTS   AGE
pod/envoy-default-example-gateway-9b7aba4f-5d8bd8f88b-nv6rl   2/2     Running   0          4m20s
pod/envoy-gateway-7db8c65f6c-w5xf6                            1/1     Running   0          12m

NAME                                             TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                                            AGE
service/envoy-default-example-gateway-9b7aba4f   LoadBalancer   10.103.27.138   172.16.0.1    80:32502/TCP                                       4m20s
service/envoy-gateway                            ClusterIP      10.101.114.12   <none>        18000/TCP,18001/TCP,18002/TCP,19001/TCP,9443/TCP   12m

NAME                                                     READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/envoy-default-example-gateway-9b7aba4f   1/1     1            1           4m20s
deployment.apps/envoy-gateway                            1/1     1            1           12m

NAME                                                                DESIRED   CURRENT   READY   AGE
replicaset.apps/envoy-default-example-gateway-9b7aba4f-5d8bd8f88b   1         1         1       4m20s
replicaset.apps/envoy-gateway-7db8c65f6c                            1         1         1       12m

If you see an output similar to this, you will know that everything has gone well.

Please take note of the LoadBalancer IP. This is the IP that you will be able to use to access your Gateway.

Create the HTTPRoute

This assumes you have a service exposed via ClusterIP in the default namespace, named my-service and it exposes port 80

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: example-route
  namespace: default
spec:
  parentRefs:
      # This references the Gateway we created before
    - name: example-gateway
  rules:
    - matches:
          # When the prefix is /
        - path:
            type: PathPrefix
            value: /
      # Redirect to my-service:80
      backendRefs:
        - name: my-service
          port: 80

http-route.yaml

Apply it

kubectl apply -f http-route.yaml

Accessing the Service

As mentioned before, you can find the Load Balancer of the Gateway using

kubectl get services -n envoy-gateway-system

In this case, the Load Balancer IP is 172.16.0.1.

By visiting that endpoint, you will be able to access your service now!

curl 172.16.0.1

Happy Coding! 🙌

Teardown

Delete the resources

kubectl -n default delete httproute example-route
kubectl -n default delete gateway example-gateway
kubectl delete gatewayclass envoy-gateway

Uninstall Envoy Gateway and the Gateway API resources

helm uninstall eg -n envoy-gateway-system

Subscribe to Kosy.Space

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
[email protected]
Subscribe