In the evolving landscape of Kubernetes, efficient and flexible management of network traffic is essential for deploying, scaling, and securing modern applications. As organizations adopt more complex microservices architectures, the need for robust traffic control mechanisms becomes increasingly critical. This is where the Gateway API comes into play.
Gateway API is a relatively new and powerful extension to Kubernetes designed to improve how traffic routing and network policies are managed. It is a set of resources that provides more expressive and extensible tools for controlling network traffic. Unlike the traditional Ingress resource, which focuses primarily on HTTP and HTTPS routing, Gateway API offers a more modular approach, supporting multiple protocols and providing advanced capabilities that address the limitations of Ingress.
The Gateway API introduces concepts like Gateways, Routes, and GatewayClasses, which allow for a clearer separation of concerns, enabling both infrastructure administrators and application developers to work more efficiently. By supporting features such as traffic splitting, path-based routing, and more granular control over traffic policies, Gateway API offers a significant step forward in Kubernetes traffic management.
As organizations increasingly demand more advanced networking features and greater flexibility in their deployments, the Gateway API is positioned as a future-proof solution, providing a standardized and consistent way to manage traffic across a wide range of use cases. Whether you are dealing with complex microservices architectures, multi-tenant environments, or simply need more control over your traffic routing, Gateway API offers the tools to meet these needs effectively.
Ingress and Gateway API comparison
In Kubernetes, managing and directing traffic to applications is a critical aspect of deploying and maintaining services. Two primary methods for achieving this are the Ingress resource and the Gateway API. Both serve the purpose of handling inbound traffic, but they differ significantly in their design, functionality, and intended use cases. Understanding these differences is crucial for choosing the right approach for your specific needs.
Ingress
Ingress is one of the older and more established methods for managing external access to services within a Kubernetes cluster. It defines a set of rules for routing external HTTP and HTTPS traffic to backend services. An Ingress resource is used in conjunction with an Ingress Controller, which implements the routing rules defined in the Ingress resource.
Key features of ingress:
- Simplicity and ease of use
- Ingress provides a straightforward way to define routing rules using a single Kubernetes resource.
- It is suitable for basic to moderately complex routing scenarios.
- Support for HTTP and HTTPS
- Ingress is primarily designed to handle HTTP and HTTPS traffic.
- It allows for features like SSL/TLS termination, name-based virtual hosting, and URL path-based routing.
- Integration with Ingress Controllers
- Various Ingress Controllers such as NGINX, Traefik, and HAProxy can be used to implement the routing rules.
- Each Ingress Controller may offer additional features and customizations, often managed via annotations.
- Annotations for extended features
- Ingress relies heavily on annotations to extend its functionality, which can lead to inconsistencies and complexity.
- Different controllers may interpret annotations differently, affecting portability.
- Common use cases:
- Ideal for simple to moderately complex HTTP/HTTPS routing needs.
- Suitable for scenarios where ease of use and quick setup are prioritized.
Gateway API
Gateway API is a more modern and flexible approach to traffic management in Kubernetes. It addresses some of the limitations of Ingress by providing a more powerful and extensible framework. Gateway API introduces a set of new resources designed to offer greater flexibility and control over traffic routing and management.
Key features of gateway API:
- Modular and extensible design
- Gateway API introduces multiple resources such as GatewayClass, Gateway, HTTPRoute, TCPRoute, and TLSRoute.
- This modular design allows for more granular and precise control over traffic management.
- Support for multiple protocols
- In addition to HTTP and HTTPS, Gateway API supports other protocols like TCP and TLS.
- This makes it suitable for a broader range of use cases beyond simple web traffic.
- Separation of responsibilities
- Gateway API separates the concerns of infrastructure management and application development.
- Administrators can manage Gateways, while developers can define routing rules using Route resources.
- Advanced features and flexibility
- Gateway API supports advanced features such as weighted traffic splitting, traffic mirroring, and more complex routing rules.
- It provides a more consistent and standardized way to define and manage these features.
- Improved consistency and portability
- Gateway API aims to reduce the reliance on annotations and provide a more consistent API surface.
- This enhances portability across different environments and implementations.
- Common use cases
- Ideal for complex traffic management scenarios requiring advanced routing capabilities.
- Suitable for multi-tenant environments and architectures with microservices requiring fine-grained control over traffic routing.
Example: Use Gateway API with Cilium
At dbi services, we follow the best practice of using Cilium as our Kubernetes CNI (Container Network Interface). If you are not familiar with Cilium you can follow these articles from my colleagues:
- Kubernetes Networking by Using Cilium – Beginner Level
- Kubernetes Networking by Using Cilium – Intermediate Level – Network Interfaces
- Kubernetes Networking by Using Cilium – Intermediate Level – Traditional Linux Routing
- Kubernetes Networking by Using Cilium – Advanced Level – eBPF Routing
Cilium not only provides powerful networking and security capabilities but also implements several Gateway API features, such as:
- GatewayClass and Gateway support: Allowing for flexible and scalable traffic management.
- L4 and L7 traffic filtering: Enabling more granular control over traffic routing.
- Native integration with HTTPRoute, GRPCRoute, and TLSRoute: Facilitating advanced protocol support and routing capabilities.
In this example, we will demonstrate how to install Cilium with Gateway API support and set up a simple HTTPRoute to route traffic to a backend service.
Other Gateway API solutions exist, so if you’re familiar with other network tools (Traefik, Istio, Contour, …) or need to implement TCPRoute and/or UDPRoute resources, you’ll find a list of implementations in the official Gateway API documentation.
Prerequisites
According to the Cilium’s documentation, we need to add the necessary CRDs then deploy the Cilium’s Helm chart with the right options:
- Add Gateway API CRDs
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.1.0/config/crd/standard/gateway.networking.k8s.io_gatewayclasses.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.1.0/config/crd/standard/gateway.networking.k8s.io_gateways.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.1.0/config/crd/standard/gateway.networking.k8s.io_httproutes.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.1.0/config/crd/standard/gateway.networking.k8s.io_referencegrants.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.1.0/config/crd/standard/gateway.networking.k8s.io_grpcroutes.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.1.0/config/crd/experimental/gateway.networking.k8s.io_tlsroutes.yaml
- Deploy cilium on your Kubernetes with Gateway API feature
# Cilium install using Helm:
helm repo add cilium https://helm.cilium.io/
helm install cilium cilium/cilium \
--version 1.16.1 \
--namespace kube-system \
--set kubeProxyReplacement=true \
--set gatewayAPI.enabled=true
# Wait for Cilium to be healthy
cilium status --wait
/¯¯\
/¯¯\__/¯¯\ Cilium: OK
\__/¯¯\__/ Operator: OK
/¯¯\__/¯¯\ Envoy DaemonSet: disabled (using embedded mode)
\__/¯¯\__/ Hubble Relay: disabled
\__/ ClusterMesh: disabled
DaemonSet cilium Desired: 1, Ready: 1/1, Available: 1/1
Deployment cilium-operator Desired: 1, Ready: 1/1, Available: 1/1
Containers: cilium Running: 1
cilium-operator Running: 1
Cluster Pods: 14/15 managed by Cilium
HTTPRoute example:
- Create YAML definition file for the HTTP server deployment and service (http-server.yaml):
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: testgw-backend
example: http-routing
name: testgw-backend
spec:
replicas: 1
selector:
matchLabels:
app: testgw-backend
template:
metadata:
labels:
app: testgw-backend
spec:
containers:
- env:
- name: POD_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- name: NAMESPACE
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
image: gcr.io/k8s-staging-ingressconformance/echoserver:v20221109-7ee2f3e
imagePullPolicy: IfNotPresent
name: testgw-backend
resources:
requests:
cpu: 10m
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
labels:
example: http-routing
name: testgw-svc
spec:
ports:
- name: http
port: 8080
protocol: TCP
targetPort: 3000
selector:
app: testgw-backend
type: ClusterIP
- Create YAML definition file for the Gateway (gateway.yaml):
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: cilium-gateway
spec:
gatewayClassName: cilium
# Depending on your Loadbalancer strategy, precise the IP address to use
addresses:
- type: IPAddress
value: 172.22.14.96
listeners:
- allowedRoutes:
namespaces:
from: Same
name: web-gw
port: 80
protocol: HTTP
- Create YAML definition file for the HTTPRoute (httproute.yaml):
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
labels:
example: http-routing
name: testgw-route
namespace: default
spec:
hostnames:
- testgw.dbi-services.com
parentRefs:
- kind: Gateway
name: cilium-gateway
rules:
- backendRefs:
- group: ""
kind: Service
name: testgw-svc
port: 8080
weight: 1
matches:
- path:
type: PathPrefix
value: /get
- Apply the resources:
kubectl apply -f http-server.yaml
kubectl apply -f gateway.yaml
kubectl apply -f httproute.yaml
- Check your Gateway API resources
kubectl get gateway
NAME CLASS ADDRESS PROGRAMMED AGE
cilium-gateway cilium 172.22.14.96 True 9m31s
kubectl get httproute
NAME HOSTNAMES AGE
testgw-route ["testgw.dbi-services.com"] 11m
- Test an HTTP request
curl http://testgw.dbi-services.com/get
{
"path": "/get",
"host": "testgw.dbi-services.com",
"method": "GET",
"proto": "HTTP/1.1",
"headers": {
"Accept": [
"*/*"
],
"User-Agent": [
"curl/8.9.1"
]
},
"namespace": "default",
"ingress": "",
"service": "",
"pod": "testgw-backend-67d4f66b9b-jtj9s"
}
Well done ! Your Gateway API HTTPRouting is working ! 🎉
Conclusion
While both Ingress and Gateway API serve to manage external traffic in Kubernetes, they cater to different needs and use cases. Ingress is simpler and quicker to set up, making it ideal for straightforward HTTP/HTTPS routing scenarios. On the other hand, Gateway API offers a more powerful, flexible, and extensible framework suitable for advanced traffic management requirements, including support for multiple protocols and more complex routing configurations. Understanding these differences can help you make an informed decision on which approach to use for your Kubernetes deployments.