Tutorial: Getting Started with the Cilium Gateway API

Gateway API support has landed on Cilium! Gateway API is the long term replacement for Kubernetes Ingress and provides operators a role-based, portable and extensible model to route traffic into your clusters.
In this blog post, we will walk you through how to install, configure and manage the Cilium Gateway API for a number of use cases. If you would like to understand the “what” and the “why” of the Cilium Gateway API, head over to that post.
This post will focus on the “how”.
If you would rather do than read, head to the Cilium Gateway API lab instead.
Installing Cilium with Gateway API
In our environment, we start with a kind-based Kubernetes cluster. You can use a configuration such as simple as this one below (note the disableDefaultCNI: true
as we will be installing Cilium instead of the default CNI):
---
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: worker
networking:
disableDefaultCNI: true
EOF
Save this configuration and deploy it (for example, with kind create cluster --config kind-config.yaml
).
Before we install Cilium with Gateway API, we need to make sure we install the Gateway API CRDs prior to the Cilium install (Gateway API is a Custom Resource Definition (CRD) based API so you’ll need to install the CRDs onto a cluster to use the API):
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v0.5.1/config/crd/standard/gateway.networking.k8s.io_gatewayclasses.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v0.5.1/config/crd/standard/gateway.networking.k8s.io_gateways.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v0.5.1/config/crd/standard/gateway.networking.k8s.io_httproutes.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v0.5.1/config/crd/experimental/gateway.networking.k8s.io_referencegrants.yaml
You can check the CRDs have been installed with the following command:
root@server:~# kubectl get crd gatewayclasses.gateway.networking.k8s.io
kubectl get crd gateways.gateway.networking.k8s.io
kubectl get crd httproutes.gateway.networking.k8s.io
kubectl get crd referencegrants.gateway.networking.k8s.io
NAME CREATED AT
gatewayclasses.gateway.networking.k8s.io 2023-03-09T13:39:22Z
NAME CREATED AT
gateways.gateway.networking.k8s.io 2023-03-09T13:39:22Z
NAME CREATED AT
httproutes.gateway.networking.k8s.io 2023-03-09T13:39:23Z
NAME CREATED AT
referencegrants.gateway.networking.k8s.io 2023-03-09T13:39:23Z
We can now go ahead and deploy Cilium. We’ve talked about the many ways to deploy Cilium in a previous post. This time, let’s use Helm. Notice the main requirement for Gateway API to work: Cilium must be configured with kubeProxyReplacement
set to partial
or strict
.
helm repo add cilium https://helm.cilium.io
helm upgrade --install cilium cilium/cilium --version 1.13.0 --namespace kube-system --set kubeProxyReplacement=strict --set gatewayAPI.enabled=true
Let’s double check it was successfully set up:
root@server:~# cilium config view | grep "enable-gateway-api"
enable-gateway-api true
enable-gateway-api-secrets-sync true
To access the service that will be exposed via the Gateway API, we need to allocate an external IP address. When a Gateway is created, an associated Kubernetes Services of the type LoadBalancer is created. When using a managed Kubernetes Service like EKS, AKS or GKE, the LoadBalancer is assigned an IP (or DNS name) automatically. For private cloud or for home labs, we need another tool – such as MetalLB below – to allocate an IP Address and to provide L2 connectivity (as in – advertising to said IP to the network with gratuitous ARPs). Note that Cilium itself provides Load-Balancer IP Address Management support but not Layer 2 connectivity (that is a work-in-progress).
KIND_NET_CIDR=$(docker network inspect kind -f '{{(index .IPAM.Config 0).Subnet}}')
METALLB_IP_START=$(echo ${KIND_NET_CIDR} | sed "s@0.0/16@255.200@")
METALLB_IP_END=$(echo ${KIND_NET_CIDR} | sed "s@0.0/16@255.250@")
METALLB_IP_RANGE="${METALLB_IP_START}-${METALLB_IP_END}"
cat << EOF > metallb_values.yaml
configInline:
address-pools:
- name: default
protocol: layer2
addresses:
- ${METALLB_IP_RANGE}
EOF
helm install --namespace metallb-system --create-namespace \
--repo https://metallb.github.io/metallb metallb metallb \
--version 0.12.1 --values metallb_values.yaml
What is a GatewayClass and a Gateway?
Before we actually start routing traffic into the cluster, we should explain what these CRDs were and why they were required.
If the CRDs have been deployed beforehand, a GatewayClass will be deployed by Cilium during its installation (assuming the Gateway API option has been selected).
Let’s verify that a GatewayClass has been deployed and accepted:
root@server:~# kubectl get gatewayclasses.gateway.networking.k8s.io
NAME CONTROLLER ACCEPTED AGE
cilium io.cilium/gateway-controller True 13m
The GatewayClass
is a type of Gateway that can be deployed: in other words, it is a template. This is done in a way to let infrastructure providers offer different types of Gateways. Users can then choose the Gateway they like.
For instance, an infrastructure provider may create two GatewayClasses
named internet
and private
for two different purposes and possibly with different features: one to proxy Internet-facing services and one for private internal applications.
In our case, we will instantiate Cilium Gateway API (io.cilium/gateway-controller
).
HTTP Routing
Let’s now deploy an application and set up GatewayAPI HTTPRoutes
to route HTTP traffic into the cluster. We will use bookinfo as a sample application.
This demo set of microservices provided by the Istio project consists of several deployments and services:
- 🔍 details
- ⭐ ratings
- ✍ reviews
- 📕 productpage
We will use several of these services as bases for our Gateway APIs.
Deploy an application
Let’s deploy the sample application in the cluster.
root@server:~# kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.12/samples/bookinfo/platform/kube/bookinfo.yaml
service/details created
serviceaccount/bookinfo-details created
deployment.apps/details-v1 created
service/ratings created
serviceaccount/bookinfo-ratings created
deployment.apps/ratings-v1 created
service/reviews created
serviceaccount/bookinfo-reviews created
deployment.apps/reviews-v1 created
deployment.apps/reviews-v2 created
deployment.apps/reviews-v3 created
service/productpage created
serviceaccount/bookinfo-productpage created
deployment.apps/productpage-v1 created
Check that the application is properly deployed:
root@server:~# kubectl get pods
NAME READY STATUS RESTARTS AGE
details-v1-586577784f-nr5t2 1/1 Running 0 61s
productpage-v1-589b848cc9-prrnh 1/1 Running 0 61s
ratings-v1-679fc7b4f-g48xz 1/1 Running 0 61s
reviews-v1-7b76665ff9-6g7fq 1/1 Running 0 61s
reviews-v2-6b86c676d9-v65k9 1/1 Running 0 61s
reviews-v3-b77c579-pqmgl 1/1 Running 0 61s
You should see multiple pods being deployed in the default
namespace.
Notice that with Cilium Service Mesh, there is no Envoy sidecar created alongside each of the demo app microservices. With a sidecar implementation, the output would show 2/2 READY
: one for the microservice and one for the Envoy sidecar.
Have a quick look at the Services deployed:
root@server:~# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
details ClusterIP 10.96.41.65 <none> 9080/TCP 2m3s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 11m
productpage ClusterIP 10.96.147.97 <none> 9080/TCP 2m3s
ratings ClusterIP 10.96.105.89 <none> 9080/TCP 2m3s
reviews ClusterIP 10.96.149.14 <none> 9080/TCP 2m3s
Note these Services are only internal-facing (ClusterIP
) and therefore there is no access from outside the cluster to these Services.
Deploy the Gateway and the HTTPRoutes
Before deploying the Gateway and HTTPRoutes, let’s review the configuration we’re going to use. Let’s review it section by section:
spec:
gatewayClassName: cilium
listeners:
- protocol: HTTP
port: 80
name: web-gw
allowedRoutes:
namespaces:
from: Same
First, note in the Gateway
section that the gatewayClassName
field uses the value cilium
. This refers to the Cilium GatewayClass
previously configured.
The Gateway will listen on port 80
for HTTP traffic coming southbound into the cluster.
The allowedRoutes
is here to specify the namespaces from which Routes may be attached to this Gateway. Same
means only Routes in the same namespace may be used by this Gateway.
Note that, if we were to use All
instead of Same
, we would enable this gateway to be associated with routes in any namespace and it would enable us to use a single gateway across multiple namespaces that may be managed by different teams.
We could specify different namespaces in the HTTPRoutes
– therefore, for example, you could send the traffic to https://acme.com/payments
in a namespace where a payment app is deployed and https://acme.com/ads
in a namespace used by the ads team for their application.
Let’s now review the HTTPRoute
manifest. HTTPRoute
is a GatewayAPI type for specifiying routing behaviour of HTTP requests from a Gateway listener to a Kubernetes Service.
It is made of Rules to direct the traffic based on your requirements.
This first Rule is essentially a simple L7 proxy route: for HTTP traffic with a path starting with /details
, forward the traffic over to the details
Service over port 9080.
rules:
- matches:
- path:
type: PathPrefix
value: /details
backendRefs:
- name: details
port: 9080
The second rule is similar but it’s leveraging different matching criteria.
If the HTTP request has:
- a HTTP header with a name set to
magic
with a value offoo
, AND - the HTTP method is “GET”, AND
- the HTTP query param is named
great
with a value ofexample
,
Then the traffic will be sent to theproductpage
service over port 9080.
rules:
- matches:
- headers:
- type: Exact
name: magic
value: foo
queryParams:
- type: Exact
name: great
value: example
path:
type: PathPrefix
value: /
method: GET
backendRefs:
- name: productpage
port: 9080
As you can see, you can deploy sophisticated L7 traffic rules that are consistent. With Ingress API, annotations were often required to achieve such routing goals and that created inconsistencies from one Ingress controller to another.
One of the benefits of these new APIs is that the Gateway API is essentially split into separate functions – one to describe the Gateway and one for the Routes to the back-end services. By splitting these two functions, it gives operators the ability to change and swap gateways but keep the same routing configuration.
In other words: if you decide you want to use a different Gateway API controller instead, you will be able to re-use the same manifest.
Let’s now deploy the Gateway and the HTTPRoute:
kubectl apply -f https://raw.githubusercontent.com/cilium/cilium/1.13.0/examples/kubernetes/gateway/basic-http.yaml
Let’s now look at the Service created by the Gateway:
root@server:~# kubectl get svc cilium-gateway-my-gateway
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
cilium-gateway-my-gateway LoadBalancer 10.96.1.63 172.18.255.201 80:31033/TCP 12s
You will see a LoadBalancer
service named cilium-gateway-my-gateway
which was created for the Gateway API. MetalLB will automatically provision an IP address for it.
The same external IP address is also associated to the Gateway:
root@server:~# kubectl get gateway
NAME CLASS ADDRESS READY AGE
my-gateway cilium 172.18.255.201 True 61s
Let’s retrieve this IP address:
root@server:~# GATEWAY=$(kubectl get gateway my-gateway -o jsonpath='{.status.addresses[0].value}')
echo $GATEWAY
172.18.255.201
HTTP Path matching
Let’s now check that traffic based on the URL path is proxied by the Gateway API.
Because of the path starts with /details
, this traffic will match the first rule and will be proxied to the details
Service over port 9080. The curl
request is successful:
root@server:~# curl --fail -s http://$GATEWAY/details/1 | jq
{
"id": 1,
"author": "William Shakespeare",
"year": 1595,
"type": "paperback",
"pages": 200,
"publisher": "PublisherA",
"language": "English",
"ISBN-10": "1234567890",
"ISBN-13": "123-1234567890"
}
If you enable Hubble (either during the Cilium installation or later on with cilium hubble enable
), you can track the flows of this particular HTTP transaction. Note how you can filter flows based on the HTTP Path.
root@server:~# hubble observe --http-path "/details"
Mar 15 10:37:23.000: 172.18.0.1:44128 (world) -> default/cilium-gateway-my-gateway:80 (world) http-request FORWARDED (HTTP/1.1 GET http://172.18.255.201/details/1)
Mar 15 10:37:23.002: 172.18.0.1:44128 (world) <- default/cilium-gateway-my-gateway:80 (world) http-response FORWARDED (HTTP/1.1 200 2ms (GET http://172.18.255.201/details/1))
HTTP Header Matching
This time, we will route traffic based on HTTP parameters like header values, method and query parameters.
rules:
- matches:
- headers:
- type: Exact
name: magic
value: foo
queryParams:
- type: Exact
name: great
value: example
path:
type: PathPrefix
value: /
method: GET
backendRefs:
- name: productpage
port: 9080
With curl
, we can specify the headers values and query parameters to match this particular rule above:
root@server:~# curl -v -H 'magic: foo' http://"$GATEWAY"\?great\=example
* Trying 172.18.255.201:80...
* Connected to 172.18.255.201 (172.18.255.201) port 80 (#0)
> GET /?great=example HTTP/1.1
> Host: 172.18.255.201
> User-Agent: curl/7.81.0
> Accept: */*
> magic: foo
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
[Output truncated for brevity]
The curl
query is successful and returns a successful 200
code and a verbose HTML reply.
Likewise, Hubble lets you visualize and filter traffic based on some HTTP values, such as the method (GET
, POST
, etc…) or the status code (200
, 404
, etc…):
root@server:~# hubble observe --http-method GET
Mar 15 10:51:46.364: 172.18.0.1:44134 (world) -> default/cilium-gateway-my-gateway:80 (world) http-request FORWARDED (HTTP/1.1 GET http://172.18.255.201/?great=example)
Mar 15 10:51:46.374: 172.18.0.1:44134 (world) <- default/cilium-gateway-my-gateway:80 (world) http-response FORWARDED (HTTP/1.1 200 10ms (GET http://172.18.255.201/?great=example))
root@server:~# hubble observe --http-status 200
Mar 15 10:51:46.374: 172.18.0.1:44134 (world) <- default/cilium-gateway-my-gateway:80 (world) http-response FORWARDED (HTTP/1.1 200 10ms (GET http://172.18.255.201/?great=example))
TLS Termination
While routing HTTP traffic was easy to understand, secure workloads will require the use of HTTPS and TLS certificates. Let’s start this walkthrough with first deploying the certificate.
For demonstration purposes we will use a TLS certificate signed by a made-up, self-signed certificate authority (CA). One easy way to do this is with mkcert
.
First, let’s create a certificate that will validate bookinfo.cilium.rocks
and hipstershop.cilium.rocks
, as these are the host names used in this Gateway example:
root@server:~# mkcert '*.cilium.rocks'
Created a new local CA 💥
Note: the local CA is not installed in the system trust store.
Run "mkcert -install" for certificates to be trusted automatically ⚠️
Created a new certificate valid for the following names 📜
- "*.cilium.rocks"
Reminder: X.509 wildcards only go one level deep, so this won't match a.b.cilium.rocks ℹ️
The certificate is at "./_wildcard.cilium.rocks.pem" and the key at "./_wildcard.cilium.rocks-key.pem" ✅
It will expire on 9 June 2025 🗓
Mkcert created a key (_wildcard.cilium.rocks-key.pem
) and a certificate (_wildcard.cilium.rocks.pem
) that we will use for the Gateway service.
Let’s now create a Kubernetes TLS secret with this key and certificate:
root@server:~# kubectl create secret tls demo-cert --key=_wildcard.cilium.rocks-key.pem --cert=_wildcard.cilium.rocks.pem
secret/demo-cert created
We can now deploy another Gateway for HTTPS Traffic:
root@server:~# kubectl apply -f https://raw.githubusercontent.com/cilium/cilium/1.13.0/examples/kubernetes/gateway/basic-https.yaml
gateway.gateway.networking.k8s.io/tls-gateway created
httproute.gateway.networking.k8s.io/https-app-route-1 created
httproute.gateway.networking.k8s.io/https-app-route-2 created
Let’s review the configuration. It is almost identical to the one we reviewed previously. Just notice the following in the Gateway manifest:
spec:
gatewayClassName: cilium
listeners:
- name: https-1
protocol: HTTPS
port: 443
hostname: "bookinfo.cilium.rocks"
tls:
certificateRefs:
- kind: Secret
name: demo-cert
And the following in the HTTPRoute manifest:
spec:
parentRefs:
- name: tls-gateway
hostnames:
- "bookinfo.cilium.rocks"
The HTTPS Gateway API examples build up on what was done in the HTTP example and adds TLS termination for two HTTP routes:
- the
/details
prefix will be routed to thedetails
HTTP service deployed earlier - the
/
prefix will be routed to theproductpage
HTTP service deployed earlier
These services will be secured via TLS and accessible on two domain names:
bookinfo.cilium.rocks
hipstershop.cilium.rocks
In our example, the Gateway serves the TLS certificate defined in the demo-cert
Secret resource for all requests to bookinfo.cilium.rocks
and to hipstershop.cilium.rocks
.
After the deployment, the Gateway will pick up and IP address from MetalLB:
root@server:~# kubectl get gateway tls-gateway
NAME CLASS ADDRESS READY AGE
tls-gateway cilium 172.18.255.202 True 33s
root@server:~#
root@server:~# GATEWAY_IP=$(kubectl get gateway tls-gateway -o jsonpath='{.status.addresses[0].value}')
echo $GATEWAY_IP
172.18.255.202
In this Gateway configuration, the host names hipstershop.cilium.rocks
and bookinfo.cilium.rocks
are specified in the path routing rules.
Since we do not have DNS entries for these names, we will modify the /etc/hosts
file on the host to manually associate these names to the known Gateway IP we retrieved.
root@server:~# cat << EOF >> /etc/hosts
${GATEWAY_IP} bookinfo.cilium.rocks
${GATEWAY_IP} hipstershop.cilium.rocks
EOF
root@server:~# tail -n 2 /etc/hosts
172.18.255.202 bookinfo.cilium.rocks
172.18.255.202 hipstershop.cilium.rocks
Requests to these names will now be directed to the Gateway.
Let’s install the Mkcert CA into your system so cURL can trust it:
root@server:~# mkcert -install
The local CA is now installed in the system trust store! ⚡️
Let’s now make a HTTPS request to the Gateway:
root@server:~# curl -s https://bookinfo.cilium.rocks/details/1 | jq
{
"id": 1,
"author": "William Shakespeare",
"year": 1595,
"type": "paperback",
"pages": 200,
"publisher": "PublisherA",
"language": "English",
"ISBN-10": "1234567890",
"ISBN-13": "123-1234567890"
}
The data was be properly retrieved, using HTTPS (and thus, the TLS handshake was properly achieved).
Traffic Splitting
For this particular use case, we’re going to use Gateway API to load-balance incoming traffic to different backends, with different weights associated.
We will use a deployment made of echo servers – they will reply to our curl
queries with the pod name and the node name.
root@server:~# kubectl apply -f https://raw.githubusercontent.com/nvibert/gateway-api-traffic-splitting/main/echo-servers.yml
service/echo-1 created
deployment.apps/echo-1 created
service/echo-2 created
deployment.apps/echo-2 created
Let’s now deploy the Gateway and the HTTPRoute:
root@server:~# kubectl apply -f gateway.yaml
kubectl apply -f http-route.yaml
gateway.gateway.networking.k8s.io/cilium-gw created
httproute.gateway.networking.k8s.io/example-route-1 created
root@server:~# kubectl apply -f https://raw.githubusercontent.com/nvibert/gateway-api-traffic-splitting/main/gateway.yaml
gateway.gateway.networking.k8s.io/my-example-gateway created
root@server:~#
root@server:~#
root@server:~# kubectl apply -f https://raw.githubusercontent.com/nvibert/gateway-api-traffic-splitting/main/httpRoute.ymlhttproute.gateway.networking.k8s.io/example-route-1 configured
The HTTPRoute
Rules includes two different backendRefs and weights associated with them
backendRefs:
- kind: Service
name: echo-1
port: 8080
weight: 50
- kind: Service
name: echo-2
port: 8090
weight: 50
Access is successful and as described above, we get, in the reply, the pod name and the node name:
root@server:~# GATEWAY=$(kubectl get gateway cilium-gw -o jsonpath='{.status.addresses[0].value}')
echo $GATEWAY
172.18.255.200
root@server:~#
root@server:~#
root@server:~# curl --fail -s http://$GATEWAY/echo
Hostname: echo-1-7d88f779b-trmzt
Pod Information:
node name: kind-worker
pod name: echo-1-7d88f779b-trmzt
pod namespace: default
pod IP: 10.0.2.228
Server values:
server_version=nginx: 1.12.2 - lua: 10010
Request Information:
client_address=10.0.1.231
method=GET
real path=/echo
query=
request_version=1.1
request_scheme=http
request_uri=http://172.18.255.200:8080/echo
Request Headers:
accept=*/*
host=172.18.255.200
user-agent=curl/7.81.0
x-forwarded-proto=http
x-request-id=d035c99d-cd5d-45ce-9eff-3fcf614ebdcc
Request Body:
-no body in request-
When repeating the curl, the traffic is split roughly between two services. To verify, we can run a loop and count how the replies are spread:
root@server:~# while true; do curl -s -k "http://$GATEWAY/echo" >> curlresponses.txt ;done
^C
root@server:~# cat curlresponses.txt| grep -c "Hostname: echo-1"
2536
root@server:~# cat curlresponses.txt| grep -c "Hostname: echo-2"
2486
Update the HTTPRoute weights (either by updating the value in the original manifest before reapplying it or by using kubectl edit httproute
) to, for example, 99 for echo-1
and 1 for echo-2
:
Running the same loop validates that traffic is split based on the new weights:
root@server:~# kubectl describe httproutes.gateway.networking.k8s.io | grep -A 10 Rules
Rules:
Backend Refs:
Group:
Kind: Service
Name: echo-1
Port: 8080
Weight: 99
Group:
Kind: Service
Name: echo-2
Port: 8090
root@server:~# kubectl describe httproutes.gateway.networking.k8s.io | grep -A 11 Rules
Rules:
Backend Refs:
Group:
Kind: Service
Name: echo-1
Port: 8080
Weight: 99
Group:
Kind: Service
Name: echo-2
Port: 8090
Weight: 1
root@server:~# cat curlresponses991.txt| grep -c "Hostname: echo-1"
1711
root@server:~# cat curlresponses991.txt| grep -c "Hostname: echo-2"
14
HTTP Header Modification
With this functionality, Cilium GatewayAPI lets us add, remove or edit HTTP Headers of incoming traffic.
This is best validated by trying without and with the functionality. We’ll use the same echo servers.
Let’s add another HTTPRoute (we can use the Gateway created in any of the previous HTTP-related use cases):
root@server:~# cat /root/echo-header-http-route.yaml
---
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: header-http-echo
spec:
parentRefs:
- name: cilium-gw
hostnames: ["echo.cilium.io"]
rules:
- matches:
- path:
type: PathPrefix
value: /cilium-add-a-header
backendRefs:
- name: echoserver
port: 9080
A curl is successful and the reply sent back from the echo server is the original HTTP Header:
root@server:~# GATEWAY=$(kubectl get gateway cilium-gw -o jsonpath='{.status.addresses[0].value}')
echo $GATEWAY
172.18.255.200
root@server:~#
root@server:~# curl -s -HHost:echo.cilium.io http://$GATEWAY/cilium-add-a-header | grep -A 6 "Request Headers"
Request Headers:
accept=*/*
host=echo.cilium.io
user-agent=curl/7.81.0
x-forwarded-proto=http
x-request-id=f1d88ff5-3929-429f-ad75-3f96959afbe3
root@server:~#
To add the header, we will be using the filters
field. Add this to the HTTPRoute rules spec (on the same indentation as matches
and backendRefs
) and re-apply it.
filters:
- type: RequestHeaderModifier
requestHeaderModifier:
add:
- name: my-cilium-header-name
value: my-cilium-header-value
When running the curl
test again, notice how the header has been added:
root@server:~# curl -s -HHost:echo.cilium.io http://$GATEWAY/cilium-add-a-header | grep -A 6 "Request Headers"
Request Headers:
accept=*/*
host=echo.cilium.io
my-cilium-header-name=my-cilium-header-value
user-agent=curl/7.81.0
x-forwarded-proto=http
x-request-id=5ea1a402-f847-4fd5-b165-5a4324a2ffaa
To remove a header, you can add the following fields:
- type: RequestHeaderModifier
requestHeaderModifier:
remove: ["x-request-id"]
Notice how the x-request-id
header has been removed:
root@server:~# curl -s -HHost:echo.cilium.io http://$GATEWAY/cilium-add-a-header | grep -A 6 "Request Headers"
Request Headers:
accept=*/*
host=echo.cilium.io
user-agent=curl/7.81.0
x-forwarded-proto=http
Request Body:
root@server:~#
Conclusion
We hope you found this deep dive into Gateway API use cases useful. As more features are added to the Gateway API, we will update this post periodically with more features.
To learn more:
- Try the Gateway API lab
- Watch the Cilium Gateway API YouTube Playlist
- Read the companion blog post
- Join Cilium Slack to interact with the Cilium community
Thanks for reading.
