forked from cilium/cilium
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Header Modifier and Splitting use cases
Signed-off-by: Nico Vibert <[email protected]>
- Loading branch information
Showing
7 changed files
with
455 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
Deploy the Echo App | ||
=================== | ||
|
||
We will use a deployment made of echo servers. | ||
|
||
The application will reply to the client and, in the body of the reply, will include information about the pod and node receiving the original request. | ||
We will use this information to illustrate how the traffic is manipulated by the Gateway. | ||
|
||
.. parsed-literal:: | ||
$ kubectl apply -f \ |SCM_WEB|\/examples/kubernetes/gateway/echo.yaml | ||
Verify the pods are running as expected. | ||
|
||
.. code-block:: shell-session | ||
$ kubectl get pods | ||
NAME READY STATUS RESTARTS AGE | ||
echo-1-7d88f779b-m6r46 1/1 Running 0 21s | ||
echo-2-5bfb6668b4-n7llh 1/1 Running 0 21s | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
109 changes: 109 additions & 0 deletions
109
Documentation/network/servicemesh/gateway-api/header.rst
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
.. only:: not (epub or latex or html) | ||
|
||
WARNING: You are looking at unreleased Cilium documentation. | ||
Please use the official rendered version released here: | ||
https://docs.cilium.io | ||
|
||
.. _gs_gateway_header: | ||
|
||
************ | ||
HTTP Header Modifier Examples | ||
************ | ||
|
||
The Gateway can modify the headers of HTTP requests from clients. | ||
|
||
.. include:: ../echo-app.rst | ||
|
||
Deploy the Cilium Gateway | ||
========================= | ||
|
||
HTTP header modification is the process of adding, removing, or modifying HTTP headers in incoming requests. | ||
To configure HTTP header modification, define a Gateway object with one or more HTTP filters. Each filter specifies a specific modification to make to incoming requests, such as adding a custom header or modifying an existing header. | ||
|
||
To add a header to a HTTP request, use a filter of the type ``RequestHeaderModifier`` with the ``add`` action and the name and value of the header. | ||
|
||
You'll find the example Gateway and HTTPRoute definition in ``request-header.yaml``. | ||
|
||
.. literalinclude:: ../../../../examples/kubernetes/gateway/request-header.yaml | ||
|
||
In this example, we will add a header named ``my-header-name`` with the ``my-header-value`` value. | ||
|
||
Deploy the Gateway and the HTTPRoute: | ||
|
||
.. parsed-literal:: | ||
$ kubectl apply -f \ |SCM_WEB|\/examples/kubernetes/gateway/request-header.yaml | ||
The above example creates a Gateway named ``cilium-gw`` that listens on port 80. | ||
|
||
.. code-block:: shell-session | ||
$ kubectl get gateway cilium-gw | ||
NAME CLASS ADDRESS PROGRAMMED AGE | ||
cilium-gw cilium 172.18.255.200 8s | ||
.. Note:: | ||
|
||
Some providers e.g. EKS use a fully-qualified domain name rather than an IP address. | ||
|
||
Modify incoming HTTP Requests | ||
================== | ||
|
||
Now that the Gateway is ready, you can make HTTP requests. | ||
|
||
.. code-block:: shell-session | ||
$ curl -s http://$GATEWAY/add-a-request-header | grep -A 6 "Request Headers" | ||
Request Headers: | ||
accept=*/* | ||
host=172.18.255.200 | ||
my-header-name=my-header-value | ||
user-agent=curl/7.81.0 | ||
x-forwarded-proto=http | ||
x-request-id=61a72702-3dfa-4bc3-a21c-7544ef36af7b | ||
A curl is successful and in the body of the response sent back from the echo server, you can see the HTTP Header from the incoming request. | ||
Note how the header had been added by the Gateway. | ||
|
||
Headers can also be removed, by using the ``remove`` keyword and a list of header names. | ||
|
||
.. code-block:: shell-session | ||
filters | ||
- type: RequestHeaderModifier | ||
requestHeaderModifier: | ||
remove: ["x-request-id"] | ||
Note how the ``x-request-id`` header has been removed (using this filter with the ``remove-a-request-header`` prefix match): | ||
|
||
.. code-block:: shell-session | ||
$ curl --fail -s http://$GATEWAY/remove-a-request-header | grep -A 6 "Request Headers" | ||
Request Headers: | ||
accept=*/* | ||
host=172.18.255.200 | ||
user-agent=curl/7.81.0 | ||
x-forwarded-proto=http | ||
To edit an existing header, use the ``set`` action and specify the value of the header to be modified and the new header value to be set. | ||
|
||
.. code-block:: shell-session | ||
filters: | ||
- type: RequestHeaderModifier | ||
requestHeaderModifier: | ||
set: | ||
- name: x-request-id | ||
value: set-cilium-header-value | ||
Note how the ``x-request-id`` header value has been modified (using this filter with the ``edit-a-request-header`` prefix match). | ||
|
||
.. code-block:: shell-session | ||
$ curl -s http://$GATEWAY/edit-a-request-header | grep -A 6 "Request Headers" | ||
Request Headers: | ||
accept=*/* | ||
host=172.18.255.200 | ||
user-agent=curl/7.81.0 | ||
x-forwarded-proto=http | ||
x-request-id=set-cilium-header-value |
143 changes: 143 additions & 0 deletions
143
Documentation/network/servicemesh/gateway-api/splitting.rst
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
.. only:: not (epub or latex or html) | ||
|
||
WARNING: You are looking at unreleased Cilium documentation. | ||
Please use the official rendered version released here: | ||
https://docs.cilium.io | ||
|
||
.. _gs_gateway_splitting: | ||
|
||
************ | ||
Traffic Splitting Example | ||
************ | ||
|
||
HTTP traffic splitting is the process of sending incoming traffic to multiple backend services, based on predefined weights or other criteria. | ||
The Cilium Gateway API includes built-in support for traffic splitting, allowing users to easily distribute incoming traffic across multiple backend services. | ||
This is very useful for canary testing or A/B scenarios. | ||
|
||
For this particular use case, we're going to use Gateway API to load-balance incoming traffic to different backends, starting with the same weights before testing with a 99/1 weight distribution. | ||
|
||
.. include:: ../echo-app.rst | ||
|
||
Deploy the Cilium Gateway | ||
========================= | ||
|
||
You'll find the example Gateway and HTTPRoute definition in ``splitting.yaml``. | ||
|
||
.. literalinclude:: ../../../../examples/kubernetes/gateway/splitting.yaml | ||
|
||
Note the even 50/50 split between the two Services. Deploy the Gateway and the HTTPRoute: | ||
|
||
.. parsed-literal:: | ||
$ kubectl apply -f \ |SCM_WEB|\/examples/kubernetes/gateway/splitting.yaml | ||
The above example creates a Gateway named ``cilium-gw`` that listens on port 80. | ||
A single route is defined and includes two different ``backendRefs`` (``echo-1`` and ``echo-2``) and weights associated with them. | ||
|
||
.. code-block:: shell-session | ||
$ kubectl get gateway cilium-gw | ||
NAME CLASS ADDRESS PROGRAMMED AGE | ||
cilium-gw cilium 172.18.255.200 8s | ||
.. Note:: | ||
|
||
Some providers e.g. EKS use a fully-qualified domain name rather than an IP address. | ||
|
||
Even traffic split | ||
================== | ||
|
||
Now that the Gateway is ready, you can make HTTP requests to the services. | ||
|
||
.. code-block:: shell-session | ||
$ GATEWAY=$(kubectl get gateway cilium-gw -o jsonpath='{.status.addresses[0].value}') | ||
$ curl --fail -s http://$GATEWAY/echo | ||
Hostname: echo-1-7d88f779b-m6r46 | ||
Pod Information: | ||
node name: kind-worker2 | ||
pod name: echo-1-7d88f779b-m6r46 | ||
pod namespace: default | ||
pod IP: 10.0.2.15 | ||
Server values: | ||
server_version=nginx: 1.12.2 - lua: 10010 | ||
Request Information: | ||
client_address=10.0.2.252 | ||
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=ee152a07-2be2-4539-b74d-ebcebf912907 | ||
Request Body: | ||
-no body in request- | ||
Notice that, in the reply, you get the name of the pod that received the query. For example: | ||
|
||
.. code-block:: shell-session | ||
Hostname: echo-2-5bfb6668b4-2rl4t | ||
Repeat the command several times. | ||
You should see the reply being balanced evenly across both pods/nodes. | ||
Let's double check that traffic is evenly split across multiple Pods by running a loop and counting the requests: | ||
|
||
.. code-block:: shell-session | ||
while true; do curl -s -k "http://$GATEWAY/echo" >> curlresponses.txt ;done | ||
Stop with ``Ctrl+C``. | ||
Verify that the responses have been (more or less) evenly spread. | ||
|
||
.. code-block:: shell-session | ||
$ cat curlresponses.txt| grep -c "Hostname: echo-1" | ||
1221 | ||
$ cat curlresponses.txt| grep -c "Hostname: echo-2" | ||
1162 | ||
Uneven (99/1) traffic split | ||
================== | ||
|
||
Update the HTTPRoute weights (either by using ``kubectl edit httproute`` or by updating the value in the original manifest before reapplying it) to, for example, ``99`` for echo-1 and ``1`` for echo-2: | ||
|
||
.. code-block:: shell-session | ||
backendRefs: | ||
- kind: Service | ||
name: echo-1 | ||
port: 8080 | ||
weight: 99 | ||
- kind: Service | ||
name: echo-2 | ||
port: 8090 | ||
weight: 1 | ||
Let's double check that traffic has been unevenly split across multiple Pods by running a loop and counting the requests: | ||
|
||
.. code-block:: shell-session | ||
while true; do curl -s -k "http://$GATEWAY/echo" >> curlresponses991.txt ;done | ||
Stop with ``Ctrl+C``. | ||
Verify that the responses have been (more or less) evenly spread. | ||
|
||
.. code-block:: shell-session | ||
$ cat curlresponses991.txt| grep -c "Hostname: echo-1" | ||
24739 | ||
$ cat curlresponses991.txt| grep -c "Hostname: echo-2" | ||
239 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
--- | ||
apiVersion: v1 | ||
kind: Service | ||
metadata: | ||
labels: | ||
app: echo-1 | ||
name: echo-1 | ||
spec: | ||
ports: | ||
- port: 8080 | ||
name: high | ||
protocol: TCP | ||
targetPort: 8080 | ||
selector: | ||
app: echo-1 | ||
--- | ||
apiVersion: apps/v1 | ||
kind: Deployment | ||
metadata: | ||
labels: | ||
app: echo-1 | ||
name: echo-1 | ||
spec: | ||
replicas: 1 | ||
selector: | ||
matchLabels: | ||
app: echo-1 | ||
template: | ||
metadata: | ||
labels: | ||
app: echo-1 | ||
spec: | ||
containers: | ||
- image: gcr.io/kubernetes-e2e-test-images/echoserver:2.2 | ||
name: echo-1 | ||
ports: | ||
- containerPort: 8080 | ||
env: | ||
- name: NODE_NAME | ||
valueFrom: | ||
fieldRef: | ||
fieldPath: spec.nodeName | ||
- name: POD_NAME | ||
valueFrom: | ||
fieldRef: | ||
fieldPath: metadata.name | ||
- name: POD_NAMESPACE | ||
valueFrom: | ||
fieldRef: | ||
fieldPath: metadata.namespace | ||
- name: POD_IP | ||
valueFrom: | ||
fieldRef: | ||
fieldPath: status.podIP | ||
--- | ||
apiVersion: v1 | ||
kind: Service | ||
metadata: | ||
labels: | ||
app: echo-2 | ||
name: echo-2 | ||
spec: | ||
ports: | ||
- port: 8090 | ||
name: high | ||
protocol: TCP | ||
targetPort: 8080 | ||
selector: | ||
app: echo-2 | ||
--- | ||
apiVersion: apps/v1 | ||
kind: Deployment | ||
metadata: | ||
labels: | ||
app: echo-2 | ||
name: echo-2 | ||
spec: | ||
replicas: 1 | ||
selector: | ||
matchLabels: | ||
app: echo-2 | ||
template: | ||
metadata: | ||
labels: | ||
app: echo-2 | ||
spec: | ||
containers: | ||
- image: gcr.io/kubernetes-e2e-test-images/echoserver:2.2 | ||
name: echo-2 | ||
ports: | ||
- containerPort: 8080 | ||
env: | ||
- name: NODE_NAME | ||
valueFrom: | ||
fieldRef: | ||
fieldPath: spec.nodeName | ||
- name: POD_NAME | ||
valueFrom: | ||
fieldRef: | ||
fieldPath: metadata.name | ||
- name: POD_NAMESPACE | ||
valueFrom: | ||
fieldRef: | ||
fieldPath: metadata.namespace | ||
- name: POD_IP | ||
valueFrom: | ||
fieldRef: | ||
fieldPath: status.podIP |
Oops, something went wrong.