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.

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