Redirects and rewrites
Deploy the sample services
Deploy httpbin
You will use the httpbin service to respond to requests.
$ kubectl create -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpbin
spec:
replicas: 1
selector:
matchLabels:
app: httpbin
version: v1
template:
metadata:
labels:
app: httpbin
version: v1
spec:
containers:
- image: docker.io/kennethreitz/httpbin
imagePullPolicy: IfNotPresent
name: httpbin
command: ["gunicorn", "--access-logfile", "-", "-b", "0.0.0.0:80", "httpbin:app"]
ports:
- containerPort: 80
EOF
Deploy the httpbin service
$ kubectl create -f - <<EOF
apiVersion: v1
kind: Service
metadata:
name: httpbin
labels:
app: httpbin
spec:
ports:
- name: http
port: 8000
targetPort: 80
selector:
app: httpbin
EOF
Deploy a curl client
We will use curl
to send requests to our httpbin
service.
$ cat <<EOF | kubectl create -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: curl
spec:
replicas: 1
selector:
matchLabels:
app: curl
template:
metadata:
labels:
app: curl
spec:
containers:
- name: curl
image: curlimages/curl
command: ["/bin/sleep","3650d"]
imagePullPolicy: IfNotPresent
EOF
Configure a redirect
You can use routes to return HTTP redirect (3xx) responses to a client.
$ kubectl exec deploy/curl -- curl -sSI http://httpbin:8000/anything/old-url
The httpbin
service will show you the URL that you hit:
{
"url": "http://httpbin:8000/anything/old-url"
}
Now, create a URL redirect route:
$ cat <<EOF | kubectl apply -f -
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: http-filter-redirect
spec:
parentRefs:
- group: ""
kind: Service
name: httpbin
port: 8000
rules:
- matches:
- path:
type: PathPrefix
value: /anything/old-url
filters:
- type: RequestRedirect
requestRedirect:
path:
type: ReplacePrefixMatch
replacePrefixMatch: /anything/new-url
statusCode: 302
- backendRefs:
- name: httpbin
port: 8000
EOF
You will see that your request was sent a redirect:
$ kubectl exec deploy/curl -- curl -sSI http://httpbin:8000/anything/old-url
HTTP/1.1 302 Found
location: http://httpbin:8000/anything/new-url
date: Tue, 29 Oct 2024 23:51:35 GMT
server: istio-envoy
x-envoy-decorator-operation: http-filter-redirect-0-istio-autogenerated-k8s-gateway:8000/*
transfer-encoding: chunked
Note that there are two rules in this route. When a route is bound to a service, as in this case, it replaces the default behavior of the mesh to pass traffic directly to that service. Without explicitly defining the backendRef
to fall through to, all traffic to httpbin
that did not match the PathPrefix
would receive a 404 error.
The first rule does not require a backendRef
as a redirect is a terminal action.
To continue, delete the rule:
$ kubectl delete httproute http-filter-redirect
Comfigure a rewrite
You can also use a route to rewrite components of a request before it is sent to its destination.
Similar to before, create a URL rewrite rule:
$ cat <<EOF | kubectl apply -f -
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: http-filter-rewrite
spec:
parentRefs:
- group: ""
kind: Service
name: httpbin
port: 8000
rules:
- matches:
- path:
type: PathPrefix
value: /anything/old-url
filters:
- type: URLRewrite
urlRewrite:
hostname: httpbin
path:
type: ReplacePrefixMatch
replacePrefixMatch: /anything/new-url
backendRefs:
- name: httpbin
port: 8000
- backendRefs:
- name: httpbin
port: 8000
EOF
Test with curl
. Requests to any path other than /anything/old-url
are unchanged:
$ kubectl exec deploy/curl -- curl -sSi http://httpbin:8000/anything/unchanged/
Look for the URL served:
{
"url": "http://httpbin:8000/anything/unchanged/"
}
Requests to /anything/old-url
are rewritten to /anything/new-url
:
$ kubectl exec deploy/curl -- curl -sSi http://httpbin:8000/anything/old-url/
Note both the new URL, and the header with the original path:
{
"headers": {
"Accept": "*/*",
"Host": "httpbin",
"User-Agent": "curl/8.7.1",
"X-Envoy-Original-Path": "/anything/old-url/"
},
"url": "http://httpbin/anything/new-url/"
}
To conclude, delete the rule:
$ kubectl delete httproute http-filter-rewrite
Cleaning up
Remove the routes, if you haven’t already:
$ kubectl delete httproute http-filter-redirect
$ kubectl delete httproute http-filter-rewrite
Delete httpbin
and curl
deployments and httpbin
service:
$ kubectl delete deploy httpbin curl
$ kubectl delete svc httpbin